`last_key` is now cached.

toying-with-ramdb
Philippe PITTOLI 2024-05-29 16:47:56 +02:00
parent 02e7e82fa1
commit 814baced05
8 changed files with 58 additions and 40 deletions

View File

@ -20,11 +20,17 @@ legendydown = 220
boite(legendxleft,legendxright,legendyup,legendydown)
legend(legendxleft,legendxright,legendyup,legendydown)
y_scale = 1000000
linear_growth(red, 110, 1000, 10000)
linear_growth(black, 110, 1000, 10000)
linear_growth(pink, 160, 1000, 10000)
linear_growth(blue, 13982, 1000, 10000)
linear_growth(green, 17350, 1000, 10000)
copy "../data/partitions.d" thru X
cx = $1*2
y_scale = 1000000
line_no_mustache(cbram, obram, $3, red)
line_no_mustache(cbcache, obcache, $6, black)
line_no_mustache(cbfifo, obfifo, $9, pink)
@ -52,11 +58,17 @@ label right "\s+2Logarithmic" unaligned "scale\s0"
obram = obuncache = obfifo = obcache = obsemi = 0
cbram = cbuncache = cbfifo = cbcache = cbsemi = 0
y_scale = 1000000
linear_growth(red, 85, 1000, 10000)
linear_growth(black, 85, 1000, 10000)
linear_growth(pink, 160, 1000, 10000)
linear_growth(blue, 13982, 1000, 10000)
linear_growth(green, 17350, 1000, 10000)
copy "../data/partitions.d" thru X
cx = $1*2
y_scale = 1000000
line_no_mustache(cbram, obram, $3, red)
line_no_mustache(cbcache, obcache, $6, black)
line_no_mustache(cbfifo, obfifo, $9, pink)

View File

@ -132,3 +132,14 @@ define line_with_mustache {
line_no_mustache($1,$2,$3,$4)
line from cx,$5/y_scale to cx,$6/y_scale
}
# WARNING: this macro y_scale.
define linear_growth {
# $1 = color
# $2 = duration of the retrieval for a single value
# $3 = min number of retrievals
# $4 = max number of retrievals
.gcolor $1
line dashed from $3,($2*$3)/y_scale to $4,($2*$4)/y_scale
.gcolor
}

View File

@ -993,12 +993,20 @@ Performance is analyzed based the partition size (the number of red cars) and th
.ps \n[PS]
.QP
This figure shows the retrieval of cars based on a partition (their color), with both a linear and a logarithmic scale.
The number of cars retrieved scales from 2000 to 10000.
.QE
In this example, both the linear and the logarithmic scales are represented to better grasp the difference between all databases.
The linear scale shows the linearity of the request time for uncached databases.
Respectively, the logarithmically scaled figure does the same for cached databases,
which are flattened in the linear scale since they all are hundreds of time quicker than the uncached ones.
The duration of a retrieval grows linearly with the number of matched entries.
On both figures, a dashed line is drawn representing a linear growth based on the quickest retrieval observed from basic indexes for each database.
This dashed line and the observed results differ slightly; observed results grow more than what has been calculated.
This difference comes, at least partially, from the additional process of putting all the results in an array (which may also include some memory management) and the accumulated random delays for the retrieval of each value (due to processus scheduling on the machine).
Further analysis of the results may be interesting but are far beyond the scope of this document.
.SS Tags (n to n relations)
.LP
.ps -2

View File

@ -128,7 +128,7 @@ def perform_add(storage : DODB::Storage(Car))
perform_benchmark_average Context.nb_run, do
corvet = corvet0.clone
corvet.name = "Corvet-#{i}"
storage << corvet
storage.unsafe_add corvet
i += 1
end
end

View File

@ -4,6 +4,8 @@ abstract class DODB::Storage(V)
# List of triggers (basic indexes, partitions, tags, etc.).
@triggers = [] of Trigger(V)
property cached_last_key : Int32
# Directory where data and triggers will be written.
property directory_name : String
@ -16,11 +18,7 @@ abstract class DODB::Storage(V)
Dir.mkdir_p data_path
Dir.mkdir_p locks_directory
begin
self.last_key
rescue
self.last_key = -1
end
@cached_last_key = init_last_key
end
# Requests a (named) lock.
@ -53,19 +51,26 @@ abstract class DODB::Storage(V)
"#{@directory_name}/last-key"
end
# Reads the last *key* in the database.
def last_key : Int32
# Reads the last database *key* from the storage device.
def init_last_key : Int32
File.read(key_file).to_i
rescue
-1
end
# Reads the (cached) last key.
def last_key : Int32
@cached_last_key
end
# Changes the last *key* in the database.
def last_key=(x : Int32)
file = File.open(key_file, "w")
file << x.to_s
file.close
@cached_last_key = x
x
rescue
raise Exception.new "could not update last-key file"
@ -104,7 +109,7 @@ abstract class DODB::Storage(V)
# For single-thread applications, use the `#unsafe_add` operation instead.
def <<(item : V)
request_lock "key"
key = last_key + 1
key = init_last_key + 1
self[key] = item
self.last_key = key
@ -398,7 +403,7 @@ abstract class DODB::Storage(V)
run_triggers key, value
if key > last_key
if key > @cached_last_key
self.last_key = key
end
end

View File

@ -43,11 +43,7 @@ class DODB::Storage::Cached(V) < DODB::Storage(V)
Dir.mkdir_p data_path
Dir.mkdir_p locks_directory
begin
self.last_key
rescue
self.last_key = -1
end
@cached_last_key = init_last_key
# Load the database in RAM at start-up.
DODB::Storage::Uncached(V).new(@directory_name).each_with_key do |v, key|
@ -56,11 +52,6 @@ class DODB::Storage::Cached(V) < DODB::Storage(V)
end
end
# Gets data from the hash in RAM.
def []?(key : Int32) : V?
self[key] rescue nil
end
# Gets the data with the *key*.
# In case the data is missing, returns an exception `DODB::MissingEntry`.
#
@ -91,7 +82,7 @@ class DODB::Storage::Cached(V) < DODB::Storage(V)
run_triggers key, value
if key > last_key
if key > @cached_last_key
self.last_key = key
end

View File

@ -43,11 +43,7 @@ class DODB::Storage::Common(V) < DODB::Storage::Cached(V)
Dir.mkdir_p data_path
Dir.mkdir_p locks_directory
begin
self.last_key
rescue
self.last_key = -1
end
@cached_last_key = init_last_key
end
# Verifies that the value is in cache, or read it on disk.

View File

@ -27,17 +27,12 @@ class DODB::Storage::RAMOnly(V) < DODB::Storage::Cached(V)
def initialize(@directory_name : String)
Dir.mkdir_p data_path
Dir.mkdir_p locks_directory
@last_key = -1
end
# The `last_key` function doesn't read a file in the `DODB::Storage::RAMOnly` database.
def last_key
@last_key
@cached_last_key = -1
end
# The `last_key=` function doesn't write to a file in the `DODB::Storage::RAMOnly` database.
def last_key=(key : Int32)
@last_key = key
@cached_last_key = key
end
# WARNING: takes `[]?` and `[]` implementations from `CachedDataBase`.
@ -54,7 +49,7 @@ class DODB::Storage::RAMOnly(V) < DODB::Storage::Cached(V)
run_triggers key, value
if key > last_key
if key > @cached_last_key
self.last_key = key
end