2 /* Copyright (C) 2010-2018 by The D Language Foundation, All Rights Reserved
3 * http://www.digitalmars.com
4 * Distributed under the Boost Software License, Version 1.0.
5 * (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
6 * https://github.com/D-Programming-Language/dmd/blob/master/src/root/aav.c
10 * Implementation of associative arrays.
19 inline size_t hash(size_t a
)
21 a
^= (a
>> 20) ^ (a
>> 12);
22 return a
^ (a
>> 7) ^ (a
>> 4);
36 size_t nodes
; // total number of aaA nodes
37 aaA
* binit
[4]; // initial value of b[]
39 aaA aafirst
; // a lot of these AA's have only one entry
42 /****************************************************
43 * Determine number of entries in associative array.
46 size_t dmd_aaLen(AA
* aa
)
48 return aa
? aa
->nodes
: 0;
52 /*************************************************
53 * Get pointer to value in associative array indexed by key.
54 * Add entry for key if it is not already there, returning a pointer to a null Value.
55 * Create the associative array if it does not already exist.
58 Value
* dmd_aaGet(AA
** paa
, Key key
)
60 //printf("paa = %p\n", paa);
63 { AA
*a
= (AA
*)mem
.xmalloc(sizeof(AA
));
64 a
->b
= (aaA
**)a
->binit
;
72 assert((*paa
)->b_length
== 4);
74 //printf("paa = %p, *paa = %p\n", paa, *paa);
76 assert((*paa
)->b_length
);
77 size_t i
= hash((size_t)key
) & ((*paa
)->b_length
- 1);
78 aaA
** pe
= &(*paa
)->b
[i
];
80 while ((e
= *pe
) != NULL
)
87 // Not found, create new elem
88 //printf("create new one\n");
90 size_t nodes
= ++(*paa
)->nodes
;
91 e
= (nodes
!= 1) ? (aaA
*)mem
.xmalloc(sizeof(aaA
)) : &(*paa
)->aafirst
;
98 //printf("length = %d, nodes = %d\n", (*paa)->b_length, nodes);
99 if (nodes
> (*paa
)->b_length
* 2)
101 //printf("rehash\n");
109 /*************************************************
110 * Get value in associative array indexed by key.
111 * Returns NULL if it is not already there.
114 Value
dmd_aaGetRvalue(AA
* aa
, Key key
)
116 //printf("_aaGetRvalue(key = %p)\n", key);
120 size_t len
= aa
->b_length
;
121 i
= hash((size_t)key
) & (len
-1);
130 return NULL
; // not found
134 /********************************************
138 void dmd_aaRehash(AA
** paa
)
140 //printf("Rehash\n");
146 size_t len
= aa
->b_length
;
151 aaA
** newb
= (aaA
**)mem
.xmalloc(sizeof(aaA
)*len
);
152 memset(newb
, 0, len
* sizeof(aaA
*));
154 for (size_t k
= 0; k
< aa
->b_length
; k
++)
157 { aaA
* enext
= e
->next
;
158 size_t j
= hash((size_t)e
->key
) & (len
-1);
164 if (aa
->b
!= (aaA
**)aa
->binit
)