Hashmap added.

git-svn-id: https://spexeah.com:8443/svn/Asuro@1235 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c
This commit is contained in:
kieron
2020-07-15 23:03:32 +00:00
parent 3c5d75e77e
commit a7ee8c6d34
12 changed files with 473 additions and 72 deletions

212
src/include/hashmap.pas Normal file
View File

@ -0,0 +1,212 @@
unit hashmap;
interface
uses
md5, util, strings, lmemorymanager, console;
type
DPHashItem = ^PHashItem;
PHashItem = ^THashItem;
THashItem = record
Next : PHashItem;
Key : pchar;
Data : void;
end;
PHashMap = ^THashMap;
THashMap = record
Size : uint32;
Table : DPHashItem;
end;
function new(size : uint32) : PHashMap;
procedure add(map : PHashMap; key : pchar; value : void);
function get(map : PHashMap; key : pchar) : void;
procedure delete(map : PHashMap; key : pchar);
procedure deleteAndFree(map : PHashMap; key : pchar);
procedure printMap(map : PHashMap);
implementation
function hashIndex(size : uint32; key : pchar) : uint32;
var
KeyLength : uint32;
Hash : PMD5Digest;
Hash128 : puint128;
Hash32 : uint32;
begin
KeyLength:= StringSize(key);
Hash:= MD5Buffer(puint8(key), KeyLength);
Hash128:= puint128(Hash);
Hash32:= MD5To32(Hash128);
hashIndex:= Hash32 mod size;
kfree(void(Hash));
end;
function newItem : PHashItem;
begin
newItem:= PHashItem(kalloc(sizeof(THashItem)));
newItem^.Next:= nil;
newItem^.Key:= nil;
newItem^.Data:= nil;
end;
procedure add(map : PHashMap; key : pchar; value : void);
var
Idx : uint32;
Item : PHashItem;
nItem : PHashItem;
begin
if (map <> nil) and (key <> nil) then begin
Idx:= hashIndex(map^.size, key);
if map^.Table[Idx] = nil then begin
Item:= newItem;
Item^.Next:= nil;
map^.Table[Idx]:= Item;
end else begin
//Collision
Item:= map^.Table[Idx];
while not StringEquals(Item^.key, key) do begin
if Item^.Next <> nil then begin
Item:= Item^.Next;
end else begin
nItem:= newItem();
Item^.Next:= nItem;
Item:= nItem;
Item^.Next:= nil;
break;
end;
end;
end;
if Item^.Key = nil then Item^.Key:= stringCopy(key);
Item^.Data:= value;
end;
end;
function get(map : PHashMap; key : pchar) : void;
var
Idx : uint32;
Item : PHashItem;
begin
get:= nil;
if (map <> nil) and (key <> nil) then begin
Idx:= hashIndex(map^.size, key);
Item:= map^.table[Idx];
if Item = nil then exit;
while not StringEquals(Item^.key, key) do begin
Item:= Item^.Next;
if Item = nil then break;
end;
if Item <> nil then get:= Item^.Data;
end;
end;
function new(size : uint32) : PHashMap;
var
Map : PHashMap;
i : uint32;
begin
Map:= PHashMap(kalloc(sizeof(THashMap)));
Map^.size:= size;
Map^.Table:= DPHashItem(Kalloc(sizeof(PHashItem) * Size));
for i:=0 to size-1 do begin
Map^.Table[i]:= nil;
end;
new:= Map;
end;
procedure deleteAndFree(map : PHashMap; key : pchar);
var
Idx : uint32;
Item : PHashItem;
Prev : PHashItem;
begin
Prev:= nil;
if (map <> nil) and (key <> nil) then begin
Idx:= hashIndex(map^.size, key);
Item:= map^.table[Idx];
while not StringEquals(Item^.key, key) do begin
Prev:= Item;
Item:= Item^.Next;
if Item = nil then break;
end;
if Item <> nil then begin
If Prev <> nil then Prev^.Next:= Item^.Next;
If Prev = nil then begin
if Item^.Next <> nil then
map^.table[Idx]:= Item^.Next
else
map^.table[Idx]:= nil;
end;
kfree(void(Item^.Key));
kfree(void(Item^.Data));
kfree(void(Item));
end;
end;
end;
procedure delete(map : PHashMap; key : pchar);
var
Idx : uint32;
Item : PHashItem;
Prev : PHashItem;
begin
Prev:= nil;
if (map <> nil) and (key <> nil) then begin
Idx:= hashIndex(map^.size, key);
Item:= map^.table[Idx];
while not StringEquals(Item^.key, key) do begin
Prev:= Item;
Item:= Item^.Next;
if Item = nil then break;
end;
if Item <> nil then begin
If Prev <> nil then Prev^.Next:= Item^.Next;
If Prev = nil then begin
if Item^.Next <> nil then
map^.table[Idx]:= Item^.Next
else
map^.table[Idx]:= nil;
end;
kfree(void(Item^.Key));
kfree(void(Item));
end;
end;
end;
procedure printMap(map : PHashMap);
var
i,c : uint32;
item : PHashItem;
begin
for i:=0 to map^.Size-1 do begin
if map^.table[i] <> nil then begin
writestring('Map[');
writeint(i);
writestring(']->(0)="');
writestring(map^.table[i]^.key);
writestring('"');
item:= map^.table[i]^.next;
c:=1;
while item <> nil do begin
writestring('->(');
writeint(c);
writestring(')="');
writestring(item^.key);
writestring('"');
inc(c);
item:= item^.next;
end;
writestringln(' ');
end;
end;
end;
end.

View File

@ -39,6 +39,8 @@ procedure MD5Update(context : PMD5Context; buffer : PuInt8; bufferLen : uInt32);
function MD5Final(context : PMD5Context) : PMD5Digest;
function MD5Buffer(buffer : PuInt8; bufferLen : uInt32) : PMD5Digest;
function MD5To32(Input : PuInt128) : uint32;
implementation
procedure Invert(Source : PuInt8; Dest : PuInt32; Count : uInt32);
@ -234,4 +236,13 @@ begin
kfree(void(context));
end;
function MD5To32(Input : PuInt128) : uint32;
var
MD5To64 : uint64;
i : uint8;
begin
MD5To32:= Input^.DWords[0] xor Input^.DWords[1] xor Input^.DWords[2] xor Input^.DWords[3];
end;
end.

View File

@ -43,7 +43,7 @@ type
vbe_interface_seg : uint16;
vbe_interface_off : uint16;
vbe_interface_len : uint16;
framebuffer_addr : uint64;
framebuffer_addr : uint64;
framebuffer_pitch : uint32;
framebuffer_width : uint32;
framebuffer_height: uint32;

View File

@ -28,6 +28,22 @@ type
uInt16 = WORD;
uInt32 = DWORD;
uInt64 = QWORD;
uint128 = packed record
case Integer of
0: (
Hi : uint64;
Lo : uint64;
);
1: (
DWords : array [0..3] of uint32;
);
2: (
Words : array [0..7] of uint16;
);
3: (
Bytes : array [0..15] of uint8;
);
end;
sInt8 = shortint;
sInt16 = smallint;
@ -42,6 +58,7 @@ type
PuInt16 = ^uInt16;
PuInt32 = ^uInt32;
PuInt64 = ^uInt64;
PuInt128 = ^uint128;
PsInt8 = ^sInt8;
PsInt16 = ^sInt16;