1 // My table library thing
3 // Written by: Test_User <hax@andrewyu.org>
5 // This is free and unencumbered software released into the public
8 // Anyone is free to copy, modify, publish, use, compile, sell, or
9 // distribute this software, either in source code form or as a compiled
10 // binary, for any purpose, commercial or non-commercial, and by any
13 // In jurisdictions that recognize copyright laws, the author or authors
14 // of this software dedicate any and all copyright interest in the
15 // software to the public domain. We make this dedication for the benefit
16 // of the public at large and to the detriment of our heirs and
17 // successors. We intend this dedication to be an overt act of
18 // relinquishment in perpetuity of all present and future rights to this
19 // software under copyright law.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 // OTHER DEALINGS IN THE SOFTWARE.
38 // currently going with a binary lookup...
40 static inline int compare(struct string a
, struct string b
) {
47 int val
= memcmp(a
.data
, b
.data
, len
);
52 else if (a
.len
> b
.len
)
59 static inline uint64_t search(struct table tbl
, struct string name
, uint8_t *exists
) {
65 size_t low
= 0, high
= tbl
.len
- 1;
70 int val
= compare(tbl
.array
[mid
].name
, name
);
89 mid
= low
+ ((high
-low
)/2);
92 int val
= compare(tbl
.array
[mid
].name
, name
);
96 } else if (val
== 0) {
105 int set_table_index(struct table
*tbl
, struct string name
, void *ptr
) {
107 uint64_t index
= search(*tbl
, name
, &exists
);
109 if (index
== tbl
->len
) {
110 void *tmp
= realloc(tbl
->array
, sizeof(*(tbl
->array
)) * (tbl
->len
+1));
117 } else if (!exists
) {
118 void *tmp
= realloc(tbl
->array
, sizeof(*(tbl
->array
)) * (tbl
->len
+1));
124 memmove(&(tbl
->array
[index
+1]), &(tbl
->array
[index
]), (tbl
->len
- index
) * sizeof(*(tbl
->array
)));
127 tbl
->array
[index
].ptr
= ptr
;
129 return 0; // don't overwrite old allocated name
132 char *data
= malloc(name
.len
);
136 memcpy(data
, name
.data
, name
.len
);
138 tbl
->array
[index
] = (struct table_index
){{data
, name
.len
}, ptr
};
143 void * get_table_index(struct table tbl
, struct string name
) {
145 uint64_t index
= search(tbl
, name
, &exists
);
149 return tbl
.array
[index
].ptr
;
152 uint8_t has_table_index(struct table tbl
, struct string name
) {
154 search(tbl
, name
, &exists
);
158 void * remove_table_index(struct table
*tbl
, struct string name
) {
160 uint64_t index
= search(*tbl
, name
, &exists
);
165 void *ptr
= tbl
->array
[index
].ptr
;
166 free(tbl
->array
[index
].name
.data
);
168 memmove(&(tbl
->array
[index
]), &(tbl
->array
[index
+1]), (tbl
->len
- index
- 1) * sizeof(*(tbl
->array
)));
171 void *tmp
= realloc(tbl
->array
, sizeof(*(tbl
->array
)) * tbl
->len
);
172 if (tmp
|| (tbl
->len
== 0))
174 // else: realloc failed on shrinking... so now we have a table that's allocated a bit too big, not much of an issue
179 void clear_table(struct table
*tbl
) {
180 for (uint64_t i
= 0; i
< tbl
->len
; i
++)
181 free(tbl
->array
[i
].name
.data
);
183 tbl
->array
= realloc(tbl
->array
, 0);