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.
- data/README +18 -20
- data/bench.html +4001 -0
- data/bin/strokedb +14 -0
- data/examples/movies.rb +105 -0
- data/examples/movies2.rb +97 -0
- data/examples/strokewiki/README +28 -0
- data/examples/strokewiki/view/edit.xhtml +27 -0
- data/examples/strokewiki/view/new.xhtml +26 -0
- data/examples/strokewiki/view/pages.xhtml +27 -0
- data/examples/strokewiki/view/show.xhtml +40 -0
- data/examples/strokewiki/view/versions.xhtml +25 -0
- data/examples/strokewiki/wiki.rb +106 -0
- data/examples/todo.rb +92 -0
- data/lib/strokedb.rb +85 -0
- data/lib/{config → strokedb}/config.rb +14 -9
- data/lib/strokedb/console.rb +87 -0
- data/lib/strokedb/core_ext.rb +10 -0
- data/lib/{util/ext → strokedb/core_ext}/blank.rb +1 -1
- data/lib/{util/ext → strokedb/core_ext}/enumerable.rb +0 -0
- data/lib/{util/ext → strokedb/core_ext}/fixnum.rb +0 -0
- data/lib/strokedb/core_ext/float.rb +4 -0
- data/lib/{util/ext → strokedb/core_ext}/hash.rb +0 -0
- data/lib/strokedb/core_ext/infinity.rb +33 -0
- data/lib/strokedb/core_ext/kernel.rb +41 -0
- data/lib/strokedb/core_ext/object.rb +16 -0
- data/lib/{util/ext → strokedb/core_ext}/string.rb +28 -1
- data/lib/strokedb/core_ext/symbol.rb +13 -0
- data/lib/strokedb/data_structures.rb +5 -0
- data/lib/strokedb/data_structures/chunked_skiplist.rb +123 -0
- data/lib/{data_structures → strokedb/data_structures}/inverted_list.rb +0 -0
- data/lib/{data_structures → strokedb/data_structures}/point_query.rb +0 -0
- data/lib/strokedb/data_structures/simple_skiplist.rb +350 -0
- data/lib/{data_structures → strokedb/data_structures}/skiplist.rb +1 -1
- data/lib/{document → strokedb}/document.rb +180 -71
- data/lib/{document → strokedb/document}/callback.rb +0 -0
- data/lib/{document → strokedb/document}/delete.rb +2 -2
- data/lib/strokedb/document/dsl.rb +4 -0
- data/lib/{document → strokedb/document/dsl}/associations.rb +0 -0
- data/lib/{document → strokedb/document/dsl}/coercions.rb +0 -0
- data/lib/strokedb/document/dsl/meta_dsl.rb +7 -0
- data/lib/{document → strokedb/document/dsl}/validations.rb +26 -21
- data/lib/{document → strokedb/document/dsl}/virtualize.rb +0 -0
- data/lib/{document → strokedb/document}/meta.rb +92 -29
- data/lib/{document → strokedb/document}/slot.rb +17 -5
- data/lib/{document → strokedb/document}/util.rb +0 -0
- data/lib/{document → strokedb/document}/versions.rb +2 -2
- data/lib/strokedb/index.rb +2 -0
- data/lib/strokedb/nsurl.rb +24 -0
- data/lib/strokedb/store.rb +149 -0
- data/lib/strokedb/stores.rb +6 -0
- data/lib/{stores → strokedb/stores}/chainable_storage.rb +20 -14
- data/lib/strokedb/stores/file_storage.rb +118 -0
- data/lib/{stores/inverted_list_index → strokedb/stores}/inverted_list_file_storage.rb +50 -0
- data/lib/strokedb/stores/memory_storage.rb +80 -0
- data/lib/{stores → strokedb/stores}/remote_store.rb +10 -4
- data/lib/strokedb/sync.rb +4 -0
- data/lib/{sync → strokedb/sync}/chain_sync.rb +0 -0
- data/lib/{sync → strokedb/sync}/diff.rb +12 -1
- data/lib/{sync/stroke_diff → strokedb/sync/diff}/array.rb +1 -1
- data/lib/{sync/stroke_diff → strokedb/sync/diff}/default.rb +0 -0
- data/lib/{sync/stroke_diff → strokedb/sync/diff}/hash.rb +1 -1
- data/lib/{sync/stroke_diff → strokedb/sync/diff}/string.rb +1 -1
- data/lib/{sync → strokedb/sync}/lamport_timestamp.rb +0 -0
- data/lib/{sync → strokedb/sync}/store_sync.rb +15 -7
- data/lib/strokedb/transaction.rb +78 -0
- data/lib/{util → strokedb}/util.rb +14 -7
- data/lib/strokedb/util/attach_dsl.rb +29 -0
- data/lib/{util → strokedb/util}/blankslate.rb +0 -0
- data/lib/strokedb/util/class_optimization.rb +93 -0
- data/lib/{util → strokedb/util}/inflect.rb +0 -0
- data/lib/strokedb/util/java_util.rb +13 -0
- data/lib/{util → strokedb/util}/lazy_array.rb +0 -0
- data/lib/{util → strokedb/util}/lazy_mapping_array.rb +4 -0
- data/lib/{util → strokedb/util}/lazy_mapping_hash.rb +0 -0
- data/lib/{util → strokedb/util}/serialization.rb +21 -0
- data/lib/strokedb/util/uuid.rb +159 -0
- data/lib/{util → strokedb/util}/xml.rb +0 -0
- data/lib/{view → strokedb}/view.rb +2 -2
- data/lib/strokedb/volumes.rb +5 -0
- data/lib/strokedb/volumes/archive_volume.rb +165 -0
- data/lib/strokedb/volumes/block_volume.rb +169 -0
- data/lib/strokedb/volumes/distributed_pointer.rb +43 -0
- data/lib/strokedb/volumes/fixed_length_skiplist_volume.rb +109 -0
- data/lib/strokedb/volumes/map_volume.rb +268 -0
- data/meta/MANIFEST +175 -0
- data/script/console +2 -70
- data/spec/integration/remote_store_spec.rb +70 -0
- data/spec/integration/search_spec.rb +76 -0
- data/spec/integration/spec_helper.rb +1 -0
- data/spec/lib/spec_helper.rb +1 -0
- data/spec/lib/strokedb/config_spec.rb +250 -0
- data/spec/lib/strokedb/core_ext/blank_spec.rb +20 -0
- data/spec/lib/strokedb/core_ext/extract_spec.rb +42 -0
- data/spec/lib/strokedb/core_ext/float_spec.rb +62 -0
- data/spec/lib/strokedb/core_ext/infinity_spec.rb +40 -0
- data/spec/lib/strokedb/core_ext/spec_helper.rb +1 -0
- data/spec/lib/strokedb/core_ext/string_spec.rb +25 -0
- data/spec/lib/strokedb/core_ext/symbol_spec.rb +8 -0
- data/spec/lib/strokedb/data_structures/chunked_skiplist_spec.rb +144 -0
- data/spec/lib/strokedb/data_structures/inverted_list_spec.rb +172 -0
- data/spec/lib/strokedb/data_structures/simple_skiplist_spec.rb +200 -0
- data/spec/lib/strokedb/data_structures/skiplist_spec.rb +253 -0
- data/spec/lib/strokedb/data_structures/spec_helper.rb +1 -0
- data/spec/lib/strokedb/document/associations_spec.rb +319 -0
- data/spec/lib/strokedb/document/callbacks_spec.rb +134 -0
- data/spec/lib/strokedb/document/coercions_spec.rb +110 -0
- data/spec/lib/strokedb/document/document_spec.rb +1063 -0
- data/spec/lib/strokedb/document/meta_meta_spec.rb +30 -0
- data/spec/lib/strokedb/document/meta_spec.rb +435 -0
- data/spec/lib/strokedb/document/metaslot_spec.rb +43 -0
- data/spec/lib/strokedb/document/slot_spec.rb +130 -0
- data/spec/lib/strokedb/document/spec_helper.rb +1 -0
- data/spec/lib/strokedb/document/validations_spec.rb +1081 -0
- data/spec/lib/strokedb/document/virtualize_spec.rb +80 -0
- data/spec/lib/strokedb/nsurl_spec.rb +73 -0
- data/spec/lib/strokedb/spec_helper.rb +1 -0
- data/spec/lib/strokedb/stores/chained_storages_spec.rb +116 -0
- data/spec/lib/strokedb/stores/spec_helper.rb +1 -0
- data/spec/lib/strokedb/stores/store_spec.rb +201 -0
- data/spec/lib/strokedb/stores/transaction_spec.rb +107 -0
- data/spec/lib/strokedb/sync/chain_sync_spec.rb +43 -0
- data/spec/lib/strokedb/sync/diff_spec.rb +111 -0
- data/spec/lib/strokedb/sync/lamport_timestamp_spec.rb +174 -0
- data/spec/lib/strokedb/sync/slot_diff_spec.rb +164 -0
- data/spec/lib/strokedb/sync/spec_helper.rb +1 -0
- data/spec/lib/strokedb/sync/store_sync_spec.rb +181 -0
- data/spec/lib/strokedb/sync/stroke_diff/array_spec.rb +97 -0
- data/spec/lib/strokedb/sync/stroke_diff/complex_spec.rb +58 -0
- data/spec/lib/strokedb/sync/stroke_diff/hash_spec.rb +144 -0
- data/spec/lib/strokedb/sync/stroke_diff/scalar_spec.rb +23 -0
- data/spec/lib/strokedb/sync/stroke_diff/spec_helper.rb +25 -0
- data/spec/lib/strokedb/sync/stroke_diff/string_spec.rb +61 -0
- data/spec/lib/strokedb/util/attach_dsl_spec.rb +45 -0
- data/spec/lib/strokedb/util/inflect_spec.rb +14 -0
- data/spec/lib/strokedb/util/lazy_array_spec.rb +157 -0
- data/spec/lib/strokedb/util/lazy_mapping_array_spec.rb +174 -0
- data/spec/lib/strokedb/util/lazy_mapping_hash_spec.rb +92 -0
- data/spec/lib/strokedb/util/spec_helper.rb +1 -0
- data/spec/lib/strokedb/util/uuid_spec.rb +46 -0
- data/spec/lib/strokedb/view_spec.rb +228 -0
- data/spec/lib/strokedb/volumes/archive_volume_spec.rb +105 -0
- data/spec/lib/strokedb/volumes/block_volume_spec.rb +100 -0
- data/spec/lib/strokedb/volumes/distributed_pointer_spec.rb +14 -0
- data/spec/lib/strokedb/volumes/fixed_length_skiplist_volume_spec.rb +177 -0
- data/spec/lib/strokedb/volumes/map_volume_spec.rb +172 -0
- data/spec/lib/strokedb/volumes/spec_helper.rb +1 -0
- data/spec/regression/docref_spec.rb +94 -0
- data/spec/regression/meta_spec.rb +23 -0
- data/spec/regression/spec_helper.rb +1 -0
- data/spec/regression/sync_spec.rb +36 -0
- data/spec/spec.opts +7 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/temp/storages/TIMESTAMP +1 -0
- data/spec/temp/storages/UUID +1 -0
- data/spec/temp/storages/database-sync/TIMESTAMP +1 -0
- data/spec/temp/storages/database-sync/UUID +1 -0
- data/spec/temp/storages/database-sync/config +1 -0
- data/spec/temp/storages/database-sync/file/LAST +1 -0
- data/spec/temp/storages/database-sync/file/bd/f6/bdf675e5-8a7b-494e-97f2-f74a14ccd95d.av +0 -0
- data/spec/temp/storages/database-sync/file/uindex.wal +0 -0
- data/spec/temp/storages/database-sync/inverted_list_file/INVERTED_INDEX +1 -0
- data/spec/temp/storages/inverted_list_storage/INVERTED_INDEX +0 -0
- data/strokedb.gemspec +120 -0
- data/task/benchmark.task +9 -0
- data/task/ditz.task +30 -0
- data/task/echoe.rb +17 -0
- data/task/rcov.task +50 -0
- data/task/rdoc.task +10 -0
- data/task/rspec.task +0 -0
- data/vendor/java_inline.rb +106 -0
- data/vendor/rbmodexcl/mrimodexcl.rb +82 -0
- data/vendor/rbmodexcl/rbmodexcl.rb +5 -0
- data/vendor/rbmodexcl/rbxmodexcl.rb +48 -0
- data/vendor/rbmodexcl/spec/unextend_spec.rb +50 -0
- data/vendor/rbmodexcl/spec/uninclude_spec.rb +26 -0
- metadata +271 -79
- data/CONTRIBUTORS +0 -7
- data/CREDITS +0 -13
- data/bin/sdbc +0 -2
- data/lib/init.rb +0 -57
- data/lib/stores/inverted_list_index/inverted_list_index.rb +0 -49
- data/lib/stores/skiplist_store/chunk.rb +0 -119
- data/lib/stores/skiplist_store/chunk_storage.rb +0 -21
- data/lib/stores/skiplist_store/file_chunk_storage.rb +0 -44
- data/lib/stores/skiplist_store/memory_chunk_storage.rb +0 -37
- data/lib/stores/skiplist_store/skiplist_store.rb +0 -217
- data/lib/stores/store.rb +0 -5
- data/lib/sync/stroke_diff/stroke_diff.rb +0 -9
- data/lib/util/ext/object.rb +0 -8
- data/lib/util/java_util.rb +0 -9
- data/lib/util/trigger_partition.rb +0 -136
- 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
|
data/meta/MANIFEST
ADDED
@@ -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
|