Hashmap added.
git-svn-id: https://spexeah.com:8443/svn/Asuro@1235 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c
This commit is contained in:
212
src/include/hashmap.pas
Normal file
212
src/include/hashmap.pas
Normal 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.
|
@ -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.
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user