Renaming, big time.

This commit is contained in:
Philippe PITTOLI 2024-05-27 17:38:37 +02:00
parent e152bc0ee7
commit 9d2b5157fe
8 changed files with 116 additions and 114 deletions

View File

@ -1,7 +1,10 @@
# The `DODB::Storage` abstract class defines the specifications of # The `DODB::Storage` abstract class defines the specifications of
# subsequent DODB databases (uncached, cached, RAM-only, etc.). # subsequent DODB databases (uncached, cached, RAM-only, etc.).
abstract class DODB::Storage(V) abstract class DODB::Storage(V)
@indexers = [] of Index(V) # List of triggers (basic indexes, partitions, tags, etc.).
@triggers = [] of Trigger(V)
# Directory where data and triggers will be written.
property directory_name : String property directory_name : String
# Creates a database. # Creates a database.
@ -161,16 +164,16 @@ abstract class DODB::Storage(V)
hash hash
end end
# Writes all indexes (basic indexes, partitions, tags, etc.) for a value. # Run triggers (indexes, partitions, tags, etc.) for a value.
def write_indexes(key : Int32, value : V) def run_triggers(key : Int32, value : V)
@indexers.each &.index(stringify_key(key), value) @triggers.each &.index(stringify_key(key), value)
end end
# Creates a new basic index **with a cache**. # Creates a new basic index **with a cache**.
# The *name* parameter is the name of the directory that will be created. # The *name* parameter is the name of the directory that will be created.
def new_index(name : String, &block : Proc(V, String | DODB::NoIndex)) def new_index(name : String, &block : Proc(V, String | DODB::NoIndex))
Index::BasicCached(V).new(self, @directory_name, name, block).tap do |indexer| Trigger::IndexCached(V).new(self, @directory_name, name, block).tap do |trigger|
@indexers << indexer @triggers << trigger
end end
end end
@ -179,8 +182,8 @@ abstract class DODB::Storage(V)
# #
# NOTE: this will be a lot slower than the cached version. # NOTE: this will be a lot slower than the cached version.
def new_uncached_index(name : String, &block : Proc(V, String | DODB::NoIndex)) def new_uncached_index(name : String, &block : Proc(V, String | DODB::NoIndex))
Index::Basic(V).new(self, @directory_name, name, block).tap do |indexer| Trigger::Index(V).new(self, @directory_name, name, block).tap do |trigger|
@indexers << indexer @triggers << trigger
end end
end end
@ -189,22 +192,22 @@ abstract class DODB::Storage(V)
# #
# NOTE: this index is the fastest, but doesn't have a file-system representation. # NOTE: this index is the fastest, but doesn't have a file-system representation.
def new_RAM_index(name : String, &block : Proc(V, String | DODB::NoIndex)) def new_RAM_index(name : String, &block : Proc(V, String | DODB::NoIndex))
Index::BasicRAMOnly(V).new(self, @directory_name, name, block).tap do |indexer| Trigger::IndexRAMOnly(V).new(self, @directory_name, name, block).tap do |trigger|
@indexers << indexer @triggers << trigger
end end
end end
# Gets an *index object* based on its name. # Gets an *index object* based on its name.
def get_index(name : String, key) def get_index(name : String, key)
index = @indexers.find &.name.==(name) index = @triggers.find &.name.==(name)
index.not_nil!.as(DODB::Index).get key index.not_nil!.as(Trigger).get key
end end
# Creates a new partition **with a cache**. # Creates a new partition **with a cache**.
# The *name* parameter is the name of the directory that will be created. # The *name* parameter is the name of the directory that will be created.
def new_partition(name : String, &block : Proc(V, String | DODB::NoIndex)) def new_partition(name : String, &block : Proc(V, String | DODB::NoIndex))
Index::PartitionCached(V).new(self, @directory_name, name, block).tap do |table| Trigger::PartitionCached(V).new(self, @directory_name, name, block).tap do |table|
@indexers << table @triggers << table
end end
end end
@ -213,8 +216,8 @@ abstract class DODB::Storage(V)
# #
# NOTE: this will be a lot slower than the cached version. # NOTE: this will be a lot slower than the cached version.
def new_uncached_partition(name : String, &block : Proc(V, String | DODB::NoIndex)) def new_uncached_partition(name : String, &block : Proc(V, String | DODB::NoIndex))
Index::Partition(V).new(self, @directory_name, name, block).tap do |table| Trigger::Partition(V).new(self, @directory_name, name, block).tap do |table|
@indexers << table @triggers << table
end end
end end
@ -223,22 +226,22 @@ abstract class DODB::Storage(V)
# #
# NOTE: this partition index is the fastest but doesn't have a file-system representation. # NOTE: this partition index is the fastest but doesn't have a file-system representation.
def new_RAM_partition(name : String, &block : Proc(V, String | DODB::NoIndex)) def new_RAM_partition(name : String, &block : Proc(V, String | DODB::NoIndex))
Index::PartitionRAMOnly(V).new(self, @directory_name, name, block).tap do |table| Trigger::PartitionRAMOnly(V).new(self, @directory_name, name, block).tap do |table|
@indexers << table @triggers << table
end end
end end
# Gets an *index (partition) object* based on its name. # Gets an *index (partition) object* based on its name.
def get_partition(table_name : String, partition_name : String) def get_partition(table_name : String, partition_name : String)
partition = @indexers.find &.name.==(table_name) partition = @triggers.find &.name.==(table_name)
partition.not_nil!.as(DODB::Partition).get partition_name partition.not_nil!.as(DODB::Partition).get partition_name
end end
# Creates a new tag **with a cache**. # Creates a new tag **with a cache**.
# The *name* parameter is the name of the directory that will be created. # The *name* parameter is the name of the directory that will be created.
def new_tags(name : String, &block : Proc(V, Array(String) | DODB::NoIndex)) def new_tags(name : String, &block : Proc(V, Array(String) | DODB::NoIndex))
Index::TagsCached(V).new(self, @directory_name, name, block).tap do |tags| Trigger::TagsCached(V).new(self, @directory_name, name, block).tap do |tags|
@indexers << tags @triggers << tags
end end
end end
@ -247,8 +250,8 @@ abstract class DODB::Storage(V)
# #
# NOTE: this will be a lot slower than the cached version. # NOTE: this will be a lot slower than the cached version.
def new_uncached_tags(name : String, &block : Proc(V, Array(String) | DODB::NoIndex)) def new_uncached_tags(name : String, &block : Proc(V, Array(String) | DODB::NoIndex))
Index::Tags(V).new(self, @directory_name, name, block).tap do |tags| Trigger::Tags(V).new(self, @directory_name, name, block).tap do |tags|
@indexers << tags @triggers << tags
end end
end end
@ -257,27 +260,27 @@ abstract class DODB::Storage(V)
# #
# NOTE: this tag index is the fastest but doesn't have a file-system representation. # NOTE: this tag index is the fastest but doesn't have a file-system representation.
def new_RAM_tags(name : String, &block : Proc(V, Array(String) | DODB::NoIndex)) def new_RAM_tags(name : String, &block : Proc(V, Array(String) | DODB::NoIndex))
Index::TagsRAMOnly(V).new(self, @directory_name, name, block).tap do |tags| Trigger::TagsRAMOnly(V).new(self, @directory_name, name, block).tap do |tags|
@indexers << tags @triggers << tags
end end
end end
# Gets an *index (tag) object* based on its name. # Gets an *index (tag) object* based on its name.
def get_tags(name, key : String) def get_tags(name, key : String)
tag = @indexers.find &.name.==(name) tag = @triggers.find &.name.==(name)
tag.not_nil!.as(DODB::Tags).get name, key tag.not_nil!.as(DODB::Tags).get name, key
end end
# WARNING: directed graphs haven't been reviewed in YEARS, assume as dead code. # WARNING: directed graphs haven't been reviewed in YEARS, assume as dead code.
def new_directed_graph(name : String, index : DODB::Index(V), &block : Proc(V, Array(String))) : DirectedGraph(V) def new_directed_graph(name : String, index : DODB::Trigger(V), &block : Proc(V, Array(String))) : DirectedGraph(V)
Index::DirectedGraph(V).new(self, @directory_name, index, name, block).tap do |table| Trigger::DirectedGraph(V).new(self, @directory_name, index, name, block).tap do |table|
@indexers << table @triggers << table
end end
end end
# Checks for collisions in the indexes. # Checks for collisions in the indexes.
def check_collisions!(key : Int32, value : V, old_value : V?) def check_collisions!(key : Int32, value : V, old_value : V?)
@indexers.each &.check!(stringify_key(key), value, old_value) @triggers.each &.check!(stringify_key(key), value, old_value)
end end
# Retrieves a value and remove it from the database. # Retrieves a value and remove it from the database.
@ -336,9 +339,9 @@ abstract class DODB::Storage(V)
Dir.mkdir_p data_path Dir.mkdir_p data_path
end end
private def remove_indexing! private def remove_triggers!
@indexers.each do |indexer| @triggers.each do |trigger|
indexer.nuke_index trigger.nuke_trigger
end end
end end
@ -346,16 +349,16 @@ abstract class DODB::Storage(V)
# #
# WARNING: slow operation. # WARNING: slow operation.
def reindex_everything! def reindex_everything!
remove_indexing! remove_triggers!
each_with_key() do |item, key| each_with_key() do |item, key|
write_indexes key, item run_triggers key, item
end end
end end
# Removes all indexes of a value. # Removes all indexes of a value.
def remove_indexes(key : Int32, value : V) def remove_triggers(key : Int32, value : V)
@indexers.each &.deindex(stringify_key(key), value) @triggers.each &.deindex(stringify_key(key), value)
end end
# Gets the data with the *key*. # Gets the data with the *key*.
@ -384,7 +387,7 @@ abstract class DODB::Storage(V)
# Removes any old indices or partitions pointing to a value about # Removes any old indices or partitions pointing to a value about
# to be replaced. # to be replaced.
if old_value if old_value
remove_indexes key, old_value remove_triggers key, old_value
end end
# Avoids corruption in case the application crashes while writing. # Avoids corruption in case the application crashes while writing.
@ -393,7 +396,7 @@ abstract class DODB::Storage(V)
::FileUtils.mv "#{path}.new", path ::FileUtils.mv "#{path}.new", path
end end
write_indexes key, value run_triggers key, value
if key > last_key if key > last_key
self.last_key = key self.last_key = key
@ -413,7 +416,7 @@ abstract class DODB::Storage(V)
rescue File::NotFoundError rescue File::NotFoundError
end end
remove_indexes key, value remove_triggers key, value
value value
end end

