-
Notifications
You must be signed in to change notification settings - Fork 12
/
cxsa_main.c
126 lines (95 loc) · 3.27 KB
/
cxsa_main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "cxsa_main.h"
#include "cxsa_locking.h"
/*************************
* initialization section
************************/
autoxs_hashkey * CXSAccessor_last_hashkey = NULL;
autoxs_hashkey * CXSAccessor_hashkeys = NULL;
HashTable* CXSAccessor_reverse_hashkeys = NULL;
/* TODO the array index storage is still thought to not be 100%
* thread-safe during re-allocation and concurrent access by an
* implementation XSUB. Requires the same linked-list dance as the
* hash case. */
U32 CXSAccessor_no_arrayindices = 0;
U32 CXSAccessor_free_arrayindices_no = 0;
I32* CXSAccessor_arrayindices = NULL;
U32 CXSAccessor_reverse_arrayindices_length = 0;
I32* CXSAccessor_reverse_arrayindices = NULL;
/*************************
* implementation section
*************************/
/* implement hash containers */
STATIC
autoxs_hashkey *
_new_hashkey() {
autoxs_hashkey * retval;
cxa_malloc(retval, 1, autoxs_hashkey);
retval->next = NULL;
if (CXSAccessor_last_hashkey != NULL) { /* apend to list */
CXSAccessor_last_hashkey->next = retval;
}
else { /* init */
CXSAccessor_hashkeys = retval;
}
CXSAccessor_last_hashkey = retval;
return retval;
}
autoxs_hashkey *
get_hashkey(pTHX_ const char* key, const I32 len) {
autoxs_hashkey * hashkey;
CXSA_ACQUIRE_GLOBAL_LOCK(CXSAccessor_lock);
/* init */
if (CXSAccessor_reverse_hashkeys == NULL)
CXSAccessor_reverse_hashkeys = CXSA_HashTable_new(16, 0.9);
hashkey = (autoxs_hashkey *) CXSA_HashTable_fetch(CXSAccessor_reverse_hashkeys, key, (STRLEN)len);
if (hashkey == NULL) { /* does not exist */
hashkey = _new_hashkey();
/* store the new hash key in the reverse lookup table */
CXSA_HashTable_store(CXSAccessor_reverse_hashkeys, key, len, hashkey);
}
CXSA_RELEASE_GLOBAL_LOCK(CXSAccessor_lock);
return hashkey;
}
/* implement array containers */
STATIC
void
_resize_array(I32** array, U32* len, U32 newlen) {
cxa_realloc(*array, newlen, I32);
*len = newlen;
}
STATIC
void
_resize_array_init(I32** array, U32* len, U32 newlen, I32 init) {
U32 i;
cxa_realloc(*array, newlen, I32);
for (i = *len; i < newlen; ++i)
(*array)[i] = init;
*len = newlen;
}
/* this is private, call get_internal_array_index instead */
I32
_new_internal_arrayindex() {
if (CXSAccessor_no_arrayindices == CXSAccessor_free_arrayindices_no) {
U32 extend = 2 + CXSAccessor_no_arrayindices * 2;
/*printf("extending array index storage by %u\n", extend);*/
_resize_array(&CXSAccessor_arrayindices, &CXSAccessor_no_arrayindices, extend);
}
return CXSAccessor_free_arrayindices_no++;
}
I32 get_internal_array_index(I32 object_ary_idx) {
I32 new_index;
CXSA_ACQUIRE_GLOBAL_LOCK(CXSAccessor_lock);
if (CXSAccessor_reverse_arrayindices_length <= (U32)object_ary_idx)
_resize_array_init( &CXSAccessor_reverse_arrayindices,
&CXSAccessor_reverse_arrayindices_length,
object_ary_idx+1, -1 );
/* -1 == "undef" */
if (CXSAccessor_reverse_arrayindices[object_ary_idx] > -1) {
CXSA_RELEASE_GLOBAL_LOCK(CXSAccessor_lock);
return CXSAccessor_reverse_arrayindices[object_ary_idx];
}
new_index = _new_internal_arrayindex();
CXSAccessor_reverse_arrayindices[object_ary_idx] = new_index;
CXSA_RELEASE_GLOBAL_LOCK(CXSAccessor_lock);
return new_index;
}