Commit aef96be4735b5cf5f6067b916ba0a74a83ca6ca1

renamed skiplist_volume to fixed_length_skiplist_volume
  
22require 'volumes/block_volume'
33require 'volumes/distributed_pointer'
44require 'volumes/map_volume'
5require 'volumes/skiplist_volume'
5require 'volumes/fixed_length_skiplist_volume'
  
1module StrokeDB
2 class FixedLengthSkiplistVolume < SimpleSkiplist
3
4 def initialize(options = {})
5 @options = options.stringify_keys
6 @volume = MapVolume.new(:record_size => (@options['maxlevel']||DEFAULT_MAXLEVEL) * 4 + 1 +
7 @options['key_length'] + @options['value_length'], :path => @options['path'])
8 @nodes = {}
9 super(nil,:maxlevel => @options['maxlevel'], :probability => @options['probability'])
10 end
11
12 def key_length
13 @options['key_length']
14 end
15
16 def value_length
17 @options['value_length']
18 end
19
20 def path
21 @options['path']
22 end
23
24 def close!
25 @volume.close!
26 end
27
28 def inspect
29 "#<StrokeDB::FixedLengthSkiplistVolume:0x#{object_id.to_s(16)} path: #{path} key_length: #{key_length} value_length: #{value_length}"
30 end
31
32 private
33
34 # SimpleSkiplist overrides
35
36
37 def node_next(x, level)
38 if node = x[0][level]
39 read_node(node[-1])
40 else
41 nil
42 end
43 end
44
45 def node_set_value!(x, value)
46 x[-2] = value
47 save_node!(x)
48 end
49
50 def node_insert_after!(x, prev, level)
51 x[0][level] = prev[0][level]
52 prev[0][level] = save_node!(x)
53 save_node!(prev)
54 end
55
56 def new_node(level, key, value, __pos = -1)
57 [
58 [nil]*level,
59 key,
60 value,
61 __pos
62 ]
63 end
64
65 def new_head
66 unless @volume.available?(0)
67 read_node(0)
68 else
69 _head = new_node(@maxlevel, "\x00" * key_length, "\x00" * value_length)
70 save_node!(_head)
71 end
72 end
73
74 def save_node!(node)
75 node_levels = node[0].map{|v| v.nil? ? -1 : v[-1]}
76 packed = ([maxlevel]+node_levels).pack("CN#{node_levels.size}")
77 key = node[-3]
78 value = node[-2]
79
80 if (szd = maxlevel - node_levels.size) > 0
81 packed += "\xff\xff\xff\xff"*szd
82 end
83
84 if node[-1] == -1 # unsaved
85 node[-1] = @volume.insert!(packed + key + value)
86 else
87 @volume.write!(node[-1],packed + key + value)
88 end
89 @head = node if node[-1] == 0
90 node
91 end
92
93 def read_node(position)
94 _node = @volume.read(position)
95 level = _node[0,1].unpack('C')[0]
96 links = _node[1,maxlevel*4].unpack("N#{level}")
97 node = [
98 LazyMappingArray.new(links).map_with do |v|
99 v == 4294967295 ? nil : read_node(v)
100 end.unmap_with {|v| v[-1] },
101 _node[maxlevel*4 + 1,key_length],
102 _node[maxlevel*4 + 1 + key_length, value_length],
103 position
104 ]
105 end
106
107
108 end
109end
  
1module StrokeDB
2 class FixedLengthSkiplistVolume < SimpleSkiplist
3
4 def initialize(options = {})
5 @options = options.stringify_keys
6 @volume = MapVolume.new(:record_size => (@options['maxlevel']||DEFAULT_MAXLEVEL) * 4 + 1 +
7 @options['key_length'] + @options['value_length'], :path => @options['path'])
8 @nodes = {}
9 super(nil,:maxlevel => @options['maxlevel'], :probability => @options['probability'])
10 end
11
12 def key_length
13 @options['key_length']
14 end
15
16 def value_length
17 @options['value_length']
18 end
19
20 def path
21 @options['path']
22 end
23
24 def close!
25 @volume.close!
26 end
27
28 def inspect
29 "#<StrokeDB::FixedLengthSkiplistVolume:0x#{object_id.to_s(16)} path: #{path} key_length: #{key_length} value_length: #{value_length}"
30 end
31
32 private
33
34 # SimpleSkiplist overrides
35
36
37 def node_next(x, level)
38 if node = x[0][level]
39 read_node(node[-1])
40 else
41 nil
42 end
43 end
44
45 def node_set_value!(x, value)
46 x[-2] = value
47 save_node!(x)
48 end
49
50 def node_insert_after!(x, prev, level)
51 x[0][level] = prev[0][level]
52 prev[0][level] = save_node!(x)
53 save_node!(prev)
54 end
55
56 def new_node(level, key, value, __pos = -1)
57 [
58 [nil]*level,
59 key,
60 value,
61 __pos
62 ]
63 end
64
65 def new_head
66 unless @volume.available?(0)
67 read_node(0)
68 else
69 _head = new_node(@maxlevel, "\x00" * key_length, "\x00" * value_length)
70 save_node!(_head)
71 end
72 end
73
74 def save_node!(node)
75 node_levels = node[0].map{|v| v.nil? ? -1 : v[-1]}
76 packed = ([maxlevel]+node_levels).pack("CN#{node_levels.size}")
77 key = node[-3]
78 value = node[-2]
79
80 if (szd = maxlevel - node_levels.size) > 0
81 packed += "\xff\xff\xff\xff"*szd
82 end
83
84 if node[-1] == -1 # unsaved
85 node[-1] = @volume.insert!(packed + key + value)
86 else
87 @volume.write!(node[-1],packed + key + value)
88 end
89 @head = node if node[-1] == 0
90 node
91 end
92
93 def read_node(position)
94 _node = @volume.read(position)
95 level = _node[0,1].unpack('C')[0]
96 links = _node[1,maxlevel*4].unpack("N#{level}")
97 node = [
98 LazyMappingArray.new(links).map_with do |v|
99 v == 4294967295 ? nil : read_node(v)
100 end.unmap_with {|v| v[-1] },
101 _node[maxlevel*4 + 1,key_length],
102 _node[maxlevel*4 + 1 + key_length, value_length],
103 position
104 ]
105 end
106
107
108 end
109end