strokedb 0.0.2.1 → 0.0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. data/README +18 -20
  2. data/bench.html +4001 -0
  3. data/bin/strokedb +14 -0
  4. data/examples/movies.rb +105 -0
  5. data/examples/movies2.rb +97 -0
  6. data/examples/strokewiki/README +28 -0
  7. data/examples/strokewiki/view/edit.xhtml +27 -0
  8. data/examples/strokewiki/view/new.xhtml +26 -0
  9. data/examples/strokewiki/view/pages.xhtml +27 -0
  10. data/examples/strokewiki/view/show.xhtml +40 -0
  11. data/examples/strokewiki/view/versions.xhtml +25 -0
  12. data/examples/strokewiki/wiki.rb +106 -0
  13. data/examples/todo.rb +92 -0
  14. data/lib/strokedb.rb +85 -0
  15. data/lib/{config → strokedb}/config.rb +14 -9
  16. data/lib/strokedb/console.rb +87 -0
  17. data/lib/strokedb/core_ext.rb +10 -0
  18. data/lib/{util/ext → strokedb/core_ext}/blank.rb +1 -1
  19. data/lib/{util/ext → strokedb/core_ext}/enumerable.rb +0 -0
  20. data/lib/{util/ext → strokedb/core_ext}/fixnum.rb +0 -0
  21. data/lib/strokedb/core_ext/float.rb +4 -0
  22. data/lib/{util/ext → strokedb/core_ext}/hash.rb +0 -0
  23. data/lib/strokedb/core_ext/infinity.rb +33 -0
  24. data/lib/strokedb/core_ext/kernel.rb +41 -0
  25. data/lib/strokedb/core_ext/object.rb +16 -0
  26. data/lib/{util/ext → strokedb/core_ext}/string.rb +28 -1
  27. data/lib/strokedb/core_ext/symbol.rb +13 -0
  28. data/lib/strokedb/data_structures.rb +5 -0
  29. data/lib/strokedb/data_structures/chunked_skiplist.rb +123 -0
  30. data/lib/{data_structures → strokedb/data_structures}/inverted_list.rb +0 -0
  31. data/lib/{data_structures → strokedb/data_structures}/point_query.rb +0 -0
  32. data/lib/strokedb/data_structures/simple_skiplist.rb +350 -0
  33. data/lib/{data_structures → strokedb/data_structures}/skiplist.rb +1 -1
  34. data/lib/{document → strokedb}/document.rb +180 -71
  35. data/lib/{document → strokedb/document}/callback.rb +0 -0
  36. data/lib/{document → strokedb/document}/delete.rb +2 -2
  37. data/lib/strokedb/document/dsl.rb +4 -0
  38. data/lib/{document → strokedb/document/dsl}/associations.rb +0 -0
  39. data/lib/{document → strokedb/document/dsl}/coercions.rb +0 -0
  40. data/lib/strokedb/document/dsl/meta_dsl.rb +7 -0
  41. data/lib/{document → strokedb/document/dsl}/validations.rb +26 -21
  42. data/lib/{document → strokedb/document/dsl}/virtualize.rb +0 -0
  43. data/lib/{document → strokedb/document}/meta.rb +92 -29
  44. data/lib/{document → strokedb/document}/slot.rb +17 -5
  45. data/lib/{document → strokedb/document}/util.rb +0 -0
  46. data/lib/{document → strokedb/document}/versions.rb +2 -2
  47. data/lib/strokedb/index.rb +2 -0
  48. data/lib/strokedb/nsurl.rb +24 -0
  49. data/lib/strokedb/store.rb +149 -0
  50. data/lib/strokedb/stores.rb +6 -0
  51. data/lib/{stores → strokedb/stores}/chainable_storage.rb +20 -14
  52. data/lib/strokedb/stores/file_storage.rb +118 -0
  53. data/lib/{stores/inverted_list_index → strokedb/stores}/inverted_list_file_storage.rb +50 -0
  54. data/lib/strokedb/stores/memory_storage.rb +80 -0
  55. data/lib/{stores → strokedb/stores}/remote_store.rb +10 -4
  56. data/lib/strokedb/sync.rb +4 -0
  57. data/lib/{sync → strokedb/sync}/chain_sync.rb +0 -0
  58. data/lib/{sync → strokedb/sync}/diff.rb +12 -1
  59. data/lib/{sync/stroke_diff → strokedb/sync/diff}/array.rb +1 -1
  60. data/lib/{sync/stroke_diff → strokedb/sync/diff}/default.rb +0 -0
  61. data/lib/{sync/stroke_diff → strokedb/sync/diff}/hash.rb +1 -1
  62. data/lib/{sync/stroke_diff → strokedb/sync/diff}/string.rb +1 -1
  63. data/lib/{sync → strokedb/sync}/lamport_timestamp.rb +0 -0
  64. data/lib/{sync → strokedb/sync}/store_sync.rb +15 -7
  65. data/lib/strokedb/transaction.rb +78 -0
  66. data/lib/{util → strokedb}/util.rb +14 -7
  67. data/lib/strokedb/util/attach_dsl.rb +29 -0
  68. data/lib/{util → strokedb/util}/blankslate.rb +0 -0
  69. data/lib/strokedb/util/class_optimization.rb +93 -0
  70. data/lib/{util → strokedb/util}/inflect.rb +0 -0
  71. data/lib/strokedb/util/java_util.rb +13 -0
  72. data/lib/{util → strokedb/util}/lazy_array.rb +0 -0
  73. data/lib/{util → strokedb/util}/lazy_mapping_array.rb +4 -0
  74. data/lib/{util → strokedb/util}/lazy_mapping_hash.rb +0 -0
  75. data/lib/{util → strokedb/util}/serialization.rb +21 -0
  76. data/lib/strokedb/util/uuid.rb +159 -0
  77. data/lib/{util → strokedb/util}/xml.rb +0 -0
  78. data/lib/{view → strokedb}/view.rb +2 -2
  79. data/lib/strokedb/volumes.rb +5 -0
  80. data/lib/strokedb/volumes/archive_volume.rb +165 -0
  81. data/lib/strokedb/volumes/block_volume.rb +169 -0
  82. data/lib/strokedb/volumes/distributed_pointer.rb +43 -0
  83. data/lib/strokedb/volumes/fixed_length_skiplist_volume.rb +109 -0
  84. data/lib/strokedb/volumes/map_volume.rb +268 -0
  85. data/meta/MANIFEST +175 -0
  86. data/script/console +2 -70
  87. data/spec/integration/remote_store_spec.rb +70 -0
  88. data/spec/integration/search_spec.rb +76 -0
  89. data/spec/integration/spec_helper.rb +1 -0
  90. data/spec/lib/spec_helper.rb +1 -0
  91. data/spec/lib/strokedb/config_spec.rb +250 -0
  92. data/spec/lib/strokedb/core_ext/blank_spec.rb +20 -0
  93. data/spec/lib/strokedb/core_ext/extract_spec.rb +42 -0
  94. data/spec/lib/strokedb/core_ext/float_spec.rb +62 -0
  95. data/spec/lib/strokedb/core_ext/infinity_spec.rb +40 -0
  96. data/spec/lib/strokedb/core_ext/spec_helper.rb +1 -0
  97. data/spec/lib/strokedb/core_ext/string_spec.rb +25 -0
  98. data/spec/lib/strokedb/core_ext/symbol_spec.rb +8 -0
  99. data/spec/lib/strokedb/data_structures/chunked_skiplist_spec.rb +144 -0
  100. data/spec/lib/strokedb/data_structures/inverted_list_spec.rb +172 -0
  101. data/spec/lib/strokedb/data_structures/simple_skiplist_spec.rb +200 -0
  102. data/spec/lib/strokedb/data_structures/skiplist_spec.rb +253 -0
  103. data/spec/lib/strokedb/data_structures/spec_helper.rb +1 -0
  104. data/spec/lib/strokedb/document/associations_spec.rb +319 -0
  105. data/spec/lib/strokedb/document/callbacks_spec.rb +134 -0
  106. data/spec/lib/strokedb/document/coercions_spec.rb +110 -0
  107. data/spec/lib/strokedb/document/document_spec.rb +1063 -0
  108. data/spec/lib/strokedb/document/meta_meta_spec.rb +30 -0
  109. data/spec/lib/strokedb/document/meta_spec.rb +435 -0
  110. data/spec/lib/strokedb/document/metaslot_spec.rb +43 -0
  111. data/spec/lib/strokedb/document/slot_spec.rb +130 -0
  112. data/spec/lib/strokedb/document/spec_helper.rb +1 -0
  113. data/spec/lib/strokedb/document/validations_spec.rb +1081 -0
  114. data/spec/lib/strokedb/document/virtualize_spec.rb +80 -0
  115. data/spec/lib/strokedb/nsurl_spec.rb +73 -0
  116. data/spec/lib/strokedb/spec_helper.rb +1 -0
  117. data/spec/lib/strokedb/stores/chained_storages_spec.rb +116 -0
  118. data/spec/lib/strokedb/stores/spec_helper.rb +1 -0
  119. data/spec/lib/strokedb/stores/store_spec.rb +201 -0
  120. data/spec/lib/strokedb/stores/transaction_spec.rb +107 -0
  121. data/spec/lib/strokedb/sync/chain_sync_spec.rb +43 -0
  122. data/spec/lib/strokedb/sync/diff_spec.rb +111 -0
  123. data/spec/lib/strokedb/sync/lamport_timestamp_spec.rb +174 -0
  124. data/spec/lib/strokedb/sync/slot_diff_spec.rb +164 -0
  125. data/spec/lib/strokedb/sync/spec_helper.rb +1 -0
  126. data/spec/lib/strokedb/sync/store_sync_spec.rb +181 -0
  127. data/spec/lib/strokedb/sync/stroke_diff/array_spec.rb +97 -0
  128. data/spec/lib/strokedb/sync/stroke_diff/complex_spec.rb +58 -0
  129. data/spec/lib/strokedb/sync/stroke_diff/hash_spec.rb +144 -0
  130. data/spec/lib/strokedb/sync/stroke_diff/scalar_spec.rb +23 -0
  131. data/spec/lib/strokedb/sync/stroke_diff/spec_helper.rb +25 -0
  132. data/spec/lib/strokedb/sync/stroke_diff/string_spec.rb +61 -0
  133. data/spec/lib/strokedb/util/attach_dsl_spec.rb +45 -0
  134. data/spec/lib/strokedb/util/inflect_spec.rb +14 -0
  135. data/spec/lib/strokedb/util/lazy_array_spec.rb +157 -0
  136. data/spec/lib/strokedb/util/lazy_mapping_array_spec.rb +174 -0
  137. data/spec/lib/strokedb/util/lazy_mapping_hash_spec.rb +92 -0
  138. data/spec/lib/strokedb/util/spec_helper.rb +1 -0
  139. data/spec/lib/strokedb/util/uuid_spec.rb +46 -0
  140. data/spec/lib/strokedb/view_spec.rb +228 -0
  141. data/spec/lib/strokedb/volumes/archive_volume_spec.rb +105 -0
  142. data/spec/lib/strokedb/volumes/block_volume_spec.rb +100 -0
  143. data/spec/lib/strokedb/volumes/distributed_pointer_spec.rb +14 -0
  144. data/spec/lib/strokedb/volumes/fixed_length_skiplist_volume_spec.rb +177 -0
  145. data/spec/lib/strokedb/volumes/map_volume_spec.rb +172 -0
  146. data/spec/lib/strokedb/volumes/spec_helper.rb +1 -0
  147. data/spec/regression/docref_spec.rb +94 -0
  148. data/spec/regression/meta_spec.rb +23 -0
  149. data/spec/regression/spec_helper.rb +1 -0
  150. data/spec/regression/sync_spec.rb +36 -0
  151. data/spec/spec.opts +7 -0
  152. data/spec/spec_helper.rb +37 -0
  153. data/spec/temp/storages/TIMESTAMP +1 -0
  154. data/spec/temp/storages/UUID +1 -0
  155. data/spec/temp/storages/database-sync/TIMESTAMP +1 -0
  156. data/spec/temp/storages/database-sync/UUID +1 -0
  157. data/spec/temp/storages/database-sync/config +1 -0
  158. data/spec/temp/storages/database-sync/file/LAST +1 -0
  159. data/spec/temp/storages/database-sync/file/bd/f6/bdf675e5-8a7b-494e-97f2-f74a14ccd95d.av +0 -0
  160. data/spec/temp/storages/database-sync/file/uindex.wal +0 -0
  161. data/spec/temp/storages/database-sync/inverted_list_file/INVERTED_INDEX +1 -0
  162. data/spec/temp/storages/inverted_list_storage/INVERTED_INDEX +0 -0
  163. data/strokedb.gemspec +120 -0
  164. data/task/benchmark.task +9 -0
  165. data/task/ditz.task +30 -0
  166. data/task/echoe.rb +17 -0
  167. data/task/rcov.task +50 -0
  168. data/task/rdoc.task +10 -0
  169. data/task/rspec.task +0 -0
  170. data/vendor/java_inline.rb +106 -0
  171. data/vendor/rbmodexcl/mrimodexcl.rb +82 -0
  172. data/vendor/rbmodexcl/rbmodexcl.rb +5 -0
  173. data/vendor/rbmodexcl/rbxmodexcl.rb +48 -0
  174. data/vendor/rbmodexcl/spec/unextend_spec.rb +50 -0
  175. data/vendor/rbmodexcl/spec/uninclude_spec.rb +26 -0
  176. metadata +271 -79
  177. data/CONTRIBUTORS +0 -7
  178. data/CREDITS +0 -13
  179. data/bin/sdbc +0 -2
  180. data/lib/init.rb +0 -57
  181. data/lib/stores/inverted_list_index/inverted_list_index.rb +0 -49
  182. data/lib/stores/skiplist_store/chunk.rb +0 -119
  183. data/lib/stores/skiplist_store/chunk_storage.rb +0 -21
  184. data/lib/stores/skiplist_store/file_chunk_storage.rb +0 -44
  185. data/lib/stores/skiplist_store/memory_chunk_storage.rb +0 -37
  186. data/lib/stores/skiplist_store/skiplist_store.rb +0 -217
  187. data/lib/stores/store.rb +0 -5
  188. data/lib/sync/stroke_diff/stroke_diff.rb +0 -9
  189. data/lib/util/ext/object.rb +0 -8
  190. data/lib/util/java_util.rb +0 -9
  191. data/lib/util/trigger_partition.rb +0 -136
  192. data/strokedb.rb +0 -75
