dodb.cr/src/dodb/partition.cr

101 lines
2.1 KiB
Crystal
Raw Normal View History

2019-12-11 18:10:09 +01:00
require "file_utils"
2020-11-15 03:07:02 +01:00
require "cbor"
2019-12-11 18:10:09 +01:00
require "./indexer.cr"
class DODB::Partition(V) < DODB::Indexer(V)
2019-12-11 18:10:09 +01:00
property name : String
property key_proc : Proc(V, String)
getter storage_root : String
@storage : DODB::Storage(V)
def initialize(@storage, @storage_root, @name, @key_proc)
2019-12-19 04:22:14 +01:00
::Dir.mkdir_p indexing_directory
2019-12-11 18:10:09 +01:00
end
def check!(key, value, old_value)
return true # Partitions dont have collisions or overloads.
end
def index(key, value)
partition = key_proc.call value
symlink = get_partition_symlink(partition, key)
Dir.mkdir_p ::File.dirname symlink
# FIXME: Should not happen anymore. Should we remove this?
::File.delete symlink if ::File.exists? symlink
::File.symlink get_data_symlink(key), symlink
end
def deindex(key, value)
partition = key_proc.call value
symlink = get_partition_symlink(partition, key)
::File.delete symlink
end
def get(partition)
r_value = Array(V).new
2019-12-19 04:22:14 +01:00
partition_directory = indexing_directory partition
return r_value unless Dir.exists? partition_directory
2019-12-11 18:10:09 +01:00
Dir.each_child partition_directory do |child|
2020-11-15 03:07:02 +01:00
r_value << V.from_cbor ::File.read("#{partition_directory}/#{child}").to_slice
2019-12-11 18:10:09 +01:00
end
r_value
end
2020-04-08 00:35:39 +02:00
def delete(partition)
delete partition, do true end
end
def delete(partition, &matcher)
partition_directory = indexing_directory partition
return unless Dir.exists? partition_directory
Dir.each_child partition_directory do |child|
path = "#{partition_directory}/#{child}"
2020-11-15 03:07:02 +01:00
item = V.from_cbor ::File.read(path).to_slice
if yield item
key = get_key path
@storage.delete key
end
end
end
2019-12-19 04:22:14 +01:00
def indexing_directory : String
2019-12-11 18:10:09 +01:00
"#{@storage_root}/partitions/by_#{@name}"
end
private def get_key(path : String) : Int32
::File.readlink(path)
2020-11-15 03:07:02 +01:00
.sub(/#{DODB.file_extension}$/, "")
.sub(/^.*\//, "")
.to_i
end
2019-12-19 04:22:14 +01:00
private def indexing_directory(partition)
"#{indexing_directory}/#{partition}"
2019-12-11 18:10:09 +01:00
end
private def get_partition_symlink(partition : String, key : String)
2020-11-15 03:07:02 +01:00
"#{indexing_directory partition}/#{key}#{DODB.file_extension}"
2019-12-11 18:10:09 +01:00
end
private def get_data_symlink(key : String)
2020-11-15 03:07:02 +01:00
"../../../data/#{key}#{DODB.file_extension}"
2019-12-11 18:10:09 +01:00
end
end