View File

@ -37,7 +37,6 @@ end
# #
# WARNING: beware of the RAM use, see `DODB::Storage::Common` for a less memory-hungry option. # WARNING: beware of the RAM use, see `DODB::Storage::Common` for a less memory-hungry option.
class DODB::Storage::Cached(V) < DODB::Storage(V) class DODB::Storage::Cached(V) < DODB::Storage(V)
@indexers = [] of Index(V)
property data = Hash(Int32, V).new property data = Hash(Int32, V).new
def initialize(@directory_name : String) def initialize(@directory_name : String)
@ -81,7 +80,7 @@ class DODB::Storage::Cached(V) < DODB::Storage(V)
# Removes any old indices or partitions pointing to a value about # Removes any old indices or partitions pointing to a value about
# to be replaced. # to be replaced.
if old_value if old_value
remove_indexes key, old_value remove_triggers key, old_value
end end
# Avoids corruption in case the application crashes while writing. # Avoids corruption in case the application crashes while writing.
@ -90,7 +89,7 @@ class DODB::Storage::Cached(V) < DODB::Storage(V)
::FileUtils.mv "#{path}.new", path ::FileUtils.mv "#{path}.new", path
end end
write_indexes key, value run_triggers key, value
if key > last_key if key > last_key
self.last_key = key self.last_key = key
@ -137,7 +136,7 @@ class DODB::Storage::Cached(V) < DODB::Storage(V)
rescue File::NotFoundError rescue File::NotFoundError
end end
remove_indexes key, value remove_triggers key, value
@data.delete key @data.delete key
value value

