123 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			Crystal
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			Crystal
		
	
	
	
	
	
| require "spec"
 | |
| require "./db-cars.cr"
 | |
| 
 | |
| # NOTE: the following tests access both database and triggers' caches directly.
 | |
| # It must not be done in real applications.
 | |
| # `data` and `lru` properties are implementation details.
 | |
| 
 | |
| describe "SPECDB::Common" do
 | |
| 	it "basics, 3 values" do
 | |
| 		car0 = Car.new "Corvet-0", "red", [] of String
 | |
| 		car1 = Car.new "Corvet-1", "red", [] of String
 | |
| 		car2 = Car.new "Corvet-2", "red", [] of String
 | |
| 		car3 = Car.new "Corvet-3", "red", [] of String
 | |
| 
 | |
| 		db = SPECDB::Common(Car).new "", 3
 | |
| 
 | |
| 		db.data.keys.sort.should eq([] of Int32)
 | |
| 
 | |
| 		db << car0
 | |
| 		db.data.keys.sort.should eq([0] of Int32)
 | |
| 
 | |
| 		db << car1
 | |
| 		db.data.keys.sort.should eq([0, 1] of Int32)
 | |
| 
 | |
| 		db << car2
 | |
| 		db.data.keys.sort.should eq([0, 1, 2] of Int32)
 | |
| 		db[0] # Let's use the first value, it shouldn't be the one to be dropped.
 | |
| 
 | |
| 		db << car3
 | |
| 		db.data.keys.sort.should eq([0, 2, 3] of Int32)
 | |
| 		db.lru.to_s.should eq "[ 3, 0, 2 ]"
 | |
| 
 | |
| 		db.delete 2
 | |
| 		db.data.keys.sort.should eq([0, 3] of Int32)
 | |
| 		db.lru.to_s.should eq "[ 3, 0 ]"
 | |
| 	end
 | |
| 
 | |
| 	it "add some values, reindex, check the values" do
 | |
| 		car0 = Car.new "Corvet-0", "red", [] of String
 | |
| 		car1 = Car.new "Corvet-1", "red", [] of String
 | |
| 		car2 = Car.new "Corvet-2", "red", [] of String
 | |
| 		car3 = Car.new "Corvet-3", "red", [] of String
 | |
| 
 | |
| 		db = SPECDB::Common(Car).new "reindex", 2
 | |
| 		index_name  = db.new_index     "name",  &.name
 | |
| 		index_color = db.new_partition "color", &.color
 | |
| 
 | |
| 		db.data.keys.sort.should eq([] of Int32)
 | |
| 
 | |
| 		db << car0
 | |
| 		db.data.keys.sort.should eq([0] of Int32)
 | |
| 
 | |
| 		db << car1
 | |
| 		db.data.keys.sort.should eq([0, 1] of Int32)
 | |
| 		db.lru.to_s.should eq "[ 1, 0 ]"
 | |
| 
 | |
| 		db.data.keys.sort.should eq([0, 1] of Int32)
 | |
| 		db.lru.to_s.should eq "[ 1, 0 ]"
 | |
| 
 | |
| 		db << car2
 | |
| 		db.data.keys.sort.should eq([1, 2] of Int32)
 | |
| 		db.lru.to_s.should eq "[ 2, 1 ]"
 | |
| 		db[0] # Let's use the first value, it shouldn't be the one to be dropped.
 | |
| 
 | |
| 		db << car3
 | |
| 		db.data.keys.sort.should eq([0, 3] of Int32)
 | |
| 		db.lru.to_s.should eq "[ 3, 0 ]"
 | |
| 
 | |
| 		# Actually remove the value indexed "2".
 | |
| 		db.delete 2
 | |
| 		# The "delete" action actually puts the value in the cache before removing it.
 | |
| 		db.data.keys.sort.should eq([3] of Int32)
 | |
| 		db.lru.to_s.should eq "[ 3 ]"
 | |
| 
 | |
| 		# db2: further tests for the LRU behavior, with `reindex_everything!` for example.
 | |
| 		db2 = SPECDB::Common(Car).new "reindex", 2, false
 | |
| 		index2_name  = db2.new_index     "name",  &.name
 | |
| 
 | |
| 		# For now, we didn't use any value in the database.
 | |
| 		# Also, triggers should have empty caches.
 | |
| 		db2.data.keys.sort.should eq([] of Int32)
 | |
| 		db2.lru.to_s.should eq "[  ]"
 | |
| 		index2_name.get?("Corvet-0").should eq car0
 | |
| 
 | |
| 		# Reindex removes all triggers (hard rm -rf trigger-dir) then reads all
 | |
| 		# data from the file-system to run the triggers. Data is put into the cache
 | |
| 		# of the `Common` database.
 | |
| 		db2.reindex_everything!
 | |
| 
 | |
| 		# Values 1 and 3 are the last recently used values following `reindex_everything!`.
 | |
| 		db2.data.keys.sort.should eq([1, 3] of Int32)
 | |
| 		db2.lru.to_s.should eq "[ 3, 1 ]"
 | |
| 
 | |
| 		total_values = 0
 | |
| 		db2.each_with_key do |v, k|
 | |
| 			total_values += 1
 | |
| 		end
 | |
| 		total_values.should eq 3
 | |
| 
 | |
| 		# db3: no need for a reindex to access values from the database,
 | |
| 		# with `each` or `each_with_key` for example.
 | |
| 		db3 = SPECDB::Common(Car).new "reindex", 2, false
 | |
| 		total_values = 0
 | |
| 		db3.each do |v|
 | |
| 			total_values += 1
 | |
| 		end
 | |
| 		total_values.should eq 3
 | |
| 
 | |
| 		# db4: no need for a reindex to access values from triggers.
 | |
| 		db4 = SPECDB::Common(Car).new "reindex", 2, false
 | |
| 		index4_name  = db4.new_index     "name",  &.name
 | |
| 		index4_color = db4.new_partition "color", &.color
 | |
| 
 | |
| 		index4_name.data.size.should eq 0 # trigger cache is empty
 | |
| 		index4_name.get?("Corvet-3").should eq car3
 | |
| 		index4_name.data.size.should eq 1 # trigger cache: one value, Corvet-3
 | |
| 
 | |
| 		index4_color.data.size.should eq 0 # trigger cache is empty
 | |
| 		index4_color.get("red").size.should eq 3 # read from the disk
 | |
| 		index4_color.data.size.should eq 1 # trigger cache: 1, the color "red"
 | |
| 		index4_color.data["red"].size.should eq 3 # 3 values in "red"
 | |
| 	end
 | |
| end
 |