Class: StrokeDB::SkiplistStore
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from Enumerable
#each_consecutive_pair, #group_by, #map_with_index, #trigger_partition
Methods inherited from Store
#remote_server, #sync!
Methods included from ChainSync
#sync_chains
Constructor Details
6
7
8
9
10
11
12
13
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 6
def initialize(opts={})
opts = opts.stringify_keys
@chunk_storage = opts['storage']
@cut_level = opts['cut_level'] || 4
@index_store = opts['index']
autosync! unless opts['noautosync']
raise "Missing chunk storage" unless @chunk_storage
end
|
Instance Attribute Details
#chunk_storage ⇒ Object
Returns the value of attribute chunk_storage.
4
5
6
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 4
def chunk_storage
@chunk_storage
end
|
#cut_level ⇒ Object
Returns the value of attribute cut_level.
4
5
6
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 4
def cut_level
@cut_level
end
|
#index_store ⇒ Object
Returns the value of attribute index_store.
4
5
6
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 4
def index_store
@index_store
end
|
Instance Method Details
#autosync! ⇒ Object
132
133
134
135
136
137
138
139
140
141
142
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 132
def autosync!
@autosync_mutex ||= Mutex.new
@autosync = nil if @autosync && !@autosync.status
at_exit { stop_autosync! }
@autosync ||= Thread.new do
until @stop_autosync
@autosync_mutex.synchronize { chunk_storage.sync_chained_storages! }
sleep(1)
end
end
end
|
120
121
122
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 120
def document
find(uuid) || StoreInfo.create!(self,:kind => 'skiplist', :uuid => uuid)
end
|
#each(options = {}) ⇒ Object
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 84
def each(options = {})
return nil unless m = @chunk_storage.find('MASTER') after = options[:after_timestamp]
include_versions = options[:include_versions]
m.each do |node|
chunk = @chunk_storage.find(node.value)
next unless chunk
next if after && chunk.timestamp <= after
chunk.each do |node|
next if after && (node.timestamp <= after)
if uuid_match = node.key.match(/^#{UUID_RE}$/) || (include_versions && uuid_match = node.key.match(/#{UUID_RE}./) )
yield Document.from_raw(self, node.value)
end
end
end
end
|
#empty? ⇒ Boolean
124
125
126
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 124
def empty?
!@chunk_storage.find('MASTER')
end
|
#exists?(uuid, version = nil) ⇒ Boolean
40
41
42
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 40
def exists?(uuid, version=nil)
!!find(uuid, version, :no_instantiation => true)
end
|
#find(uuid, version = nil, opts = {}) ⇒ Object
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 15
def find(uuid, version=nil, opts = {})
uuid_version = uuid + (version ? ".#{version}" : "")
master_chunk = @chunk_storage.find('MASTER')
return nil unless master_chunk chunk_uuid = master_chunk.find_nearest(uuid_version, nil)
return nil unless chunk_uuid chunk = @chunk_storage.find(chunk_uuid)
return nil unless chunk
raw_doc = chunk.find(uuid_version)
if raw_doc
return raw_doc if opts[:no_instantiation]
doc = Document.from_raw(self, raw_doc.freeze)
doc.extend(VersionedDocument) if version
return doc
end
nil
end
|
#full_dump ⇒ Object
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 67
def full_dump
puts "Full storage dump:"
m = @chunk_storage.find('MASTER')
puts "No master!" unless m
m.each do |node|
puts "[chunk: #{node.key}]"
chunk = @chunk_storage.find(node.value)
if chunk
chunk.each do |node|
puts " [doc: #{node.key}] => {uuid: #{node.value['__uuid__']}, version: #{node.value['version']}, previous_version: #{node.value['previous_version']}"
end
else
puts " nil! (but in MASTER somehow?...)"
end
end
end
|
#head_version(uuid) ⇒ Object
44
45
46
47
48
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 44
def head_version(uuid)
raw_doc = find(uuid, nil, :no_instantiation => true)
return raw_doc['version'] if raw_doc
nil
end
|
128
129
130
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 128
def inspect
"#<Skiplist store #{uuid}#{empty? ? " (empty)" : ""}>"
end
|
#next_timestamp ⇒ Object
105
106
107
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 105
def next_timestamp
@timestamp = timestamp.next
end
|
#save!(doc) ⇒ Object
50
51
52
53
54
55
56
57
58
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 50
def save!(doc)
master_chunk = find_or_create_master_chunk
next_timestamp
insert_with_cut(doc.uuid, doc, master_chunk) unless doc.is_a?(VersionedDocument)
insert_with_cut("#{doc.uuid}.#{doc.version}", doc, master_chunk)
update_master_chunk!(doc, master_chunk)
end
|
#save_as_head!(doc) ⇒ Object
60
61
62
63
64
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 60
def save_as_head!(doc)
master_chunk = find_or_create_master_chunk
insert_with_cut(doc.uuid, doc, master_chunk)
update_master_chunk!(doc, master_chunk)
end
|
#search(*args) ⇒ Object
35
36
37
38
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 35
def search(*args)
return [] unless @index_store
@index_store.find(*args)
end
|
#stop_autosync! ⇒ Object
144
145
146
147
148
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 144
def stop_autosync!
if @autosync_mutex
@autosync_mutex.synchronize { @stop_autosync = true; chunk_storage.sync_chained_storages! }
end
end
|
#timestamp ⇒ Object
102
103
104
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 102
def timestamp
@timestamp ||= (lts = find_or_create_master_chunk.timestamp) ? LTS.from_raw(lts) : LTS.zero(uuid)
end
|
109
110
111
112
113
114
115
116
117
118
|
# File 'lib/stores/skiplist_store/skiplist_store.rb', line 109
def uuid
return @uuid if @uuid
master_chunk = @chunk_storage.find('MASTER')
unless master_chunk
@uuid = Util.random_uuid
else
@uuid = master_chunk.store_uuid
end
@uuid
end
|