From c475c4f584f4cbd538e1ed1b26c38de2bb79d397 Mon Sep 17 00:00:00 2001 From: Philippe PITTOLI Date: Thu, 9 May 2024 18:41:20 +0200 Subject: [PATCH] Specs are fixed & reworked for the most part. New benchmarks. --- TODO.md | 5 - spec/benchmark-cars.cr | 212 ++++++++--------------- spec/{benchmark.cr => benchmark-todo.cr} | 0 spec/spec-database.cr | 6 +- spec/test-cars.cr | 55 +++--- 5 files changed, 99 insertions(+), 179 deletions(-) rename spec/{benchmark.cr => benchmark-todo.cr} (100%) diff --git a/TODO.md b/TODO.md index 1b66136..8b6039c 100644 --- a/TODO.md +++ b/TODO.md @@ -1,8 +1,3 @@ -# API - -Cached indexes (index, partition, tags) should be used by default. -Uncached indexes should be an option, through a new function `add_uncached_index` or something. - # Performance Search with some kind of "pagination" system: ask entries with a limit on the number of elements and an offset. diff --git a/spec/benchmark-cars.cr b/spec/benchmark-cars.cr index 988a4fb..3170a47 100644 --- a/spec/benchmark-cars.cr +++ b/spec/benchmark-cars.cr @@ -1,181 +1,109 @@ require "benchmark" require "./benchmark-utilities.cr" +require "./cars.cr" -require "../src/dodb.cr" -require "./test-data.cr" +cars_ram = DODB::RAMOnlySpecDataBase(Car).new +cars_cached = DODB::CachedSpecDataBase(Car).new +cars_semi = DODB::SpecDataBase(Car).new "-semi" +cars_uncached = DODB::SpecDataBase(Car).new -class DODBCachedCars < DODB::CachedDataBase(Car) - property storage_dir : String - def initialize(storage_ext = "", remove_previous_data = true) - @storage_dir = "test-storage-cars-cached#{storage_ext}" - - if remove_previous_data - ::FileUtils.rm_rf storage_dir - end - - super storage_dir - end - - def rm_storage_dir - ::FileUtils.rm_rf @storage_dir - end -end - -class DODBUnCachedCars < DODB::DataBase(Car) - property storage_dir : String - def initialize(storage_ext = "", remove_previous_data = true) - @storage_dir = "test-storage-cars-uncached#{storage_ext}" - - if remove_previous_data - ::FileUtils.rm_rf storage_dir - end - - super storage_dir - end - - def rm_storage_dir - ::FileUtils.rm_rf @storage_dir - end -end - -class DODBSemiCachedCars < DODB::DataBase(Car) - property storage_dir : String - def initialize(storage_ext = "", remove_previous_data = true) - @storage_dir = "test-storage-cars-semi#{storage_ext}" - - if remove_previous_data - ::FileUtils.rm_rf storage_dir - end - - super storage_dir - end - - def rm_storage_dir - ::FileUtils.rm_rf @storage_dir - end -end - -def init_indexes(storage : DODB::Storage) - n = storage.new_index "name", &.name - c = storage.new_partition "color", &.color - k = storage.new_tags "keyword", &.keywords - return n, c, k -end - -def init_uncached_indexes(storage : DODB::Storage) - n = storage.new_uncached_index "name", &.name - c = storage.new_uncached_partition "color", &.color - k = storage.new_uncached_tags "keyword", &.keywords - return n, c, k -end - -def add_cars(storage : DODB::Storage, nb_iterations : Int32) - i = 0 - car1 = Car.new "Corvet", "red", [ "shiny", "impressive", "fast", "elegant" ] - car2 = Car.new "Bullet-GT", "blue", [ "shiny", "fast", "expensive" ] - car3 = Car.new "Deudeuche", "beige", [ "curvy", "sublime" ] - car4 = Car.new "Ford-5", "red", [ "unknown" ] - car5 = Car.new "C-MAX", "gray", [ "spacious", "affordable" ] - - while i < nb_iterations - car1.name = "Corvet-#{i}" - car2.name = "Bullet-GT-#{i}" - car3.name = "Deudeuche-#{i}" - car4.name = "Ford-5-#{i}" - car5.name = "C-MAX-#{i}" - - storage << car1 - storage << car2 - storage << car3 - storage << car4 - storage << car5 - i += 1 - STDOUT.write "\radding value #{i}".to_slice - end - puts "" -end - -cars_cached = DODBCachedCars.new -cars_uncached = DODBUnCachedCars.new -cars_semi = DODBSemiCachedCars.new - -cached_searchby_name, cached_searchby_color, cached_searchby_keywords = init_indexes cars_cached -uncached_searchby_name, uncached_searchby_color, uncached_searchby_keywords = init_uncached_indexes cars_uncached -semi_searchby_name, semi_searchby_color, semi_searchby_keywords = init_indexes cars_semi +ram_searchby_name, ram_searchby_color, ram_searchby_keywords = ram_indexes cars_ram +cached_searchby_name, cached_searchby_color, cached_searchby_keywords = cached_indexes cars_cached +semi_searchby_name, semi_searchby_color, semi_searchby_keywords = cached_indexes cars_semi +uncached_searchby_name, uncached_searchby_color, uncached_searchby_keywords = uncached_indexes cars_uncached +add_cars cars_ram, 1_000 add_cars cars_cached, 1_000 -add_cars cars_uncached, 1_000 add_cars cars_semi, 1_000 +add_cars cars_uncached, 1_000 # Searching for data with an index. +puts "search by index 'Corvet-500': get a single value" Benchmark.ips do |x| - x.report("(cars db) searching a data with an index (with a cache)") do + x.report("(ram db and index) searching a data with an index") do + corvet = ram_searchby_name.get "Corvet-500" + end + + x.report("(cached db and index) searching a data with an index") do corvet = cached_searchby_name.get "Corvet-500" end - x.report("(cars db) searching a data with an index (semi: cache is only on index)") do + x.report("(semi: uncached db but cached index) searching a data with an index") do corvet = semi_searchby_name.get "Corvet-500" end - x.report("(cars db) searching a data with an index (without a cache)") do + x.report("(uncached db and index) searching a data with an index") do corvet = uncached_searchby_name.get "Corvet-500" end end # Searching for data with a partition. +puts "" +puts "search by partition 'red': get #{ram_searchby_color.get("red").size} values" Benchmark.ips do |x| - x.report("(cars db) searching a data with a partition (with a cache)") do - red_cars = cached_searchby_color.get "red" + x.report("(ram db and partition) searching a data with a partition") do + corvet = ram_searchby_color.get "red" end - x.report("(cars db) searching a data with a partition (semi: cache is only on partition)") do - red_cars = semi_searchby_color.get "red" + x.report("(cached db and partition) searching a data with a partition") do + corvet = cached_searchby_color.get "red" end - x.report("(cars db) searching a data with a partition (without a cache)") do - red_cars = uncached_searchby_color.get "red" + x.report("(semi: uncached db but cached partition) searching a data with a partition") do + corvet = semi_searchby_color.get "red" + end + + x.report("(uncached db and partition) searching a data with a partition") do + corvet = uncached_searchby_color.get "red" end end # Searching for data with a tag. +puts "" +puts "search by tag 'spacious': get #{ram_searchby_keywords.get("spacious").size} values" Benchmark.ips do |x| - x.report("(cars db) searching a data with a tag (with a cache)") do - red_cars = cached_searchby_keywords.get "spacious" + x.report("(ram db and tag) searching a data with a tag") do + corvet = ram_searchby_keywords.get "spacious" end - x.report("(cars db) searching a data with a tag (semi: cache is only on tags)") do - red_cars = semi_searchby_keywords.get "spacious" + x.report("(cached db and tag) searching a data with a tag") do + corvet = cached_searchby_keywords.get "spacious" end - x.report("(cars db) searching a data with a tag (without a cache)") do - red_cars = uncached_searchby_keywords.get "spacious" + x.report("(semi: uncached db but cached tag) searching a data with a tag") do + corvet = semi_searchby_keywords.get "spacious" + end + + x.report("(uncached db and tag) searching a data with a tag") do + corvet = uncached_searchby_keywords.get "spacious" end end -cars_cached.rm_storage_dir -cars_uncached.rm_storage_dir +#cars_ram.rm_storage_dir +#cars_cached.rm_storage_dir +#cars_semi.rm_storage_dir +#cars_uncached.rm_storage_dir -cars_cached = DODBCachedCars.new -cars_uncached = DODBUnCachedCars.new - -#init_indexes cars_cached -#init_indexes cars_uncached -cached_searchby_name, cached_searchby_color, cached_searchby_keywords = init_indexes cars_cached -uncached_searchby_name, uncached_searchby_color, uncached_searchby_keywords = init_uncached_indexes cars_uncached - -add_cars cars_cached, 1_000 -add_cars cars_uncached, 1_000 - -nb_run = 1000 - -perform_benchmark_average_verbose "(cached) search db with an index", nb_run, do - cached_searchby_name.get "Corvet-500" -end - -perform_benchmark_average_verbose "(uncached) search db with an index", nb_run, do - uncached_searchby_name.get "Corvet-500" -end - -cars_cached.rm_storage_dir -cars_uncached.rm_storage_dir -cars_semi.rm_storage_dir +#cars_cached = DODB::CachedSpecDataBase(Car).new +#cars_uncached = DODB::SpecDataBase(Car).new +# +##init_indexes cars_cached +##init_indexes cars_uncached +#cached_searchby_name, cached_searchby_color, cached_searchby_keywords = cached_indexes cars_cached +#uncached_searchby_name, uncached_searchby_color, uncached_searchby_keywords = uncached_indexes cars_uncached +# +#add_cars cars_cached, 1_000 +#add_cars cars_uncached, 1_000 +# +#nb_run = 1000 +# +#perform_benchmark_average_verbose "(cached) search db with an index", nb_run, do +# cached_searchby_name.get "Corvet-500" +#end +# +#perform_benchmark_average_verbose "(uncached) search db with an index", nb_run, do +# uncached_searchby_name.get "Corvet-500" +#end +# +#cars_cached.rm_storage_dir +#cars_uncached.rm_storage_dir diff --git a/spec/benchmark.cr b/spec/benchmark-todo.cr similarity index 100% rename from spec/benchmark.cr rename to spec/benchmark-todo.cr diff --git a/spec/spec-database.cr b/spec/spec-database.cr index 6a78f8e..313ca7e 100644 --- a/spec/spec-database.cr +++ b/spec/spec-database.cr @@ -1,7 +1,7 @@ class DODB::SpecDataBase(V) < DODB::DataBase(V) property storage_dir : String def initialize(storage_ext = "", remove_previous_data = true) - @storage_dir = "test-spec-storage#{storage_ext}" + @storage_dir = "specdb-storage-uncached#{storage_ext}" if remove_previous_data ::FileUtils.rm_rf storage_dir @@ -18,7 +18,7 @@ end class DODB::CachedSpecDataBase(V) < DODB::CachedDataBase(V) property storage_dir : String def initialize(storage_ext = "", remove_previous_data = true) - @storage_dir = "test-spec-storage-cached#{storage_ext}" + @storage_dir = "specdb-storage-cached#{storage_ext}" if remove_previous_data ::FileUtils.rm_rf storage_dir @@ -35,7 +35,7 @@ end class DODB::RAMOnlySpecDataBase(V) < DODB::RAMOnlyDataBase(V) property storage_dir : String def initialize(storage_ext = "", remove_previous_data = true) - @storage_dir = "test-spec-storage-ram#{storage_ext}" + @storage_dir = "specdb-storage-ram#{storage_ext}" if remove_previous_data ::FileUtils.rm_rf storage_dir diff --git a/spec/test-cars.cr b/spec/test-cars.cr index 0ed9c43..63c66ee 100644 --- a/spec/test-cars.cr +++ b/spec/test-cars.cr @@ -4,42 +4,39 @@ require "./cars.cr" corvet0 = Car.new "Corvet-0", "red", [ "shiny", "impressive", "fast", "elegant" ] -describe "DODB car" do - describe "behavior of uncached, cached and ram indexes:" do - it "RAM DB - add items, add indexes, search, reindex, search" do +describe "uncached, cached and ram indexes" do + it "RAM DB - add items, add indexes, search, reindex, search" do - cars_ram0 = DODB::RAMOnlySpecDataBase(Car).new "-0" - cars_ram1 = DODB::RAMOnlySpecDataBase(Car).new "-1" - cars_ram2 = DODB::RAMOnlySpecDataBase(Car).new "-2" + cars_ram0 = DODB::RAMOnlySpecDataBase(Car).new "-0" + cars_ram1 = DODB::RAMOnlySpecDataBase(Car).new "-1" + cars_ram2 = DODB::RAMOnlySpecDataBase(Car).new "-2" - add_cars cars_ram0, 1 - add_cars cars_ram1, 1 - add_cars cars_ram2, 1 + add_cars cars_ram0, 1 + add_cars cars_ram1, 1 + add_cars cars_ram2, 1 - uncached_searchby_name, uncached_searchby_color, uncached_searchby_keywords = uncached_indexes cars_ram0 - cached_searchby_name, cached_searchby_color, cached_searchby_keywords = cached_indexes cars_ram1 - ram_searchby_name, ram_searchby_color, ram_searchby_keywords = ram_indexes cars_ram2 + uncached_searchby_name, uncached_searchby_color, uncached_searchby_keywords = uncached_indexes cars_ram0 + cached_searchby_name, cached_searchby_color, cached_searchby_keywords = cached_indexes cars_ram1 + ram_searchby_name, ram_searchby_color, ram_searchby_keywords = ram_indexes cars_ram2 - uncached_searchby_name.get?("Corvet-0").should be_nil - cached_searchby_name.get?("Corvet-0").should be_nil - ram_searchby_name.get?("Corvet-0").should be_nil + uncached_searchby_name.get?("Corvet-0").should be_nil + cached_searchby_name.get?("Corvet-0").should be_nil + ram_searchby_name.get?("Corvet-0").should be_nil - cars_ram0.reindex_everything! - cars_ram1.reindex_everything! - cars_ram2.reindex_everything! + cars_ram0.reindex_everything! + cars_ram1.reindex_everything! + cars_ram2.reindex_everything! - # Cannot get the value since it's not written on disk. - # FIXME: should only retrieve the key with the index, not the actual value. - # So, this should work. - uncached_searchby_name.get?("Corvet-0").should be_nil + # Get the value even if not written on the disk since the index was written on the disk. + # The value is retrieved by the database, the index only reads its key in the database. + uncached_searchby_name.get?("Corvet-0").should eq corvet0 - # Both cached and RAM indexes can retrieve the value since they store the key. - cached_searchby_name.get?("Corvet-0").should eq corvet0 - ram_searchby_name.get?("Corvet-0").should eq corvet0 + # Both cached and RAM indexes can retrieve the value since they store the key. + cached_searchby_name.get?("Corvet-0").should eq corvet0 + ram_searchby_name.get?("Corvet-0").should eq corvet0 - cars_ram0.rm_storage_dir - cars_ram1.rm_storage_dir - cars_ram2.rm_storage_dir - end +# cars_ram0.rm_storage_dir +# cars_ram1.rm_storage_dir +# cars_ram2.rm_storage_dir end end