From 984b6a89c8eb49b85a892890059c368320396187 Mon Sep 17 00:00:00 2001 From: kieron Date: Fri, 17 Jul 2020 22:29:27 +0000 Subject: [PATCH] Hashmaps now autoexpand based on loadFactor. git-svn-id: https://spexeah.com:8443/svn/Asuro@1298 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c --- src/console.pas | 1 + src/cpu.pas | 16 +++++ src/include/hashmap.pas | 141 +++++++++++++++++++++++++--------------- src/kernel.pas | 5 +- src/stub/stub.asm | 2 +- 5 files changed, 111 insertions(+), 54 deletions(-) diff --git a/src/console.pas b/src/console.pas index cb619c82..9ec671f6 100644 --- a/src/console.pas +++ b/src/console.pas @@ -2040,6 +2040,7 @@ begin writestring(identifier); writestring('] '); writestring(str); + redrawWindows; end; procedure Outputln(identifier : PChar; str : PChar); diff --git a/src/cpu.pas b/src/cpu.pas index 11a2b7cd..77729344 100644 --- a/src/cpu.pas +++ b/src/cpu.pas @@ -262,6 +262,21 @@ begin printCapabilities(getTerminalHWND); end; +procedure enableSSE(); +begin + If CPUID.Capabilities0^.SSE then begin + asm + MOV EAX, CR0 + AND AX, $FFFB + OR AX, $2 + MOV CR0, EAX + MOV EAX, CR4 + OR AX, 3 shl 9 + MOV CR4, EAX + end; + end; +end; + procedure init(); begin terminal.registerCommand('CPU', @Terminal_Command_CPU, 'CPU Info.'); @@ -270,6 +285,7 @@ begin getCPUIdentifier; getCPUCapabilities; getCPUClockSpeed; + enableSSE; end; end. \ No newline at end of file diff --git a/src/include/hashmap.pas b/src/include/hashmap.pas index a7b43150..72029e4a 100644 --- a/src/include/hashmap.pas +++ b/src/include/hashmap.pas @@ -3,7 +3,7 @@ unit hashmap; interface uses - md5, util, strings, lmemorymanager, console; + md5, util, strings, lmemorymanager, console, tracer; type DPHashItem = ^PHashItem; @@ -16,15 +16,16 @@ type end; PHashMap = ^THashMap; THashMap = record - Size : uint32; - Table : DPHashItem; + Size : uint32; + LoadFactor : Single; + Count : 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 delete(map : PHashMap; key : pchar; freeItem : boolean); procedure printMap(map : PHashMap); implementation @@ -59,6 +60,69 @@ begin newItem^.Hash:= 0; end; +procedure putItem(table : DPHashItem; item : PHashItem; idx : uint32); +var + ExistingItem : PHashItem; + c : uint32; + +begin + tracer.push_trace('hashmap.putItem.1'); + ExistingItem:= table[idx]; + tracer.push_trace('hashmap.putItem.2'); + if ExistingItem = nil then begin + tracer.push_trace('hashmap.putItem.3'); + table[idx]:= item; + end else begin + tracer.push_trace('hashmap.putItem.4'); + c:=0; + while ExistingItem^.Next <> nil do begin + tracer.push_trace('hashmap.putItem.5'); + ExistingItem:= ExistingItem^.Next; + end; + tracer.push_trace('hashmap.putItem.6'); + ExistingItem^.Next:= item; + tracer.push_trace('hashmap.putItem.6'); + end; +end; + +procedure checkAndRebase(map : PHashMap); +var + size : Single; + loadFactor : Single; + max_load : Single; + NewTable : DPHashItem; + NewSize : uint32; + i : uint32; + Item : PHashItem; + Next : PHashItem; + +begin + size:= map^.size; + loadFactor:= map^.LoadFactor; + max_load:= size * loadFactor; + if map^.count > max_load then begin + NewSize:= map^.Size * 2; + NewTable:= DPHashItem(kalloc(sizeof(PHashItem) * NewSize)); + for i:=0 to NewSize-1 do begin + NewTable[i]:= nil; + end; + If NewTable <> nil then begin + for i:=0 to map^.size-1 do begin + item:= map^.table[i]; + while item <> nil do begin + Next:= item^.Next; + item^.Next:= nil; + putItem(NewTable, item, hashIndex(NewSize, item^.hash)); + item:= Next; + end; + end; + kfree(void(map^.table)); + map^.table:= NewTable; + map^.size:= NewSize; + end; + end; +end; + procedure add(map : PHashMap; key : pchar; value : void); var Idx : uint32; @@ -92,6 +156,8 @@ begin if Item^.Key = nil then Item^.Key:= stringCopy(key); Item^.Data:= value; Item^.Hash:= hash; + inc(map^.count); + checkAndRebase(map); end; end; @@ -125,13 +191,15 @@ begin Map:= PHashMap(kalloc(sizeof(THashMap))); Map^.size:= size; Map^.Table:= DPHashItem(Kalloc(sizeof(PHashItem) * Size)); + Map^.LoadFactor:= 0.75; + Map^.Count:= 0; for i:=0 to size-1 do begin Map^.Table[i]:= nil; end; new:= Map; end; -procedure deleteAndFree(map : PHashMap; key : pchar); +procedure delete(map : PHashMap; key : pchar; freeItem : boolean); var Idx : uint32; hash : uint32; @@ -144,54 +212,25 @@ begin hash:= KeyHash(key); Idx:= hashIndex(map^.size, hash); 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; + while not StringEquals(Item^.key, key) do begin + Prev:= Item; + Item:= Item^.Next; + if Item = nil then break; end; - kfree(void(Item^.Key)); - kfree(void(Item^.Data)); - kfree(void(Item)); - end; - end; -end; - -procedure delete(map : PHashMap; key : pchar); -var - Idx : uint32; - hash : uint32; - Item : PHashItem; - Prev : PHashItem; - -begin - Prev:= nil; - if (map <> nil) and (key <> nil) then begin - hash:= KeyHash(key); - Idx:= hashIndex(map^.size, hash); - 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; + 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)); + if freeItem then kfree(void(Item^.Data)); + kfree(void(Item)); + dec(map^.count); end; - kfree(void(Item^.Key)); - kfree(void(Item)); end; end; end; diff --git a/src/kernel.pas b/src/kernel.pas index 1621420d..9d3d7e01 100644 --- a/src/kernel.pas +++ b/src/kernel.pas @@ -178,7 +178,9 @@ begin console.init(); { CPUID } + console.outputln('CPU', 'Init begin'); cpu.init(); + console.outputln('CPU', 'Init end'); { Call Tracer } tracer.init(); @@ -242,8 +244,7 @@ begin tracer.push_trace('kmain.TICK'); - - HM:= hashmap.new(10000); + HM:= hashmap.new(16); hashmap.add(HM, 'testificate', void(1)); hashmap.add(HM, 'asuro', void(10)); hashmap.add(HM, 'myfirstos', void(100)); diff --git a/src/stub/stub.asm b/src/stub/stub.asm index 53ea9f7e..4c695127 100644 --- a/src/stub/stub.asm +++ b/src/stub/stub.asm @@ -63,8 +63,8 @@ dd 0 dd 0 dd 0 dd 0 +dd 1280 dd 1024 -dd 768 dd 16 ;