1+ #include "metac_value_table.h"
2+
3+ const metac_node_ptr_t empty_node = {~0u };
4+
5+ static inline bool IsFilled (metac_value_table_slot_t slot )
6+ {
7+ return slot .HashKey != 0 ;
8+ }
9+
10+ void ValueTable_Init_ (metac_value_table_t * table , uint32_t slotCountLog2 , metac_alloc_t * alloc ,
11+ const char * file , uint32_t line )
12+ {
13+ table -> SlotCount_Log2 = slotCountLog2 ;
14+ const uint32_t maxSlots = (1 << table -> SlotCount_Log2 );
15+ table -> Slots = cast (metac_value_table_slot_t * )
16+ Allocator_Calloc_ (alloc , sizeof (metac_value_table_slot_t ), maxSlots , file , line );
17+ table -> SlotsUsed = 0 ;
18+
19+
20+ void ValueTable_Free (metac_value_table_t * table )
21+ {
22+ static const metac_value_table_t zeroTable = {0 };
23+ (* table ) = zeroTable ;
24+ }
25+
26+ metac_node_ptr_t GetOrAddValue (metac_value_table_t * table , metac_node_ptr_t keyNode , metac_node_ptr_t valueNode )
27+ {
28+ metac_node_ptr_t result = {0 };
29+
30+ const uint32_t slotIndexMask = ((1 << table -> SlotCount_Log2 ) - 1 );
31+ const uint32_t initialSlotIndex = (keyNodeHash & slotIndexMask );
32+ uint32_t displacement = 0 ;
33+
34+ for (uint32_t slotIndex = initialSlotIndex ; (++ slotIndex & slotIndexMask ) != initialSlotIndex ;)
35+ {
36+ metac_value_table_slot_t * slot = & table -> Slots [(slotIndex - 1 ) & slotIndexMask ];
37+
38+ if (slot -> HashKey == keyNodeHash )
39+ {
40+ if (slot -> KeyNode .v == keyNode .v )
41+ {
42+ result = slot -> ValueNode ;
43+ #ifdef REFCOUNT
44+ slot -> RefCount ++ ;
45+ #endif
46+ break ;
47+ }
48+ }
49+ else if (slot -> HashKey == 0 )
50+ {
51+ result = valueNode ;
52+ slot -> HashKey = keyNodeHash ;
53+ slot -> KeyNode = keyNode ;
54+ slot -> ValueNode = valueNode ;
55+ #ifdef REFCOUNT
56+ slot -> RefCount = 1 ;
57+ slot -> Displacement = displacement ;
58+ #endif
59+ table -> SlotsUsed ++ ;
60+ break ;
61+ }
62+ displacement ++ ;
63+ }
64+ return result ;
65+ }
66+
67+ int32_t ValueTable_HasKey (metac_value_table_t * table , uint32_t keyNodeHash , metac_node_ptr_t keyNode )
68+ {
69+ int32_t result = -1 ;
70+ const uint32_t slotIndexMask = ((1 << table -> SlotCount_Log2 ) - 1 );
71+ const uint32_t initialSlotIndex = (keyNodeHash & slotIndexMask );
72+
73+ for (uint32_t slotIndex = initialSlotIndex ; (++ slotIndex & slotIndexMask ) != initialSlotIndex ;)
74+ {
75+ int32_t idx = (int32_t )((slotIndex - 1 ) & slotIndexMask );
76+ metac_value_table_slot_t slot = table -> Slots [idx ];
77+
78+ if (slot .HashKey == 0 )
79+ break ;
80+ if (slot .HashKey == keyNodeHash && slot .KeyNode .v == keyNode .v )
81+ {
82+ result = idx ;
83+ break ;
84+ }
85+ }
86+
87+ return result ;
88+ }
89+
90+ metac_node_ptr_t IsValueInTable (metac_value_table_t * table , uint32_t keyNodeHash , metac_node_ptr_t keyNode )
91+ {
92+ metac_node_ptr_t result = {0 };
93+ const uint32_t slotIndexMask = ((1 << table -> SlotCount_Log2 ) - 1 );
94+ const uint32_t initialSlotIndex = (keyNodeHash & slotIndexMask );
95+
96+ for (uint32_t slotIndex = initialSlotIndex ; (++ slotIndex & slotIndexMask ) != initialSlotIndex ;)
97+ {
98+ metac_value_table_slot_t slot = table -> Slots [(slotIndex - 1 ) & slotIndexMask ];
99+
100+ if (slot .HashKey == 0 )
101+ return result ;
102+ if (slot .HashKey == keyNodeHash && slot .KeyNode .v == keyNode .v )
103+ {
104+ result = slot .ValueNode ;
105+ return result ;
106+ }
107+ }
108+
109+ return result ;
110+ }
111+
112+ metac_value_table_slot_t * ValueTableLookup (metac_value_table_t * table , uint32_t keyNodeHash , metac_node_ptr_t keyNode , metac_node_ptr_t valueNode )
113+ {
114+ const uint32_t slotIndexMask = ((1 << table -> SlotCount_Log2 ) - 1 );
115+ const uint32_t initialSlotIndex = (keyNodeHash & slotIndexMask );
116+
117+ for (uint32_t slotIndex = initialSlotIndex ; (++ slotIndex & slotIndexMask ) != initialSlotIndex ;)
118+ {
119+ uint32_t lookupIdx = (slotIndex - 1 ) & slotIndexMask ;
120+ metac_value_table_slot_t slot = table -> Slots [lookupIdx ];
121+
122+ if (slot .HashKey == 0 )
123+ return 0 ;
124+ if (slot .HashKey == keyNodeHash && slot .KeyNode .v == keyNode .v && slot .ValueNode .v == valueNode .v )
125+ return table -> Slots + lookupIdx ;
126+ }
127+
128+ return 0 ;
129+ }
130+
131+ bool IsInValueTable (metac_value_table_t * table , uint32_t keyNodeHash , metac_node_ptr_t keyNode , metac_node_ptr_t valueNode )
132+ {
133+ return ValueTableLookup (table , keyNodeHash , keyNode , valueNode ) != 0 ;
134+ }
0 commit comments