View File

@ -2,7 +2,7 @@
# #
# This database implementation enables the use of DODB to store data with the same lifetime as the application. # This database implementation enables the use of DODB to store data with the same lifetime as the application.
# #
# Indexing (basic indexes, partitions, tags) will behave the same way. # Triggers (basic indexes, partitions, tags) will behave the same way.
# ``` # ```
# # Creates a DODB RAM-only database (yes, the path is still required). # # Creates a DODB RAM-only database (yes, the path is still required).
# car_database = DODB::Storage::RAMOnly.new "/path/to/db" # car_database = DODB::Storage::RAMOnly.new "/path/to/db"
@ -23,7 +23,7 @@
# ``` # ```
class DODB::Storage::RAMOnly(V) < DODB::Storage::Cached(V) class DODB::Storage::RAMOnly(V) < DODB::Storage::Cached(V)
# Initialization still uses a directory name and creates a few paths. # Initialization still uses a directory name and creates a few paths.
# This is an implementation detail to re-use code of `DODB::Storage` and to get the indexers to work. # This is an implementation detail to re-use code of `DODB::Storage` and to get the triggers to work.
def initialize(@directory_name : String) def initialize(@directory_name : String)
Dir.mkdir_p data_path Dir.mkdir_p data_path
Dir.mkdir_p locks_directory Dir.mkdir_p locks_directory
@ -49,10 +49,10 @@ class DODB::Storage::RAMOnly(V) < DODB::Storage::Cached(V)
# Removes any old indices or partitions pointing to a value about to be replaced. # Removes any old indices or partitions pointing to a value about to be replaced.
if old_value if old_value
remove_indexes key, old_value remove_triggers key, old_value
end end
write_indexes key, value run_triggers key, value
if key > last_key if key > last_key
self.last_key = key self.last_key = key
@ -66,7 +66,7 @@ class DODB::Storage::RAMOnly(V) < DODB::Storage::Cached(V)
return if value.nil? return if value.nil?
remove_indexes key, value remove_triggers key, value
@data.delete key @data.delete key
value value

View File

