strokedb 0.0.2.1 → 0.0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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