Add cached indexes (index, partition, tag): we are now 500x faster.
parent
f5c9d1a7f2
commit
061e945384
|
@ -108,4 +108,22 @@ class DODB::CachedDataBase(V) < DODB::Storage(V)
|
||||||
super
|
super
|
||||||
@data = Hash(Int32, V).new
|
@data = Hash(Int32, V).new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def new_index(name : String, &block : Proc(V, String))
|
||||||
|
CachedIndex(V).new(self, @directory_name, name, block).tap do |indexer|
|
||||||
|
@indexers << indexer
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_partition(name : String, &block : Proc(V, String))
|
||||||
|
CachedPartition(V).new(self, @directory_name, name, block).tap do |table|
|
||||||
|
@indexers << table
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_tags(name : String, &block : Proc(V, Array(String)))
|
||||||
|
CachedTags(V).new(self, @directory_name, name, block).tap do |tags|
|
||||||
|
@indexers << tags
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -142,3 +142,43 @@ class DODB::Index(V) < DODB::Indexer(V)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class DODB::CachedIndex(V) < DODB::Index(V)
|
||||||
|
# This hash contains the relation between the index key and the data key.
|
||||||
|
property data = Hash(String, Int32).new
|
||||||
|
|
||||||
|
def check!(key, value, old_value)
|
||||||
|
index_key = key_proc.call value
|
||||||
|
|
||||||
|
# FIXME: Check it’s not pointing to “old_value”, if any, before raising.
|
||||||
|
if data[index_key]?
|
||||||
|
if old_value
|
||||||
|
old_key = key_proc.call old_value
|
||||||
|
return if index_key == old_key
|
||||||
|
end
|
||||||
|
|
||||||
|
raise IndexOverload.new "index '#{@name}' is overloaded for key '#{key}'"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def index(key, value)
|
||||||
|
super(key, value)
|
||||||
|
|
||||||
|
index_key = key_proc.call value
|
||||||
|
return if index_key.is_a? NoIndex
|
||||||
|
|
||||||
|
@data[index_key] = key.to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
def deindex(key, value)
|
||||||
|
super(key, value)
|
||||||
|
|
||||||
|
index_key = key_proc.call value
|
||||||
|
return if index_key.is_a? NoIndex
|
||||||
|
|
||||||
|
@data.delete index_key
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(index : String) : V
|
||||||
|
@storage[@data[index]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -93,3 +93,41 @@ class DODB::Partition(V) < DODB::Indexer(V)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class DODB::CachedPartition(V) < DODB::Partition(V)
|
||||||
|
# This hash contains the relation between the index key and the data keys.
|
||||||
|
property data = Hash(String, Array(Int32)).new
|
||||||
|
|
||||||
|
def index(key, value)
|
||||||
|
super(key, value)
|
||||||
|
partition = key_proc.call value
|
||||||
|
|
||||||
|
array = if v = @data[partition]?
|
||||||
|
v
|
||||||
|
else
|
||||||
|
Array(Int32).new
|
||||||
|
end
|
||||||
|
array << key.to_i
|
||||||
|
|
||||||
|
@data[partition] = array
|
||||||
|
end
|
||||||
|
|
||||||
|
def deindex(key, value)
|
||||||
|
super(key, value)
|
||||||
|
partition = key_proc.call value
|
||||||
|
|
||||||
|
if v = @data[partition]?
|
||||||
|
v.delete key.to_i
|
||||||
|
@data[partition] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(partition)
|
||||||
|
r_value = Array(V).new
|
||||||
|
|
||||||
|
@data[partition].each do |data_key|
|
||||||
|
r_value << @storage[data_key]
|
||||||
|
end
|
||||||
|
|
||||||
|
r_value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -107,3 +107,46 @@ class DODB::Tags(V) < DODB::Indexer(V)
|
||||||
"../../../data/#{key}"
|
"../../../data/#{key}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class DODB::CachedTags(V) < DODB::Tags(V)
|
||||||
|
# This hash contains the relation between the index key and the data keys.
|
||||||
|
property data = Hash(String, Array(Int32)).new
|
||||||
|
|
||||||
|
def index(key, value)
|
||||||
|
super(key, value)
|
||||||
|
indices = key_proc.call value
|
||||||
|
|
||||||
|
indices.each do |tag|
|
||||||
|
array = if v = @data[tag]?
|
||||||
|
v
|
||||||
|
else
|
||||||
|
Array(Int32).new
|
||||||
|
end
|
||||||
|
array << key.to_i
|
||||||
|
|
||||||
|
@data[tag] = array
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def deindex(key, value)
|
||||||
|
super(key, value)
|
||||||
|
indices = key_proc.call value
|
||||||
|
|
||||||
|
indices.each do |tag|
|
||||||
|
if v = @data[tag]?
|
||||||
|
v.delete key.to_i
|
||||||
|
@data[tag] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(tag : String)
|
||||||
|
r_value = Array(V).new
|
||||||
|
|
||||||
|
@data[tag].each do |data_key|
|
||||||
|
r_value << @storage[data_key]
|
||||||
|
end
|
||||||
|
|
||||||
|
r_value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in New Issue