@ -1,6 +1,6 @@
# Abstract class `DODB::Index(V)` represents the specifications for # Abstract class `DODB::Trigger(V)` represents the specifications for
# the indexes (basic indexes, partitions, tags, etc.). # triggers (indexes, partitions, tags, etc.).
abstract class DODB::Index(V) abstract class DODB::Trigger(V)
# Indexes a value, used for **internal operations**. # Indexes a value, used for **internal operations**.
# #
@ -27,14 +27,14 @@ abstract class DODB::Index(V)
# Directory where the values will be written. # Directory where the values will be written.
# #
# NOTE: used for internal operations. # NOTE: used for internal operations.
abstract def indexing_directory : String abstract def trigger_directory : String
# Removes all the index entries, removes the `#indexing_directory` by default. # Removes all the index entries, removes the `#trigger_directory` by default.
# #
# NOTE: used for internal operations. # NOTE: used for internal operations.
def nuke_index def nuke_trigger
FileUtils.rm_rf indexing_directory FileUtils.rm_rf trigger_directory
end end
end end
require "./index/*" require "./trigger/*"

View File

@ -3,17 +3,17 @@ require "json"
# WARNING: this code hasn't been reviewed nor used in years. # WARNING: this code hasn't been reviewed nor used in years.
class DODB::Index::DirectedGraph(V) < DODB::Index(V) class DODB::Trigger::DirectedGraph(V) < DODB::Trigger(V)
property name : String property name : String
property key_proc : Proc(V, Array(String)) property key_proc : Proc(V, Array(String))
getter storage_root : String getter storage_root : String
getter index : Index(V) getter index : Trigger::Index(V)
@storage : DODB::Storage(V) @storage : DODB::Storage(V)
def initialize(@storage, @storage_root, @index, @name, @key_proc) def initialize(@storage, @storage_root, @index, @name, @key_proc)
::Dir.mkdir_p indexing_directory ::Dir.mkdir_p trigger_directory
end end
def check!(key, value, old_value) def check!(key, value, old_value)
@ -126,7 +126,7 @@ class DODB::Index::DirectedGraph(V) < DODB::Index(V)
r_value r_value
end end
def indexing_directory : String def trigger_directory : String
"#{@storage_root}/graphs/by_#{@name}" "#{@storage_root}/graphs/by_#{@name}"
end end
@ -137,16 +137,16 @@ class DODB::Index::DirectedGraph(V) < DODB::Index(V)
.to_i .to_i
end end
private def indexing_directory(node) private def trigger_directory(node)
"#{indexing_directory}/#{node}" "#{trigger_directory}/#{node}"
end end
private def get_node_symlink(node : String, key : String) private def get_node_symlink(node : String, key : String)
"#{indexing_directory node}/#{key}.json" "#{trigger_directory node}/#{key}.json"
end end
private def get_outgoing_links_directory(node) private def get_outgoing_links_directory(node)
"#{indexing_directory node}/outgoing" "#{trigger_directory node}/outgoing"
end end
private def get_outgoing_symlink(node, link) private def get_outgoing_symlink(node, link)
@ -154,7 +154,7 @@ class DODB::Index::DirectedGraph(V) < DODB::Index(V)
end end
private def get_incoming_links_directory(node) private def get_incoming_links_directory(node)
"#{indexing_directory node}/incoming" "#{trigger_directory node}/incoming"
end end
private def get_incoming_symlink(node, link) private def get_incoming_symlink(node, link)
@ -165,7 +165,7 @@ class DODB::Index::DirectedGraph(V) < DODB::Index(V)
"../../../../data/#{key}.json" "../../../../data/#{key}.json"
end end
# Roughly matches Index#file_path_index, but works if @storage_root # Roughly matches `Trigger#file_path_index`, but works if @storage_root
# is an absolute path as well. # is an absolute path as well.
private def get_cross_index_data_symlink(node : String) private def get_cross_index_data_symlink(node : String)
"../../../../indices/by_#{@index.name}/#{node}.json" "../../../../indices/by_#{@index.name}/#{node}.json"

View File