@@ -0,0 +1,43 @@
1
+ module StrokeDB
2
+ # DP is for pointing to DataVolume item. It can address zillions
3
+ # of DataVolumes, 4 GB each.
4
+ #
5
+ # DP is stored as a 160 bit bytestring. First 128 bits is a volume UUID.
6
+ # Next 32 bits is an offset in a volume (unsigned long). Hence, the limit
7
+ # for DataVolume size: max 4 Gb. Actually, real-world applications would
8
+ # have relatively small datavolumes (about 64 Mb).
9
+ class DistributedPointer
10
+ attr_accessor :volume_uuid, :offset
11
+
12
+ # Initialize pointer with given components.
13
+ # * uuid UUID (either raw or formatted)
14
+ # * offset is a positive integer
15
+ #
16
+ def initialize(uuid, offset)
17
+ @volume_uuid = uuid.to_raw_uuid
18
+ @offset = offset
19
+ end
20
+
21
+ # Creates a pointer object using binary string.
22
+ #
23
+ def self.unpack(string160bit)
24
+ new(string160bit[0, 16], string160bit[16, 4].unpack("L")[0])
25
+ end
26
+
27
+ # Converts pointer object to it's string representation.
28
+ #
29
+ def pack
30
+ @volume_uuid + [@offset].pack("L")
31
+ end
32
+
33
+ def self.pack(uuid,offset)
34
+ uuid.to_raw_uuid + [offset].pack("L")
35
+ end
36
+
37
+ def inspect #:nodoc:
38
+ "#<DistributedPointer #{@volume_uuid.to_formatted_uuid}:#{@offset}>"
39
+ end
40
+
41
+ alias :to_s :inspect
42
+ end
43
+ end
@@ -0,0 +1,109 @@
1
+ module 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
109
+ end
@@ -0,0 +1,268 @@
1
+ require 'readbytes'
2
+ module StrokeDB
3
+
4
+ class MapVolume
5
+
6
+ HEADER_SIZE = 512
7
+ MAGIC_SIGNATURE = "\x11\x12\x19\x81"
8
+ VERSION = "00"
9
+
10
+ attr_accessor :first_available_position
11
+
12
+ def initialize(options = {})
13
+ @options = options.stringify_keys
14
+ initialize_file
15
+ end
16
+
17
+ def insert!(record)
18
+ position = find_first_available_position
19
+ write!(position,record)
20
+ end
21
+
22
+ def elastic_insert!(record)
23
+ position = find_first_available_chunk_position((record.size + 4) % 8)
24
+ elastic_write!(position,record)
25
+ end
26
+
27
+ def write!(position,record)
28
+ raise InvalidRecordSizeError if record.size != record_size
29
+ decrement_available_capacity!(position)
30
+ write_at_position!(position,record)
31
+ position
32
+ end
33
+
34
+ def elastic_write!(position,record)
35
+ decrement_available_chunk!(position,(record.size + 4) % 8)
36
+ elastic_write_at_position!(position,record)
37
+ position
38
+ end
39
+
40
+ def read(position)
41
+ raise InvalidRecordPositionError if available?(position)
42
+ read_at_position(position)
43
+ end
44
+
45
+ def elastic_read(position)
46
+ @data_file.seek(position*record_size)
47
+ size = @data_file.read(4).unpack('N').first
48
+ @data_file.read(size)
49
+ end
50
+
51
+ def delete!(position)
52
+ self.first_available_position = -1
53
+ increment_available_capacity!(position)
54
+ end
55
+
56
+ def available?(position)
57
+ read_map_byte(position) & (1 << (position % 8)) == 0
58
+ end
59
+
60
+ def empty?
61
+ read_map == "\x00" * map_size
62
+ end
63
+
64
+ def record_size
65
+ @options['record_size']
66
+ end
67
+
68
+ def bitmap_extension_pace
69
+ @options['bitmap_extension_pace']||8192
70
+ end
71
+
72
+ def path
73
+ @options['path']
74
+ end
75
+
76
+ def close!
77
+ @bitmap_file.close
78
+ @data_file.close
79
+ end
80
+
81
+ def map_size
82
+ return @map_size if @map_size
83
+ pos = @bitmap_file.pos
84
+ @bitmap_file.seek(0,IO::SEEK_END)
85
+ size = @bitmap_file.pos - HEADER_SIZE
86
+ @bitmap_file.seek(pos)
87
+ @map_size = size
88
+ end
89
+
90
+
91
+ private
92
+
93
+ def initialize_file
94
+ FileUtils.mkdir_p path
95
+ bitmap_path = File.join(path,'bitmap')
96
+ data_path = File.join(path,'data')
97
+ unless File.exists?(bitmap_path)
98
+ @bitmap_file = File.new(bitmap_path,'w+')
99
+ @first_available_position = 0
100
+ initialize_file_header!
101
+ initialize_file_map!
102
+ else
103
+ @bitmap_file = File.new(bitmap_path,'r+')
104
+ @first_available_position = -1
105
+ read_file_header
106
+ initialize_file_header!
107
+ end
108
+ unless File.exists?(data_path)
109
+ @data_file = File.new(data_path,'w+')
110
+ else
111
+ @data_file = File.new(data_path,'r+')
112
+ end
113
+ read_map
114
+ end
115
+
116
+ def read_file_header
117
+ @bitmap_file.seek(0)
118
+ begin
119
+ header = @bitmap_file.readbytes(HEADER_SIZE)
120
+ rescue TruncatedDataError
121
+ raise InvalidMapVolumeError
122
+ end
123
+ raise InvalidMapVolumeError unless header[0,4] = MAGIC_SIGNATURE
124
+ @options['record_size'] = header[6,4].unpack("N").first
125
+ @first_available_position = (pos = header[10,4].unpack("N").first) == 4294967295 ? -1 : pos
126
+ end
127
+
128
+ def initialize_file_header!
129
+ header = "\xff"*HEADER_SIZE
130
+ header[0,4] = MAGIC_SIGNATURE
131
+ header[4,2] = VERSION
132
+ header[6,4] = [record_size].pack("N")
133
+ header[10,4] = [first_available_position].pack("N")
134
+ @bitmap_file.seek(0)
135
+ @bitmap_file.write(header)
136
+ end
137
+
138
+ def update_file_header!
139
+ @bitmap_file.seek(10)
140
+ @bitmap_file.write([first_available_position].pack("N"))
141
+ end
142
+
143
+ def initialize_file_map!
144
+ extend_map
145
+ end
146
+
147
+
148
+ def read_map
149
+ return @bitmap if @bitmap
150
+ @bitmap_file.seek(HEADER_SIZE)
151
+ @bitmap = @bitmap_file.read(map_size)
152
+ end
153
+
154
+ def find_first_available_position
155
+ unless first_available_position == -1
156
+ first_available_position
157
+ else
158
+ byte_num = 0
159
+ byte = nil
160
+ read_map.each_byte do |v|
161
+ if v != 255
162
+ byte = v
163
+ break
164
+ else
165
+ byte_num += 1
166
+ false
167
+ end
168
+ end
169
+ if byte
170
+ byte_offset = byte.to_s(2).ljust(8,'0').index('0')
171
+ return byte_num*8 + byte_offset
172
+ end
173
+ nil
174
+ end
175
+ end
176
+
177
+ def find_first_available_chunk_position(chunk)
178
+ unless position = read_map.index("\x00" * chunk)
179
+ position = map_size * 8
180
+ extend_map
181
+ end
182
+ position
183
+ end
184
+
185
+ def decrement_available_capacity!(position)
186
+ byte = read_map_byte(position)
187
+ mask = (1 << (position % 8))
188
+ return unless byte & mask == 0
189
+
190
+ write_map_byte(position, byte | mask)
191
+
192
+ if read_map_byte(position + 1) == 255
193
+ @first_available_position = -1
194
+ else
195
+ @first_available_position = position + 1
196
+ end
197
+
198
+ update_file_header!
199
+ end
200
+
201
+ def decrement_available_chunk!(position,length)
202
+ @bitmap_file.seek(HEADER_SIZE + (position % 8))
203
+ update ="\xff" * (length+1)
204
+ @bitmap_file.write(update)
205
+ @first_available_position = -1
206
+ @bitmap[position%8,length+1] = update
207
+ update_file_header!
208
+ end
209
+
210
+
211
+ def increment_available_capacity!(position)
212
+ update_map_byte!(position) {|byte| byte & (255 ^ (1 << (position % 8))) }
213
+ update_file_header!
214
+ end
215
+
216
+ def update_map_byte!(position)
217
+ byte = yield(read_map_byte(position))
218
+ write_map_byte(position,byte)
219
+ end
220
+
221
+ def read_map_byte(position)
222
+ extend_map if map_size*8 <= position # TODO: spec it
223
+ read_map[position/8]
224
+ # @bitmap_file.seek(HEADER_SIZE + position/8)
225
+ # @bitmap_file.read(1).unpack('C').first # in Ruby 1.8 we can also do [0] instead of unpack
226
+ end
227
+
228
+ def write_map_byte(position,byte)
229
+ @bitmap_file.seek(HEADER_SIZE + position/8)
230
+ @bitmap_file.write([byte].pack('C'))
231
+ @bitmap[position/8] = byte
232
+ end
233
+
234
+ def write_at_position!(position,record)
235
+ @data_file.seek(position*record_size)
236
+ @data_file.write(record)
237
+ end
238
+
239
+ def elastic_write_at_position!(position,record)
240
+ @data_file.seek(position*record_size)
241
+ @data_file.write([record.size].pack('N') + record)
242
+ end
243
+
244
+ def read_at_position(position)
245
+ @data_file.seek(position*record_size)
246
+ @data_file.read(record_size)
247
+ end
248
+
249
+ def extend_map
250
+ pos = @bitmap_file.pos
251
+ @bitmap_file.truncate(pos + bitmap_extension_pace)
252
+ # @bitmap_file.seek(pos)
253
+ @bitmap += "\x00"*bitmap_extension_pace if @bitmap
254
+ @map_size = nil
255
+ end
256
+
257
+ end
258
+
259
+ class InvalidRecordSizeError < Exception
260
+ end
261
+
262
+ class InvalidRecordPositionError < Exception
263
+ end
264
+
265
+ class InvalidMapVolumeError < Exception
266
+ end
267
+
268
+ end
@@ -0,0 +1,175 @@
1
+ bench.html
2
+ bin/strokedb
3
+ examples/movies.rb
4
+ examples/movies2.rb
5
+ examples/strokewiki/README
6
+ examples/strokewiki/view/edit.xhtml
7
+ examples/strokewiki/view/new.xhtml
8
+ examples/strokewiki/view/pages.xhtml
9
+ examples/strokewiki/view/show.xhtml
10
+ examples/strokewiki/view/versions.xhtml
11
+ examples/strokewiki/wiki.rb
12
+ examples/todo.rb
13
+ lib/strokedb/config.rb
14
+ lib/strokedb/console.rb
15
+ lib/strokedb/core_ext/blank.rb
16
+ lib/strokedb/core_ext/enumerable.rb
17
+ lib/strokedb/core_ext/fixnum.rb
18
+ lib/strokedb/core_ext/float.rb
19
+ lib/strokedb/core_ext/hash.rb
20
+ lib/strokedb/core_ext/infinity.rb
21
+ lib/strokedb/core_ext/kernel.rb
22
+ lib/strokedb/core_ext/object.rb
23
+ lib/strokedb/core_ext/string.rb
24
+ lib/strokedb/core_ext/symbol.rb
25
+ lib/strokedb/core_ext.rb
26
+ lib/strokedb/data_structures/chunked_skiplist.rb
27
+ lib/strokedb/data_structures/inverted_list.rb
28
+ lib/strokedb/data_structures/point_query.rb
29
+ lib/strokedb/data_structures/simple_skiplist.rb
30
+ lib/strokedb/data_structures/skiplist.rb
31
+ lib/strokedb/data_structures.rb
32
+ lib/strokedb/document/callback.rb
33
+ lib/strokedb/document/delete.rb
34
+ lib/strokedb/document/dsl/associations.rb
35
+ lib/strokedb/document/dsl/coercions.rb
36
+ lib/strokedb/document/dsl/meta_dsl.rb
37
+ lib/strokedb/document/dsl/validations.rb
38
+ lib/strokedb/document/dsl/virtualize.rb
39
+ lib/strokedb/document/dsl.rb
40
+ lib/strokedb/document/meta.rb
41
+ lib/strokedb/document/slot.rb
42
+ lib/strokedb/document/util.rb
43
+ lib/strokedb/document/versions.rb
44
+ lib/strokedb/document.rb
45
+ lib/strokedb/index.rb
46
+ lib/strokedb/nsurl.rb
47
+ lib/strokedb/store.rb
48
+ lib/strokedb/stores/chainable_storage.rb
49
+ lib/strokedb/stores/file_storage.rb
50
+ lib/strokedb/stores/inverted_list_file_storage.rb
51
+ lib/strokedb/stores/memory_storage.rb
52
+ lib/strokedb/stores/remote_store.rb
53
+ lib/strokedb/stores.rb
54
+ lib/strokedb/sync/chain_sync.rb
55
+ lib/strokedb/sync/diff/array.rb
56
+ lib/strokedb/sync/diff/default.rb
57
+ lib/strokedb/sync/diff/hash.rb
58
+ lib/strokedb/sync/diff/string.rb
59
+ lib/strokedb/sync/diff.rb
60
+ lib/strokedb/sync/lamport_timestamp.rb
61
+ lib/strokedb/sync/store_sync.rb
62
+ lib/strokedb/sync.rb
63
+ lib/strokedb/transaction.rb
64
+ lib/strokedb/util/attach_dsl.rb
65
+ lib/strokedb/util/blankslate.rb
66
+ lib/strokedb/util/class_optimization.rb
67
+ lib/strokedb/util/inflect.rb
68
+ lib/strokedb/util/java_util.rb
69
+ lib/strokedb/util/lazy_array.rb
70
+ lib/strokedb/util/lazy_mapping_array.rb
71
+ lib/strokedb/util/lazy_mapping_hash.rb
72
+ lib/strokedb/util/serialization.rb
73
+ lib/strokedb/util/uuid.rb
74
+ lib/strokedb/util/xml.rb
75
+ lib/strokedb/util.rb
76
+ lib/strokedb/view.rb
77
+ lib/strokedb/volumes/archive_volume.rb
78
+ lib/strokedb/volumes/block_volume.rb
79
+ lib/strokedb/volumes/distributed_pointer.rb
80
+ lib/strokedb/volumes/fixed_length_skiplist_volume.rb
81
+ lib/strokedb/volumes/map_volume.rb
82
+ lib/strokedb/volumes.rb
83
+ lib/strokedb.rb
84
+ README
85
+ script/console
86
+ spec/integration/remote_store_spec.rb
87
+ spec/integration/search_spec.rb
88
+ spec/integration/spec_helper.rb
89
+ spec/lib/spec_helper.rb
90
+ spec/lib/strokedb/config_spec.rb
91
+ spec/lib/strokedb/core_ext/blank_spec.rb
92
+ spec/lib/strokedb/core_ext/extract_spec.rb
93
+ spec/lib/strokedb/core_ext/float_spec.rb
94
+ spec/lib/strokedb/core_ext/infinity_spec.rb
95
+ spec/lib/strokedb/core_ext/spec_helper.rb
96
+ spec/lib/strokedb/core_ext/string_spec.rb
97
+ spec/lib/strokedb/core_ext/symbol_spec.rb
98
+ spec/lib/strokedb/data_structures/chunked_skiplist_spec.rb
99
+ spec/lib/strokedb/data_structures/inverted_list_spec.rb
100
+ spec/lib/strokedb/data_structures/simple_skiplist_spec.rb
101
+ spec/lib/strokedb/data_structures/skiplist_spec.rb
102
+ spec/lib/strokedb/data_structures/spec_helper.rb
103
+ spec/lib/strokedb/document/associations_spec.rb
104
+ spec/lib/strokedb/document/callbacks_spec.rb
105
+ spec/lib/strokedb/document/coercions_spec.rb
106
+ spec/lib/strokedb/document/document_spec.rb
107
+ spec/lib/strokedb/document/meta_meta_spec.rb
108
+ spec/lib/strokedb/document/meta_spec.rb
109
+ spec/lib/strokedb/document/metaslot_spec.rb
110
+ spec/lib/strokedb/document/slot_spec.rb
111
+ spec/lib/strokedb/document/spec_helper.rb
112
+ spec/lib/strokedb/document/validations_spec.rb
113
+ spec/lib/strokedb/document/virtualize_spec.rb
114
+ spec/lib/strokedb/nsurl_spec.rb
115
+ spec/lib/strokedb/spec_helper.rb
116
+ spec/lib/strokedb/stores/chained_storages_spec.rb
117
+ spec/lib/strokedb/stores/spec_helper.rb
118
+ spec/lib/strokedb/stores/store_spec.rb
119
+ spec/lib/strokedb/stores/transaction_spec.rb
120
+ spec/lib/strokedb/sync/chain_sync_spec.rb
121
+ spec/lib/strokedb/sync/diff_spec.rb
122
+ spec/lib/strokedb/sync/lamport_timestamp_spec.rb
123
+ spec/lib/strokedb/sync/slot_diff_spec.rb
124
+ spec/lib/strokedb/sync/spec_helper.rb
125
+ spec/lib/strokedb/sync/store_sync_spec.rb
126
+ spec/lib/strokedb/sync/stroke_diff/array_spec.rb
127
+ spec/lib/strokedb/sync/stroke_diff/complex_spec.rb
128
+ spec/lib/strokedb/sync/stroke_diff/hash_spec.rb
129
+ spec/lib/strokedb/sync/stroke_diff/scalar_spec.rb
130
+ spec/lib/strokedb/sync/stroke_diff/spec_helper.rb
131
+ spec/lib/strokedb/sync/stroke_diff/string_spec.rb
132
+ spec/lib/strokedb/util/attach_dsl_spec.rb
133
+ spec/lib/strokedb/util/inflect_spec.rb
134
+ spec/lib/strokedb/util/lazy_array_spec.rb
135
+ spec/lib/strokedb/util/lazy_mapping_array_spec.rb
136
+ spec/lib/strokedb/util/lazy_mapping_hash_spec.rb
137
+ spec/lib/strokedb/util/spec_helper.rb
138
+ spec/lib/strokedb/util/uuid_spec.rb
139
+ spec/lib/strokedb/view_spec.rb
140
+ spec/lib/strokedb/volumes/archive_volume_spec.rb
141
+ spec/lib/strokedb/volumes/block_volume_spec.rb
142
+ spec/lib/strokedb/volumes/distributed_pointer_spec.rb
143
+ spec/lib/strokedb/volumes/fixed_length_skiplist_volume_spec.rb
144
+ spec/lib/strokedb/volumes/map_volume_spec.rb
145
+ spec/lib/strokedb/volumes/spec_helper.rb
146
+ spec/regression/docref_spec.rb
147
+ spec/regression/meta_spec.rb
148
+ spec/regression/spec_helper.rb
149
+ spec/regression/sync_spec.rb
150
+ spec/spec.opts
151
+ spec/spec_helper.rb
152
+ spec/temp/storages/database-sync/config
153
+ spec/temp/storages/database-sync/file/bd/f6/bdf675e5-8a7b-494e-97f2-f74a14ccd95d.av
154
+ spec/temp/storages/database-sync/file/LAST
155
+ spec/temp/storages/database-sync/file/uindex.wal
156
+ spec/temp/storages/database-sync/inverted_list_file/INVERTED_INDEX
157
+ spec/temp/storages/database-sync/TIMESTAMP
158
+ spec/temp/storages/database-sync/UUID
159
+ spec/temp/storages/inverted_list_storage/INVERTED_INDEX
160
+ spec/temp/storages/TIMESTAMP
161
+ spec/temp/storages/UUID
162
+ strokedb.gemspec
163
+ task/benchmark.task
164
+ task/ditz.task
165
+ task/echoe.rb
166
+ task/rcov.task
167
+ task/rdoc.task
168
+ task/rspec.task
169
+ vendor/java_inline.rb
170
+ vendor/rbmodexcl/mrimodexcl.rb
171
+ vendor/rbmodexcl/rbmodexcl.rb
172
+ vendor/rbmodexcl/rbxmodexcl.rb
173
+ vendor/rbmodexcl/spec/unextend_spec.rb
174
+ vendor/rbmodexcl/spec/uninclude_spec.rb
175
+ meta/MANIFEST