2 changed files with 47 additions and 0 deletions
@ -0,0 +1,46 @@ |
|||
;; HashStringTable.cake: Hash a string then store in a central table |
|||
;; The strings will be copied for the table to ensure it will stick around until |
|||
;; free-string-table is called. |
|||
(import "Hash.cake" "Dictionary.cake") |
|||
(c-import &with-decls "<stdint.h>" "<stddef.h>") |
|||
|
|||
(defstruct hash-string-pair |
|||
key uint32_t |
|||
;; Owned by the string table |
|||
str (addr char)) |
|||
|
|||
(def-type-alias-global string-table (addr hash-string-pair)) ;; dictionary |
|||
(def-type-alias-global string-id uint32_t) |
|||
|
|||
(defun id-from-string (interned-strings (addr string-table) |
|||
str (addr (const char)) |
|||
string-length size_t |
|||
&return string-id) |
|||
(var hash uint32_t 0) |
|||
(hash-crc32 str string-length (addr hash)) |
|||
(unless (dict-ptr-at (deref interned-strings) hash) |
|||
(var new-pair hash-string-pair |
|||
(array hash |
|||
;; TODO: better memory allocation strategy |
|||
(strdup str))) |
|||
(dict-set-struct (deref interned-strings) new-pair)) |
|||
(return hash)) |
|||
|
|||
;; For safe comparison to quickly determine whether the string was not found |
|||
(var-global c-string-missing-from-string-table (const (addr (const char))) |
|||
"<String not in table>") |
|||
|
|||
;; May return null if the string has never been added to the string table |
|||
(defun string-from-string-id (interned-strings (addr string-table) |
|||
id string-id |
|||
&return (addr (const char))) |
|||
(var pair (addr hash-string-pair) (dict-ptr-at (deref interned-strings) id)) |
|||
(unless pair |
|||
(return c-string-missing-from-string-table)) |
|||
(return (path pair > str))) |
|||
|
|||
(defun free-string-table (table (addr string-table)) |
|||
(each-item-in-dict (deref table) i entry (addr hash-string-pair) |
|||
(free (path entry > str))) |
|||
(dict-free (deref table)) |
|||
(set (deref table) null)) |
Loading…
Reference in new issue