FIFO + paper
This commit is contained in:
parent
dc34e5b881
commit
fefc4e9b26
6
Makefile
6
Makefile
@ -5,9 +5,15 @@ Q ?= @
|
|||||||
SHOULD_UPDATE = ./bin/should-update
|
SHOULD_UPDATE = ./bin/should-update
|
||||||
DBDIR=/tmp/tests-on-dodb
|
DBDIR=/tmp/tests-on-dodb
|
||||||
|
|
||||||
|
RESULTS_DIR=results
|
||||||
benchmark-cars:
|
benchmark-cars:
|
||||||
$(Q)crystal build spec/benchmark-cars.cr $(OPTS) --release
|
$(Q)crystal build spec/benchmark-cars.cr $(OPTS) --release
|
||||||
|
|
||||||
|
benchmark-cars-run: benchmark-cars
|
||||||
|
./benchmark-cars search # by default, test search durations
|
||||||
|
./bin/stats.sh $(RESULTS_DIR)
|
||||||
|
./bin/extract-data-benchmark-cars.sh $(RESULTS_DIR)
|
||||||
|
|
||||||
build: benchmark-cars
|
build: benchmark-cars
|
||||||
|
|
||||||
wipe-db:
|
wipe-db:
|
||||||
|
@ -7,8 +7,8 @@ ticks left out from 0 to 350 by 50
|
|||||||
label left "Request duration" unaligned "for a partition (ms)" "(Median)" left 0.8
|
label left "Request duration" unaligned "for a partition (ms)" "(Median)" left 0.8
|
||||||
label bot "Number of cars matching the partition" down 0.1
|
label bot "Number of cars matching the partition" down 0.1
|
||||||
|
|
||||||
obram = obuncache = obcache = obsemi = 0
|
obram = obuncache = obfifo = obcache = obsemi = 0
|
||||||
cbram = cbuncache = cbcache = cbsemi = 0
|
cbram = cbuncache = cbfifo = cbcache = cbsemi = 0
|
||||||
|
|
||||||
legendxleft = 1000
|
legendxleft = 1000
|
||||||
legendxright = 6500
|
legendxright = 6500
|
||||||
@ -23,21 +23,26 @@ copy "../data/partitions.d" thru X
|
|||||||
|
|
||||||
y_scale = 1000000
|
y_scale = 1000000
|
||||||
|
|
||||||
# ram cached semi uncached
|
# ram cached fifo semi uncached
|
||||||
line from cx,$2/y_scale to cx,$4/y_scale
|
line from cx,$2/y_scale to cx,$4/y_scale
|
||||||
line from cx,$5/y_scale to cx,$7/y_scale
|
line from cx,$5/y_scale to cx,$7/y_scale
|
||||||
line from cx,$8/y_scale to cx,$10/y_scale
|
line from cx,$8/y_scale to cx,$10/y_scale
|
||||||
line from cx,$11/y_scale to cx,$13/y_scale
|
line from cx,$11/y_scale to cx,$13/y_scale
|
||||||
|
line from cx,$14/y_scale to cx,$16/y_scale
|
||||||
|
|
||||||
#ty = $3
|
#ty = $3
|
||||||
|
|
||||||
cbram = $3/y_scale
|
cbram = $3/y_scale
|
||||||
cbcache = $6/y_scale
|
cbcache = $6/y_scale
|
||||||
cbsemi = $9/y_scale
|
cbfifo = $9/y_scale
|
||||||
cbuncache = $12/y_scale
|
cbsemi = $12/y_scale
|
||||||
|
cbuncache = $15/y_scale
|
||||||
|
|
||||||
if (obram > 0) then {line from cx,cbram to ox,obram}
|
if (obram > 0) then {line from cx,cbram to ox,obram}
|
||||||
if (obcache > 0) then {line from cx,cbcache to ox,obcache}
|
if (obcache > 0) then {line from cx,cbcache to ox,obcache}
|
||||||
|
.gcolor pink
|
||||||
|
if (obfifo > 0) then {line from cx,cbfifo to ox,obfifo}
|
||||||
|
.gcolor
|
||||||
.gcolor blue
|
.gcolor blue
|
||||||
if (obsemi > 0) then {line from cx,cbsemi to ox,obsemi}
|
if (obsemi > 0) then {line from cx,cbsemi to ox,obsemi}
|
||||||
.gcolor
|
.gcolor
|
||||||
@ -47,15 +52,19 @@ copy "../data/partitions.d" thru X
|
|||||||
|
|
||||||
obram = cbram
|
obram = cbram
|
||||||
obcache = cbcache
|
obcache = cbcache
|
||||||
|
obfifo = cbfifo
|
||||||
obsemi = cbsemi
|
obsemi = cbsemi
|
||||||
obuncache = cbuncache
|
obuncache = cbuncache
|
||||||
ox = cx
|
ox = cx
|
||||||
|
|
||||||
# ram cached semi uncached
|
# ram cached fifo semi uncached
|
||||||
.gcolor red
|
.gcolor red
|
||||||
bullet at cx,cbram
|
bullet at cx,cbram
|
||||||
.gcolor
|
.gcolor
|
||||||
bullet at cx,cbcache
|
bullet at cx,cbcache
|
||||||
|
.gcolor pink
|
||||||
|
bullet at cx,cbfifo
|
||||||
|
.gcolor
|
||||||
.gcolor blue
|
.gcolor blue
|
||||||
bullet at cx,cbsemi
|
bullet at cx,cbsemi
|
||||||
.gcolor
|
.gcolor
|
||||||
|
@ -6,8 +6,8 @@ ticks left out from 0 to 170 by 20
|
|||||||
label left "Request duration" unaligned "for a tag (ms)" "(Median)" left 0.8
|
label left "Request duration" unaligned "for a tag (ms)" "(Median)" left 0.8
|
||||||
label bot "Number of cars matching the tag" down 0.1
|
label bot "Number of cars matching the tag" down 0.1
|
||||||
|
|
||||||
obram = obuncache = obcache = obsemi = 0
|
obram = obuncache = obfifo = obcache = obsemi = 0
|
||||||
cbram = cbuncache = cbcache = cbsemi = 0
|
cbram = cbuncache = cbfifo = cbcache = cbsemi = 0
|
||||||
|
|
||||||
legendxleft = 200
|
legendxleft = 200
|
||||||
legendxright = 3000
|
legendxright = 3000
|
||||||
@ -22,21 +22,26 @@ copy "../data/tags.d" thru X
|
|||||||
|
|
||||||
y_scale = 1000000
|
y_scale = 1000000
|
||||||
|
|
||||||
# ram cached semi uncached
|
# ram cached fifo semi uncached
|
||||||
line from cx,$2/y_scale to cx,$4/y_scale
|
line from cx,$2/y_scale to cx,$4/y_scale
|
||||||
line from cx,$5/y_scale to cx,$7/y_scale
|
line from cx,$5/y_scale to cx,$7/y_scale
|
||||||
line from cx,$8/y_scale to cx,$10/y_scale
|
line from cx,$8/y_scale to cx,$10/y_scale
|
||||||
line from cx,$11/y_scale to cx,$13/y_scale
|
line from cx,$11/y_scale to cx,$13/y_scale
|
||||||
|
line from cx,$14/y_scale to cx,$16/y_scale
|
||||||
|
|
||||||
#ty = $3
|
#ty = $3
|
||||||
|
|
||||||
cbram = $3/y_scale
|
cbram = $3/y_scale
|
||||||
cbcache = $6/y_scale
|
cbcache = $6/y_scale
|
||||||
cbsemi = $9/y_scale
|
cbfifo = $9/y_scale
|
||||||
cbuncache = $12/y_scale
|
cbsemi = $12/y_scale
|
||||||
|
cbuncache = $15/y_scale
|
||||||
|
|
||||||
if (obram > 0) then {line from cx,cbram to ox,obram}
|
if (obram > 0) then {line from cx,cbram to ox,obram}
|
||||||
if (obcache > 0) then {line from cx,cbcache to ox,obcache}
|
if (obcache > 0) then {line from cx,cbcache to ox,obcache}
|
||||||
|
.gcolor pink
|
||||||
|
if (obfifo > 0) then {line from cx,cbfifo to ox,obfifo}
|
||||||
|
.gcolor
|
||||||
.gcolor blue
|
.gcolor blue
|
||||||
if (obsemi > 0) then {line from cx,cbsemi to ox,obsemi}
|
if (obsemi > 0) then {line from cx,cbsemi to ox,obsemi}
|
||||||
.gcolor
|
.gcolor
|
||||||
@ -46,15 +51,19 @@ copy "../data/tags.d" thru X
|
|||||||
|
|
||||||
obram = cbram
|
obram = cbram
|
||||||
obcache = cbcache
|
obcache = cbcache
|
||||||
|
obfifo = cbfifo
|
||||||
obsemi = cbsemi
|
obsemi = cbsemi
|
||||||
obuncache = cbuncache
|
obuncache = cbuncache
|
||||||
ox = cx
|
ox = cx
|
||||||
|
|
||||||
# ram cached semi uncached
|
# ram cached fifo semi uncached
|
||||||
.gcolor red
|
.gcolor red
|
||||||
bullet at cx,cbram
|
bullet at cx,cbram
|
||||||
.gcolor
|
.gcolor
|
||||||
bullet at cx,cbcache
|
bullet at cx,cbcache
|
||||||
|
.gcolor pink
|
||||||
|
bullet at cx,cbfifo
|
||||||
|
.gcolor
|
||||||
.gcolor blue
|
.gcolor blue
|
||||||
bullet at cx,cbsemi
|
bullet at cx,cbsemi
|
||||||
.gcolor
|
.gcolor
|
||||||
|
@ -19,7 +19,7 @@ define legend {
|
|||||||
diffx = xright - xleft
|
diffx = xright - xleft
|
||||||
diffy = yup - ydown
|
diffy = yup - ydown
|
||||||
|
|
||||||
hdiff = diffy/4.3
|
hdiff = diffy/5.7
|
||||||
cy = yup - (diffy/6)
|
cy = yup - (diffy/6)
|
||||||
cx = (diffx/20) + xleft
|
cx = (diffx/20) + xleft
|
||||||
|
|
||||||
@ -27,6 +27,7 @@ define legend {
|
|||||||
lendx = cx + diffx/8
|
lendx = cx + diffx/8
|
||||||
tstartx = lendx + diffx/20
|
tstartx = lendx + diffx/20
|
||||||
|
|
||||||
|
.ps -2
|
||||||
.gcolor red
|
.gcolor red
|
||||||
line from lstartx,cy to lendx,cy
|
line from lstartx,cy to lendx,cy
|
||||||
.gcolor
|
.gcolor
|
||||||
@ -35,6 +36,11 @@ define legend {
|
|||||||
line from lstartx,cy to lendx,cy
|
line from lstartx,cy to lendx,cy
|
||||||
"Cached db and index" ljust at tstartx,cy
|
"Cached db and index" ljust at tstartx,cy
|
||||||
cy = cy - hdiff
|
cy = cy - hdiff
|
||||||
|
.gcolor pink
|
||||||
|
line from lstartx,cy to lendx,cy
|
||||||
|
.gcolor
|
||||||
|
"FIFO db and cached index" ljust at tstartx,cy
|
||||||
|
cy = cy - hdiff
|
||||||
.gcolor blue
|
.gcolor blue
|
||||||
line from lstartx,cy to lendx,cy
|
line from lstartx,cy to lendx,cy
|
||||||
.gcolor
|
.gcolor
|
||||||
@ -44,4 +50,5 @@ define legend {
|
|||||||
line from lstartx,cy to lendx,cy
|
line from lstartx,cy to lendx,cy
|
||||||
.gcolor
|
.gcolor
|
||||||
"Uncached db and index" ljust at tstartx,cy
|
"Uncached db and index" ljust at tstartx,cy
|
||||||
|
.ps +2
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,6 @@ require "./db-cars.cr"
|
|||||||
# ENV["NBRUN"] rescue 100
|
# ENV["NBRUN"] rescue 100
|
||||||
# ENV["MAXINDEXES"] rescue 5_000
|
# ENV["MAXINDEXES"] rescue 5_000
|
||||||
|
|
||||||
class DODB::Storage(V)
|
|
||||||
def empty_db
|
|
||||||
while pop
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Context
|
class Context
|
||||||
class_property report_dir = "results"
|
class_property report_dir = "results"
|
||||||
class_property max_indexes = 5_000
|
class_property max_indexes = 5_000
|
||||||
@ -85,10 +78,36 @@ def prepare_env(storage, name, s_index, s_partition, s_tags, &)
|
|||||||
long_operation "removing #{name} data" { storage.rm_storage_dir }
|
long_operation "removing #{name} data" { storage.rm_storage_dir }
|
||||||
end
|
end
|
||||||
|
|
||||||
def batch()
|
def search_benchmark(storage : DODB::Storage(Car),
|
||||||
|
current_db_size : Int32,
|
||||||
|
name : String,
|
||||||
|
search_name : DODB::Index::Basic(Car),
|
||||||
|
search_color : DODB::Index::Partition(Car),
|
||||||
|
search_keywords : DODB::Index::Tags(Car))
|
||||||
|
name_to_search = ENV["CARNAME"] rescue "Corvet-#{(current_db_size/2).to_i}"
|
||||||
|
color_to_search = ENV["CARCOLOR"] rescue "red"
|
||||||
|
keyword_to_search = ENV["CARKEYWORD"] rescue "spacious"
|
||||||
|
puts "NEW BATCH: db-size #{current_db_size}, name: '#{name_to_search}', color: '#{color_to_search}', tag: '#{keyword_to_search}'"
|
||||||
|
report(storage, "#{name}_#{current_db_size}_index") do
|
||||||
|
corvet = search_name.get name_to_search
|
||||||
|
end
|
||||||
|
if current_db_size <= Context.max_indexes
|
||||||
|
report(storage, "#{name}_#{current_db_size}_partitions") do
|
||||||
|
corvet = search_color.get? color_to_search
|
||||||
|
end
|
||||||
|
report(storage, "#{name}_#{current_db_size}_tags") do
|
||||||
|
corvet = search_keywords.get? keyword_to_search
|
||||||
|
end
|
||||||
|
else
|
||||||
|
fake_report("#{name}_#{current_db_size}_partitions")
|
||||||
|
fake_report("#{name}_#{current_db_size}_tags")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def bench_searches()
|
||||||
cars_ram = SPECDB::RAMOnly(Car).new
|
cars_ram = SPECDB::RAMOnly(Car).new
|
||||||
cars_cached = SPECDB::Cached(Car).new
|
cars_cached = SPECDB::Cached(Car).new
|
||||||
cars_fifo = DODB::FIFOSpecDataBase(Car).new
|
cars_fifo = SPECDB::FIFO(Car).new "", 5000 # With only 5_000 entries
|
||||||
cars_semi = SPECDB::Uncached(Car).new "-semi"
|
cars_semi = SPECDB::Uncached(Car).new "-semi"
|
||||||
cars_uncached = SPECDB::Uncached(Car).new
|
cars_uncached = SPECDB::Uncached(Car).new
|
||||||
|
|
||||||
@ -98,32 +117,7 @@ def batch()
|
|||||||
semi_Sby_name, semi_Sby_color, semi_Sby_keywords = cached_indexes cars_semi
|
semi_Sby_name, semi_Sby_color, semi_Sby_keywords = cached_indexes cars_semi
|
||||||
uncached_Sby_name, uncached_Sby_color, uncached_Sby_keywords = uncached_indexes cars_uncached
|
uncached_Sby_name, uncached_Sby_color, uncached_Sby_keywords = uncached_indexes cars_uncached
|
||||||
|
|
||||||
fn = ->(storage : DODB::Storage(Car),
|
fn = ->search_benchmark(DODB::Storage(Car), Int32, String, DODB::Index::Basic(Car), DODB::Index::Partition(Car), DODB::Index::Tags(Car))
|
||||||
current_db_size : Int32,
|
|
||||||
name : String,
|
|
||||||
search_name : DODB::Index::Basic(Car),
|
|
||||||
search_color : DODB::Index::Partition(Car),
|
|
||||||
search_keywords : DODB::Index::Tags(Car)) {
|
|
||||||
|
|
||||||
name_to_search = ENV["CARNAME"] rescue "Corvet-#{(current_db_size/2).to_i}"
|
|
||||||
color_to_search = ENV["CARCOLOR"] rescue "red"
|
|
||||||
keyword_to_search = ENV["CARKEYWORD"] rescue "spacious"
|
|
||||||
puts "NEW BATCH: db-size #{current_db_size}, name: '#{name_to_search}', color: '#{color_to_search}', tag: '#{keyword_to_search}'"
|
|
||||||
report(storage, "#{name}_#{current_db_size}_index") do
|
|
||||||
corvet = search_name.get name_to_search
|
|
||||||
end
|
|
||||||
if current_db_size <= Context.max_indexes
|
|
||||||
report(storage, "#{name}_#{current_db_size}_partitions") do
|
|
||||||
corvet = search_color.get? color_to_search
|
|
||||||
end
|
|
||||||
report(storage, "#{name}_#{current_db_size}_tags") do
|
|
||||||
corvet = search_keywords.get? keyword_to_search
|
|
||||||
end
|
|
||||||
else
|
|
||||||
fake_report("#{name}_#{current_db_size}_partitions")
|
|
||||||
fake_report("#{name}_#{current_db_size}_tags")
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
prepare_env cars_ram, "ram", ram_Sby_name, ram_Sby_color, ram_Sby_keywords, &fn
|
prepare_env cars_ram, "ram", ram_Sby_name, ram_Sby_color, ram_Sby_keywords, &fn
|
||||||
prepare_env cars_cached, "cached", cached_Sby_name, cached_Sby_color, cached_Sby_keywords, &fn
|
prepare_env cars_cached, "cached", cached_Sby_name, cached_Sby_color, cached_Sby_keywords, &fn
|
||||||
@ -143,14 +137,16 @@ def perform_add(storage : DODB::Storage(Car))
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def batch_add()
|
def bench_add()
|
||||||
cars_ram = SPECDB::RAMOnly(Car).new
|
cars_ram = SPECDB::RAMOnly(Car).new
|
||||||
cars_cached = SPECDB::Cached(Car).new
|
cars_cached = SPECDB::Cached(Car).new
|
||||||
|
cars_fifo = SPECDB::FIFO(Car).new "", 5_000
|
||||||
cars_semi = SPECDB::Uncached(Car).new "-semi"
|
cars_semi = SPECDB::Uncached(Car).new "-semi"
|
||||||
cars_uncached = SPECDB::Uncached(Car).new
|
cars_uncached = SPECDB::Uncached(Car).new
|
||||||
|
|
||||||
ram_indexes cars_ram
|
ram_indexes cars_ram
|
||||||
cached_indexes cars_cached
|
cached_indexes cars_cached
|
||||||
|
cached_indexes cars_fifo
|
||||||
cached_indexes cars_semi
|
cached_indexes cars_semi
|
||||||
uncached_indexes cars_uncached
|
uncached_indexes cars_uncached
|
||||||
|
|
||||||
@ -160,6 +156,9 @@ def batch_add()
|
|||||||
avr = perform_add(cars_cached)
|
avr = perform_add(cars_cached)
|
||||||
puts "(cached db and indexes) add a value (average on #{Context.nb_run} tries): #{avr}"
|
puts "(cached db and indexes) add a value (average on #{Context.nb_run} tries): #{avr}"
|
||||||
|
|
||||||
|
avr = perform_add(cars_fifo)
|
||||||
|
puts "(fifo db and cached indexes) add a value (average on #{Context.nb_run} tries): #{avr}"
|
||||||
|
|
||||||
avr = perform_add(cars_semi)
|
avr = perform_add(cars_semi)
|
||||||
puts "(uncached db but cached indexes) add a value (average on #{Context.nb_run} tries): #{avr}"
|
puts "(uncached db but cached indexes) add a value (average on #{Context.nb_run} tries): #{avr}"
|
||||||
|
|
||||||
@ -172,6 +171,22 @@ def batch_add()
|
|||||||
cars_uncached.rm_storage_dir
|
cars_uncached.rm_storage_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def bench_50_shades_of_fifo()
|
||||||
|
cars_fifo1 = SPECDB::FIFO(Car).new "", 1_000
|
||||||
|
cars_fifo5 = SPECDB::FIFO(Car).new "", 5_000
|
||||||
|
cars_fifo10 = SPECDB::FIFO(Car).new "", 10_000
|
||||||
|
|
||||||
|
fifo_Sby_name1, fifo_Sby_color1, fifo_Sby_keywords1 = cached_indexes cars_fifo1
|
||||||
|
fifo_Sby_name5, fifo_Sby_color5, fifo_Sby_keywords5 = cached_indexes cars_fifo5
|
||||||
|
fifo_Sby_name10, fifo_Sby_color10, fifo_Sby_keywords10 = cached_indexes cars_fifo10
|
||||||
|
|
||||||
|
fn = ->search_benchmark(DODB::Storage(Car), Int32, String, DODB::Index::Basic(Car), DODB::Index::Partition(Car), DODB::Index::Tags(Car))
|
||||||
|
|
||||||
|
prepare_env cars_fifo1, "fifo1", fifo_Sby_name1, fifo_Sby_color1, fifo_Sby_keywords1, &fn
|
||||||
|
prepare_env cars_fifo5, "fifo5", fifo_Sby_name5, fifo_Sby_color5, fifo_Sby_keywords5, &fn
|
||||||
|
prepare_env cars_fifo10, "fifo10", fifo_Sby_name10, fifo_Sby_color10, fifo_Sby_keywords10, &fn
|
||||||
|
end
|
||||||
|
|
||||||
ENV["REPORT_DIR"]?.try { |report_dir| Context.report_dir = report_dir }
|
ENV["REPORT_DIR"]?.try { |report_dir| Context.report_dir = report_dir }
|
||||||
Dir.mkdir_p Context.report_dir
|
Dir.mkdir_p Context.report_dir
|
||||||
|
|
||||||
@ -187,5 +202,18 @@ pp! Context.to
|
|||||||
pp! Context.incr
|
pp! Context.incr
|
||||||
pp! Context.max_indexes
|
pp! Context.max_indexes
|
||||||
|
|
||||||
batch
|
if ARGV.size == 0
|
||||||
batch_add
|
puts "Usage: benchmark-cars (fifo|search|add)"
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
case ARGV[0]
|
||||||
|
when /fifo/
|
||||||
|
bench_50_shades_of_fifo
|
||||||
|
when /search/
|
||||||
|
bench_searches
|
||||||
|
when /add/
|
||||||
|
bench_add
|
||||||
|
else
|
||||||
|
puts "Usage: benchmark-cars (fifo|search|add)"
|
||||||
|
end
|
||||||
|
@ -24,10 +24,10 @@ class SPECDB::Cached(V) < DODB::Storage::Cached(V)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class DODB::FIFOSpecDataBase(V) < DODB::Storage::Stacked(V)
|
class SPECDB::FIFO(V) < DODB::Storage::Stacked(V)
|
||||||
property storage_dir : String
|
property storage_dir : String
|
||||||
def initialize(storage_ext = "", remove_previous_data = true)
|
def initialize(storage_ext = "", @max_entries = 100_000, remove_previous_data = true)
|
||||||
@storage_dir = "specdb-storage-fifo#{storage_ext}"
|
@storage_dir = "specdb-storage-fifo-#{@max_entries}#{storage_ext}"
|
||||||
::FileUtils.rm_rf storage_dir if remove_previous_data
|
::FileUtils.rm_rf storage_dir if remove_previous_data
|
||||||
super storage_dir
|
super storage_dir
|
||||||
end
|
end
|
||||||
|
@ -73,7 +73,6 @@ class DODB::Storage::Cached(V) < DODB::Storage(V)
|
|||||||
@data[key] rescue raise MissingEntry.new(key)
|
@data[key] rescue raise MissingEntry.new(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
# :inherit:
|
|
||||||
def []=(key : Int32, value : V)
|
def []=(key : Int32, value : V)
|
||||||
old_value = self.[key]?
|
old_value = self.[key]?
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
# ```
|
# ```
|
||||||
#
|
#
|
||||||
# NOTE: fast for frequently requested data and requires a stable (and configurable) amount of memory.
|
# NOTE: fast for frequently requested data and requires a stable (and configurable) amount of memory.
|
||||||
# TODO: not yet implemented.
|
|
||||||
class DODB::Storage::Stacked(V) < DODB::Storage::Cached(V)
|
class DODB::Storage::Stacked(V) < DODB::Storage::Cached(V)
|
||||||
# The *stack* a simple FIFO instance where the key of the requested data is pushed.
|
# The *stack* a simple FIFO instance where the key of the requested data is pushed.
|
||||||
# In case the number of stored entries exceeds what is allowed, the least recently used entry is removed.
|
# In case the number of stored entries exceeds what is allowed, the least recently used entry is removed.
|
||||||
@ -52,9 +51,35 @@ class DODB::Storage::Stacked(V) < DODB::Storage::Cached(V)
|
|||||||
|
|
||||||
def [](key : Int32) : V
|
def [](key : Int32) : V
|
||||||
val = @data[key] rescue raise MissingEntry.new(key)
|
val = @data[key] rescue raise MissingEntry.new(key)
|
||||||
|
push_fifo key
|
||||||
|
val
|
||||||
|
end
|
||||||
|
|
||||||
|
# Assumes new entries are more requested than old ones.
|
||||||
|
def []=(key : Int32, value : V)
|
||||||
|
super key, value
|
||||||
|
push_fifo key
|
||||||
|
end
|
||||||
|
|
||||||
|
# :inherit:
|
||||||
|
#
|
||||||
|
# Assumes new entries are more requested than old ones.
|
||||||
|
def <<(item : V)
|
||||||
|
key = super item
|
||||||
|
push_fifo key
|
||||||
|
end
|
||||||
|
|
||||||
|
def unsafe_delete(key : Int32)
|
||||||
|
@stack.delete key if super key
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete(key : Int32)
|
||||||
|
@stack.delete key if super key
|
||||||
|
end
|
||||||
|
|
||||||
|
private def push_fifo(key : Int32)
|
||||||
if entry_to_remove = @stack << key
|
if entry_to_remove = @stack << key
|
||||||
@data.delete entry_to_remove
|
@data.delete entry_to_remove
|
||||||
end
|
end
|
||||||
val
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -27,11 +27,16 @@ class FIFO(V)
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Pushes a value in the FIFO and gets the oldest value whether it exceeds the allowed number of entries.
|
# Pushes a value in the FIFO and gets the oldest value whether it exceeds the allowed number of entries.
|
||||||
# NOTE: `#<<(v : V)` is the only function since it's enough for the intended use, feel free to improve this.
|
# NOTE: `#<<(v : V)` is (almost) the only function since it's enough for the intended use, feel free to improve this.
|
||||||
# WARNING: implementation is extremely simple (3 lines) and not designed to be highly efficient.
|
# WARNING: implementation is extremely simple (3 lines) and not designed to be highly efficient.
|
||||||
def <<(v : V) : V?
|
def <<(v : V) : V?
|
||||||
@data.select! { |x| v != v } # remove dups
|
@data.select! { |x| v != v } # remove dups
|
||||||
@data.unshift v # push on top of the stack
|
@data.unshift v # push on top of the stack
|
||||||
@data.pop if @data.size > @max_entries # remove least recently used entry if `@data` is too big
|
@data.pop if @data.size > @max_entries # remove least recently used entry if `@data` is too big
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Removes a value.
|
||||||
|
def delete(v : V)
|
||||||
|
@data.select! { |x| v != v }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user