@ -25,9 +25,9 @@ require "file_utils"
# ``` # ```
# #
# NOTE: no cache, thus considered as *slow* for creation, deletion **and retrieval**. # NOTE: no cache, thus considered as *slow* for creation, deletion **and retrieval**.
# NOTE: see `BasicCached` for a cached version, faster for retrieval. # NOTE: see `IndexCached` for a cached version, faster for retrieval.
# NOTE: for fast operations without fs representation, see `BasicRAMOnly`. # NOTE: for fast operations without fs representation, see `IndexRAMOnly`.
class DODB::Index::Basic(V) < DODB::Index(V) class DODB::Trigger::Index(V) < DODB::Trigger(V)
# Name of the index, such as *id* or *color* for example. # Name of the index, such as *id* or *color* for example.
# This is an arbitrary value, mostly to create the index directory. # This is an arbitrary value, mostly to create the index directory.
# #
@ -49,7 +49,7 @@ class DODB::Index::Basic(V) < DODB::Index(V)
# #
# WARNING: this is an internal operation, do not instanciate an index by hand. # WARNING: this is an internal operation, do not instanciate an index by hand.
def initialize(@storage : DODB::Storage(V), @storage_root : String, @name : String, @key_proc : Proc(V, String | NoIndex)) def initialize(@storage : DODB::Storage(V), @storage_root : String, @name : String, @key_proc : Proc(V, String | NoIndex))
Dir.mkdir_p indexing_directory Dir.mkdir_p trigger_directory
end end
def check!(key : String, value : V, old_value : V?) def check!(key : String, value : V, old_value : V?)
@ -263,13 +263,13 @@ class DODB::Index::Basic(V) < DODB::Index(V)
end end
# :inherit: # :inherit:
def indexing_directory : String def trigger_directory : String
"#{@storage_root}/indices/by_#{@name}" "#{@storage_root}/indices/by_#{@name}"
end end
# FIXME: Now that its being used outside of this class, name it properly. # FIXME: Now that its being used outside of this class, name it properly.
def file_path_index(index_key : String) def file_path_index(index_key : String)
"#{indexing_directory}/#{index_key}" "#{trigger_directory}/#{index_key}"
end end
# Creates the relative path to the data from the indexing directory. # Creates the relative path to the data from the indexing directory.
@ -306,9 +306,9 @@ end
# #
# NOTE: cached, reasonable amount of memory used since it's just an index. # NOTE: cached, reasonable amount of memory used since it's just an index.
# NOTE: fast for retrieval, slow for index creation and deletion (fs operations). # NOTE: fast for retrieval, slow for index creation and deletion (fs operations).
# NOTE: see `DODB::Index::Basic` for an uncached version, even less memory-hungry. # NOTE: see `DODB::Trigger::Index` for an uncached version, even less memory-hungry.
# NOTE: for fast operations without fs representation, see `BasicRAMOnly`. # NOTE: for fast operations without fs representation, see `IndexRAMOnly`.
class DODB::Index::BasicCached(V) < DODB::Index::Basic(V) class DODB::Trigger::IndexCached(V) < DODB::Trigger::Index(V)
# This hash contains the relation between the index key and the data key, used for # This hash contains the relation between the index key and the data key, used for
# **internal operations**. # **internal operations**.
# #
@ -331,13 +331,13 @@ class DODB::Index::BasicCached(V) < DODB::Index::Basic(V)
end end
end end
# Clears the cache and removes the `#indexing_directory`. # Clears the cache and removes the `#trigger_directory`.
def nuke_index def nuke_trigger
super super
data.clear data.clear
end end
# Indexes the value on the file-system as `DODB::Index::Basic#index` but also puts the index in a cache. # Indexes the value on the file-system as `DODB::Trigger::Index#index` but also puts the index in a cache.
# #
# NOTE: used for internal operations. # NOTE: used for internal operations.
def index(key, value) def index(key, value)
@ -348,7 +348,7 @@ class DODB::Index::BasicCached(V) < DODB::Index::Basic(V)
@data[index_key] = key.to_i @data[index_key] = key.to_i
end end
# Removes the index of a value on the file-system as `DODB::Index::Basic#deindex` but also from # Removes the index of a value on the file-system as `DODB::Trigger::Index#deindex` but also from
# the cache, used for **internal operations**. # the cache, used for **internal operations**.
# #
# NOTE: used for internal operations. # NOTE: used for internal operations.
@ -384,13 +384,13 @@ end
# ``` # ```
# #
# Since there is no file-system operations, all the operations are fast. # Since there is no file-system operations, all the operations are fast.
# `DODB::Index::BasicRAMOnly` enables the flexibility of indexes without a file-system representation # `DODB::Trigger::IndexRAMOnly` enables the flexibility of indexes without a file-system representation
# for absolute efficiency. # for absolute efficiency.
# Exactly as easy to use as the other index implementations. # Exactly as easy to use as the other index implementations.
# #
# NOTE: reasonable amount of memory used since it's just an index. # NOTE: reasonable amount of memory used since it's just an index.
# NOTE: fast for all operations, but no file-system representation. # NOTE: fast for all operations, but no file-system representation.
class DODB::Index::BasicRAMOnly(V) < DODB::Index::BasicCached(V) class DODB::Trigger::IndexRAMOnly(V) < DODB::Trigger::IndexCached(V)
# Indexes a value in RAM, no file-system operation. # Indexes a value in RAM, no file-system operation.
# #
# NOTE: used for internal operations. # NOTE: used for internal operations.
@ -422,7 +422,7 @@ class DODB::Index::BasicRAMOnly(V) < DODB::Index::BasicCached(V)
end end
# Clears the index. # Clears the index.
def nuke_index def nuke_trigger
data.clear data.clear
end end
end end

View File

