sssimulator / Matrix / string_indexer.c @ master
History | View | Annotate | Download (2.71 KB)
1 |
/*
|
---|---|
2 |
* This is SSSim: the Simple & Stupid Simulator
|
3 |
*
|
4 |
* Copyright (c) 2015 Luca Baldesi
|
5 |
*
|
6 |
* This is free software; see gpl-3.0.txt
|
7 |
*/
|
8 |
|
9 |
#include <stdint.h> |
10 |
#include <string.h> |
11 |
#include <malloc.h> |
12 |
|
13 |
#define STRING_INDEXER_INC_SIZE 10 |
14 |
|
15 |
struct string_indexer {
|
16 |
char ** strings;
|
17 |
uint32_t * ids; |
18 |
uint32_t n_elements; |
19 |
uint32_t size; |
20 |
}; |
21 |
|
22 |
int string_indexer_init(struct string_indexer * si,const uint32_t size) |
23 |
{ |
24 |
if(si)
|
25 |
{ |
26 |
si->n_elements = 0;
|
27 |
si->size = size; |
28 |
si->strings = (char **) malloc (sizeof(char *) * si->size); |
29 |
si->ids = (uint32_t *) malloc (sizeof(char *) * si->size); |
30 |
} |
31 |
return si->strings == NULL || si->ids == NULL ? -1 : 0; |
32 |
} |
33 |
|
34 |
struct string_indexer * string_indexer_new(const uint32_t size) |
35 |
{ |
36 |
struct string_indexer * si = NULL; |
37 |
|
38 |
si = (struct string_indexer *) malloc (sizeof(struct string_indexer)); |
39 |
|
40 |
string_indexer_init(si,size); |
41 |
return si;
|
42 |
} |
43 |
|
44 |
void string_indexer_destroy(struct string_indexer ** si) |
45 |
{ |
46 |
uint32_t i; |
47 |
// fprintf(stderr, "[DEBUG] in string destroy\n");
|
48 |
|
49 |
if(si && *si && (*si)->strings)
|
50 |
{ |
51 |
for(i = 0; i < (*si)->n_elements; i++) |
52 |
free(((*si)->strings)[i]); |
53 |
free((*si)->strings); |
54 |
} |
55 |
if (si)
|
56 |
{ |
57 |
if(*si && (*si)->ids)
|
58 |
free((*si)->ids); |
59 |
if(*si)
|
60 |
free(*si); |
61 |
*si = NULL;
|
62 |
} |
63 |
} |
64 |
|
65 |
uint32_t string_indexer_check_pos(const struct string_indexer *h, const char * s) |
66 |
{ |
67 |
uint32_t a,b,i; |
68 |
|
69 |
i = 0;
|
70 |
if(h && h->n_elements > 0) |
71 |
{ |
72 |
a = 0;
|
73 |
b = h->n_elements-1;
|
74 |
i = (b+a)/2;
|
75 |
|
76 |
while(b > a)
|
77 |
{ |
78 |
if (strcmp(s,h->strings[i]) > 0) |
79 |
a = i+1;
|
80 |
if (strcmp(s,h->strings[i]) < 0) |
81 |
b = i ? i-1 : 0; |
82 |
if (strcmp(s,h->strings[i]) == 0) |
83 |
a = b = i; |
84 |
|
85 |
i = (b+a)/2;
|
86 |
} |
87 |
if (strcmp(s,h->strings[i]) > 0) |
88 |
i++; |
89 |
} |
90 |
|
91 |
return i;
|
92 |
} |
93 |
|
94 |
uint32_t string_indexer_id(struct string_indexer * si,const char * line) |
95 |
{ |
96 |
uint32_t i; |
97 |
|
98 |
if(si && line)
|
99 |
{ |
100 |
i = string_indexer_check_pos(si,line); |
101 |
if(i>= si->n_elements || strcmp(line,(si->strings)[i]))
|
102 |
{ |
103 |
if((si->n_elements + 1) >= si->size) |
104 |
{ |
105 |
si->size += STRING_INDEXER_INC_SIZE; |
106 |
si->strings = (char **) realloc(si->strings,sizeof(char*) * si->size); |
107 |
si->ids = (uint32_t *) realloc(si->ids,sizeof(uint32_t) * si->size);
|
108 |
} |
109 |
memmove(&(si->strings[i+1]),&(si->strings[i]),sizeof(char *) * (si->n_elements -i)); |
110 |
memmove(&(si->ids[i+1]),&(si->ids[i]),sizeof(uint32_t) * (si->n_elements -i)); |
111 |
|
112 |
si->strings[i] = strdup(line); |
113 |
si->ids[i] = si->n_elements; |
114 |
si->n_elements++; |
115 |
} |
116 |
return si->ids[i];
|
117 |
} |
118 |
return 0; |
119 |
} |
120 |
|
121 |
uint32_t string_indexer_size(struct string_indexer *si)
|
122 |
{ |
123 |
if(si)
|
124 |
return si->n_elements;
|
125 |
else
|
126 |
return 0; |
127 |
} |
128 |
|
129 |
uint8_t string_indexer_check(const struct string_indexer * si,const char* s) |
130 |
{ |
131 |
uint32_t pos; |
132 |
|
133 |
pos = string_indexer_check_pos(si,s); |
134 |
|
135 |
if(pos >= si->n_elements || strcmp(si->strings[pos],s) != 0) |
136 |
return 0; |
137 |
return 1; |
138 |
} |