From cef650d6d74c89e95fd9718be4373e351e8f9e40 Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Mon, 21 Aug 2017 17:49:04 +0300 Subject: [PATCH] added simple hash table tester --- src/shared/zhash00.dpr | 160 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 src/shared/zhash00.dpr diff --git a/src/shared/zhash00.dpr b/src/shared/zhash00.dpr new file mode 100644 index 0000000..f6a321e --- /dev/null +++ b/src/shared/zhash00.dpr @@ -0,0 +1,160 @@ +{$INCLUDE ../a_modes.inc} +// tests for hash table +{$DEFINE EXCESSIVE_CHECKS} +uses + SysUtils, + hashtbl in '../hashtable.pas'; + +const + MaxItems = 16384; + + +{ +function hequ (constref a, b: Integer): Boolean; begin result := (a = b); end; + +function hhash (constref k: Integer): LongWord; +begin + //result := fnvHash(k, sizeof(k)); + //result := u32Hash(LongWord(k)); + result := joaatHash(k, sizeof(k)); +end; +} + + +var + its: array [0..MaxItems-1] of Integer; + marks: array [0..MaxItems-1] of Boolean; + hash: THashIntInt; + i, v, hv: Integer; + del: Boolean; + +procedure checkHash (dump: Boolean=false); +var + i, v: Integer; + flag: Boolean; + count: Integer = 0; +begin + if dump then writeln('====== CHECK ======'); + for i := 0 to High(its) do + begin + if dump then + begin + v := -1; + flag := hash.get(i, v); + writeln(' check #', i, '; v=', v, '; flag=', flag); + end; + if (its[i] >= 0) then + begin + Inc(count); + if not hash.has(i) then raise Exception.Create('(0.0) fuuuuuuuuuuuu'); + if not hash.get(i, v) then raise Exception.Create('(0.1) fuuuuuuuuuuuu'); + if (v <> its[i]) then raise Exception.Create('(0.2) fuuuuuuuuuuuu'); + end + else + begin + if hash.has(i) then raise Exception.Create('(0.3) fuuuuuuuuuuuu'); + end; + end; + if (count <> hash.count) then raise Exception.Create('(0.4) fuuuuuuuuuuuu'); + if dump then writeln('------'); +end; + + +procedure testIterator (); +var + i, count: Integer; + + function iter (constref k: Integer; constref v: Integer): Boolean; + begin + result := false; // don't stop + //writeln('key=', k, '; value=', v); + if marks[k] then raise Exception.Create('duplicate entry in iterator'); + if (its[k] <> v) then raise Exception.Create('invalid entry in iterator'); + marks[k] := true; + Inc(count); + end; + +begin + count := 0; + for i := 0 to High(marks) do marks[i] := false; + hash.forEach(iter); + if (count <> hash.count) then + begin + writeln('0: count=', count, '; hash.count=', hash.count); + //raise Exception.Create('lost entries in iterator'); + end; + count := 0; + for i := 0 to High(marks) do if marks[i] then Inc(count); + if (count <> hash.count) then + begin + writeln('1: count=', count, '; hash.count=', hash.count); + raise Exception.Create('lost entries in iterator'); + end; +end; + + +var + xcount: Integer; +begin + for i := 0 to High(its) do its[i] := -1; + + //hash := THashInt.Create(hhash, hequ); + hash := hashNewIntInt(); + + Randomize(); + + writeln('testing: insertion'); + xcount := 0; + for i := 0 to MaxItems-1 do + begin + v := Random(MaxItems); + //writeln('i=', i, '; v=', v, '; its[v]=', its[v]); + if (its[v] >= 0) then + begin + if not hash.has(v) then raise Exception.Create('(1.0) fuuuuuuuuuuuu'); + if not hash.get(v, hv) then raise Exception.Create('(1.1) fuuuuuuuuuuuu'); + if (hv <> its[v]) then raise Exception.Create('(1.2) fuuuuuuuuuuuu'); + end + else + begin + its[v] := i; + if hash.put(v, i) then raise Exception.Create('(1.3) fuuuuuuuuuuuu'); + Inc(xcount); + if (xcount <> hash.count) then raise Exception.Create('(1.4) fuuuuuuuuuuuu'); + end; + {$IFDEF EXCESSIVE_CHECKS}checkHash();{$ENDIF} + {$IFDEF EXCESSIVE_CHECKS}testIterator();{$ENDIF} + end; + if (xcount <> hash.count) then raise Exception.Create('(1.4) fuuuuuuuuuuuu'); + checkHash(); + testIterator(); + + writeln('testing: deletion'); + for i := 0 to MaxItems*8 do + begin + v := Random(MaxItems); + //writeln('trying to delete ', v, '; its[v]=', its[v]); + del := hash.del(v); + //writeln(' del=', del); + if del then + begin + if (its[v] < 0) then raise Exception.Create('(2.0) fuuuuuuuuuuuu'); + Dec(xcount); + end + else + begin + if (its[v] >= 0) then raise Exception.Create('(2.1) fuuuuuuuuuuuu'); + end; + its[v] := -1; + if (xcount <> hash.count) then raise Exception.Create('(1.4) fuuuuuuuuuuuu'); + hash.compact(); + if (xcount <> hash.count) then raise Exception.Create('(1.4) fuuuuuuuuuuuu'); + {$IFDEF EXCESSIVE_CHECKS}checkHash();{$ENDIF} + {$IFDEF EXCESSIVE_CHECKS}testIterator();{$ENDIF} + if (hash.count = 0) then break; + end; + + writeln('testing: complete'); + checkHash(); + testIterator(); +end. -- 2.29.2