@ -30,7 +30,7 @@ require "file_utils"
# NOTE: no cache, thus considered as *slow* for creation, deletion **and retrieval**. # NOTE: no cache, thus considered as *slow* for creation, deletion **and retrieval**.
# NOTE: see `PartitionCached` for a cached version, faster for retrieval. # NOTE: see `PartitionCached` for a cached version, faster for retrieval.
# NOTE: for fast operations without fs representation, see `PartitionRAMOnly`. # NOTE: for fast operations without fs representation, see `PartitionRAMOnly`.
class DODB::Index::Partition(V) < DODB::Index(V) class DODB::Trigger::Partition(V) < DODB::Trigger(V)
# Name of the index, such as *color* for example. # Name of the index, such as *color* for example.
# This is an arbitrary value, mostly to create the index directory. # This is an arbitrary value, mostly to create the index directory.
# #
@ -52,7 +52,7 @@ class DODB::Index::Partition(V) < DODB::Index(V)
# #
# WARNING: this is an internal operation, do not instanciate a partition by hand. # WARNING: this is an internal operation, do not instanciate a partition by hand.
def initialize(@storage : DODB::Storage(V), @storage_root : String, @name : String, @key_proc : Proc(V, String | NoIndex)) def initialize(@storage : DODB::Storage(V), @storage_root : String, @name : String, @key_proc : Proc(V, String | NoIndex))
::Dir.mkdir_p indexing_directory ::Dir.mkdir_p trigger_directory
end end
# Checks for collisions. # Checks for collisions.
@ -122,7 +122,7 @@ class DODB::Index::Partition(V) < DODB::Index(V)
# ``` # ```
# WARNING: throws a MissingEntry exception on non-existing partition. # WARNING: throws a MissingEntry exception on non-existing partition.
def get_with_keys(partition : String) : Array(Tuple(V, Int32)) def get_with_keys(partition : String) : Array(Tuple(V, Int32))
partition_directory = indexing_directory partition partition_directory = trigger_directory partition
raise MissingEntry.new(@name, partition) unless Dir.exists? partition_directory raise MissingEntry.new(@name, partition) unless Dir.exists? partition_directory
r_value = Array(Tuple(V, Int32)).new r_value = Array(Tuple(V, Int32)).new
@ -171,7 +171,7 @@ class DODB::Index::Partition(V) < DODB::Index(V)
end end
# :inherit: # :inherit:
def indexing_directory : String def trigger_directory : String
"#{@storage_root}/partitions/by_#{@name}" "#{@storage_root}/partitions/by_#{@name}"
end end
@ -179,12 +179,12 @@ class DODB::Index::Partition(V) < DODB::Index(V)
path.sub(/^.*\//, "").to_i path.sub(/^.*\//, "").to_i
end end
private def indexing_directory(partition) private def trigger_directory(partition)
"#{indexing_directory}/#{partition}" "#{trigger_directory}/#{partition}"
end end
private def get_partition_symlink(partition : String, key : String) private def get_partition_symlink(partition : String, key : String)
"#{indexing_directory partition}/#{key}" "#{trigger_directory partition}/#{key}"
end end
private def get_data_symlink(key : String) private def get_data_symlink(key : String)
@ -223,14 +223,14 @@ end
# NOTE: fast for retrieval, slow for index creation and deletion (fs operations). # NOTE: fast for retrieval, slow for index creation and deletion (fs operations).
# NOTE: see `Partition` for an uncached version, even less memory-hungry. # NOTE: see `Partition` for an uncached version, even less memory-hungry.
# NOTE: for fast operations without fs representation, see `PartitionRAMOnly`. # NOTE: for fast operations without fs representation, see `PartitionRAMOnly`.
class DODB::Index::PartitionCached(V) < DODB::Index::Partition(V) class DODB::Trigger::PartitionCached(V) < DODB::Trigger::Partition(V)
# This hash contains the relation between the index key and the data key, used for # This hash contains the relation between the index key and the data key, used for
# **internal operations**. # **internal operations**.
# #
# WARNING: used for internal operations, do not change its content or access it directly. # WARNING: used for internal operations, do not change its content or access it directly.
property data = Hash(String, Array(Int32)).new property data = Hash(String, Array(Int32)).new
# Indexes the value on the file-system as `DODB::Index::Partition#index` but also puts the index in a cache. # Indexes the value on the file-system as `DODB::Trigger::Partition#index` but also puts the index in a cache.
# #
# NOTE: used for internal operations. # NOTE: used for internal operations.
def index(key : String, value : V) def index(key : String, value : V)
@ -248,7 +248,7 @@ class DODB::Index::PartitionCached(V) < DODB::Index::Partition(V)
@data[partition] = array @data[partition] = array
end end
# Removes the index of a value on the file-system as `DODB::Index::Partition#deindex` but also from # Removes the index of a value on the file-system as `DODB::Trigger::Partition#deindex` but also from
# the cache, used for **internal operations**. # the cache, used for **internal operations**.
# #
# NOTE: used for internal operations. # NOTE: used for internal operations.
@ -264,7 +264,7 @@ class DODB::Index::PartitionCached(V) < DODB::Index::Partition(V)
end end
# Gets partition entries and the database key for each entry. # Gets partition entries and the database key for each entry.
# In `DODB::Index::PartitionCached`, `#get_with_keys(partition : String)` is modified to retrieve data keys from # In `DODB::Trigger::PartitionCached`, `#get_with_keys(partition : String)` is modified to retrieve data keys from
# the index cache. # the index cache.
# In case the data isn't already in the cache, it is retrieved from the file-system. # In case the data isn't already in the cache, it is retrieved from the file-system.
# #
@ -294,8 +294,8 @@ class DODB::Index::PartitionCached(V) < DODB::Index::Partition(V)
r_value r_value
end end
# Clears the cache and removes the `#indexing_directory`. # Clears the cache and removes the `#trigger_directory`.
def nuke_index def nuke_trigger
super super
data.clear data.clear
end end
@ -309,14 +309,14 @@ end
# ``` # ```
# #
# Since there is no file-system operations, all the operations are fast. # Since there is no file-system operations, all the operations are fast.
# `DODB::Index::PartitionRAMOnly` enables the flexibility of partitions without a file-system representation. # `DODB::Trigger::PartitionRAMOnly` enables the flexibility of partitions without a file-system representation.
# Absolute efficiency, exactly as easy to use as the other partition implementations. # Absolute efficiency, exactly as easy to use as the other partition implementations.
# #
# NOTE: reasonable amount of memory used since it's just an index. # NOTE: reasonable amount of memory used since it's just an index.
# NOTE: fast for all operations, but no file-system representation. # NOTE: fast for all operations, but no file-system representation.
# NOTE: see `Partition` for an uncached version, even less memory-hungry. # NOTE: see `Partition` for an uncached version, even less memory-hungry.
# NOTE: for an fs representation but still fast for retrieval, see `PartitionCached`. # NOTE: for an fs representation but still fast for retrieval, see `PartitionCached`.
class DODB::Index::PartitionRAMOnly(V) < DODB::Index::PartitionCached(V) class DODB::Trigger::PartitionRAMOnly(V) < DODB::Trigger::PartitionCached(V)
def index(key : String, value : V) def index(key : String, value : V)
partition = key_proc.call value partition = key_proc.call value
return if partition.is_a? NoIndex return if partition.is_a? NoIndex
@ -366,7 +366,7 @@ class DODB::Index::PartitionRAMOnly(V) < DODB::Index::PartitionCached(V)
end end
# Clears the cache. # Clears the cache.
def nuke_index def nuke_trigger
data.clear data.clear
end end
end end

View File

@ -31,7 +31,7 @@ require "file_utils"
# NOTE: no cache, thus considered as *slow* for creation, deletion **and retrieval**. # NOTE: no cache, thus considered as *slow* for creation, deletion **and retrieval**.
# NOTE: see `TagsCached` for a cached version, faster for retrieval. # NOTE: see `TagsCached` for a cached version, faster for retrieval.
# NOTE: for fast operations without fs representation, see `TagsRAMOnly`. # NOTE: for fast operations without fs representation, see `TagsRAMOnly`.
class DODB::Index::Tags(V) < DODB::Index(V) class DODB::Trigger::Tags(V) < DODB::Trigger(V)
# Name of the index, such as *keywords* for example. # Name of the index, such as *keywords* for example.
# This is an arbitrary value, mostly to create the index directory. # This is an arbitrary value, mostly to create the index directory.
# #
@ -53,7 +53,7 @@ class DODB::Index::Tags(V) < DODB::Index(V)
# #
# WARNING: this is an internal operation, do not instanciate a tag index by hand. # WARNING: this is an internal operation, do not instanciate a tag index by hand.
def initialize(@storage : DODB::Storage(V), @storage_root : String, @name : String, @key_proc : Proc(V, Array(String) | NoIndex)) def initialize(@storage : DODB::Storage(V), @storage_root : String, @name : String, @key_proc : Proc(V, Array(String) | NoIndex))
::Dir.mkdir_p indexing_directory ::Dir.mkdir_p trigger_directory
end end
# Checks for collisions. # Checks for collisions.
@ -103,7 +103,7 @@ class DODB::Index::Tags(V) < DODB::Index(V)
# ``` # ```
# WARNING: throws a MissingEntry exception on non-existing tag. # WARNING: throws a MissingEntry exception on non-existing tag.
def get_with_keys(tag : String) : Array(Tuple(V, Int32)) def get_with_keys(tag : String) : Array(Tuple(V, Int32))
tag_directory = indexing_directory tag tag_directory = trigger_directory tag
raise MissingEntry.new(@name, tag) unless Dir.exists? tag_directory raise MissingEntry.new(@name, tag) unless Dir.exists? tag_directory
r_value = Array(Tuple(V, Int32)).new r_value = Array(Tuple(V, Int32)).new
@ -127,7 +127,7 @@ class DODB::Index::Tags(V) < DODB::Index(V)
# Nothing can beat custom implementations tailored with specific problems in mind, so in case this # Nothing can beat custom implementations tailored with specific problems in mind, so in case this
# algorithm isn't fine for you, feel free to override this function for your specific data-set. # algorithm isn't fine for you, feel free to override this function for your specific data-set.
# #
# NOTE: to seriously boost performance, use `DODB::Index::TagsCached`. # NOTE: to seriously boost performance, use `DODB::Trigger::TagsCached`.
# WARNING: throws a MissingEntry exception on non-existing tag or no match. # WARNING: throws a MissingEntry exception on non-existing tag or no match.
def get_with_keys(keys : Array(String)) : Array(Tuple(V, Int32)) def get_with_keys(keys : Array(String)) : Array(Tuple(V, Int32))
r_value = Array(Tuple(V, Int32)).new r_value = Array(Tuple(V, Int32)).new
@ -217,16 +217,16 @@ class DODB::Index::Tags(V) < DODB::Index(V)
path.sub(/^.*\//, "").to_i path.sub(/^.*\//, "").to_i
end end
def indexing_directory : String def trigger_directory : String
"#{@storage_root}/tags/by_#{@name}" "#{@storage_root}/tags/by_#{@name}"
end end
private def indexing_directory(tag) private def trigger_directory(tag)
"#{indexing_directory}/#{tag}" "#{trigger_directory}/#{tag}"
end end
private def get_tagged_entry_path(tag : String, key : String) private def get_tagged_entry_path(tag : String, key : String)
"#{indexing_directory}/#{tag}/#{key}" "#{trigger_directory}/#{tag}/#{key}"
end end
private def get_data_symlink(key : String) private def get_data_symlink(key : String)
@ -266,7 +266,7 @@ end
# NOTE: fast for retrieval, slow for index creation and deletion (fs operations). # NOTE: fast for retrieval, slow for index creation and deletion (fs operations).
# NOTE: see `Tags` for an uncached version, even less memory-hungry. # NOTE: see `Tags` for an uncached version, even less memory-hungry.
# NOTE: for fast operations without fs representation, see `TagsRAMOnly`. # NOTE: for fast operations without fs representation, see `TagsRAMOnly`.
class DODB::Index::TagsCached(V) < DODB::Index::Tags(V) class DODB::Trigger::TagsCached(V) < DODB::Trigger::Tags(V)
# This hash contains the relation between the index key and the data keys. # This hash contains the relation between the index key and the data keys.
property data = Hash(String, Array(Int32)).new property data = Hash(String, Array(Int32)).new
@ -302,7 +302,7 @@ class DODB::Index::TagsCached(V) < DODB::Index::Tags(V)
end end
end end
# In `DODB::Index::TagsCached`, `#get_with_keys(tag : String)` is modified to retrieve data keys from the index cache. # In `DODB::Trigger::TagsCached`, `#get_with_keys(tag : String)` is modified to retrieve data keys from the index cache.
# In case the data isn't already in the cache, it is retrieved from the file-system. # In case the data isn't already in the cache, it is retrieved from the file-system.
# #
# ``` # ```
@ -331,8 +331,8 @@ class DODB::Index::TagsCached(V) < DODB::Index::Tags(V)
r_value r_value
end end
# Clears the cache and removes the `#indexing_directory`. # Clears the cache and removes the `#trigger_directory`.
def nuke_index def nuke_trigger
super super
data.clear data.clear
end end
@ -346,14 +346,14 @@ end
# ``` # ```
# #
# Since there is no file-system operations, all the operations are fast. # Since there is no file-system operations, all the operations are fast.
# `DODB::Index::TagsRAMOnly` enables the flexibility of tags without a file-system representation. # `DODB::Trigger::TagsRAMOnly` enables the flexibility of tags without a file-system representation.
# Absolute efficiency, exactly as easy to use as the other tag implementations. # Absolute efficiency, exactly as easy to use as the other tag implementations.
# #
# NOTE: reasonable amount of memory used since it's just an index. # NOTE: reasonable amount of memory used since it's just an index.
# NOTE: fast for all operations, but no file-system representation. # NOTE: fast for all operations, but no file-system representation.
# NOTE: see `Tags` for an uncached version, even less memory-hungry. # NOTE: see `Tags` for an uncached version, even less memory-hungry.
# NOTE: for an fs representation but still fast for retrieval, see `TagsCached`. # NOTE: for an fs representation but still fast for retrieval, see `TagsCached`.
class DODB::Index::TagsRAMOnly(V) < DODB::Index::TagsCached(V) class DODB::Trigger::TagsRAMOnly(V) < DODB::Trigger::TagsCached(V)
def index(key : String, value : V) def index(key : String, value : V)
tags = key_proc.call value tags = key_proc.call value
return if tags.is_a? NoIndex return if tags.is_a? NoIndex
@ -407,7 +407,7 @@ class DODB::Index::TagsRAMOnly(V) < DODB::Index::TagsCached(V)
end end
# Clears the cache. # Clears the cache.
def nuke_index def nuke_trigger
data.clear data.clear
end end
end end