DEADSOFTWARE

added simple hash table tester
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Mon, 21 Aug 2017 14:49:04 +0000 (17:49 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Mon, 21 Aug 2017 19:29:32 +0000 (22:29 +0300)
src/shared/zhash00.dpr [new file with mode: 0644]

diff --git a/src/shared/zhash00.dpr b/src/shared/zhash00.dpr
new file mode 100644 (file)
index 0000000..f6a321e
--- /dev/null
@@ -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.