Branch data Line data Source code
1 : : #include "vqueue.h"
2 : : #include "fch_buckets.h"
3 : : #include <stdio.h>
4 : : #include <assert.h>
5 : : #include <stdlib.h>
6 : : //#define DEBUG
7 : : #include "debug.h"
8 : :
9 : : typedef struct __fch_bucket_entry_t
10 : : {
11 : : char * value;
12 : : cmph_uint32 length;
13 : : } fch_bucket_entry_t;
14 : :
15 : : typedef struct __fch_bucket_t
16 : : {
17 : : fch_bucket_entry_t * entries;
18 : : cmph_uint32 capacity, size;
19 : : } fch_bucket_t;
20 : :
21 : :
22 : :
23 : 0 : static void fch_bucket_new(fch_bucket_t *bucket)
24 : : {
25 : 0 : assert(bucket);
26 : 0 : bucket->size = 0;
27 : 0 : bucket->entries = NULL;
28 : 0 : bucket->capacity = 0;
29 : 0 : }
30 : :
31 : 0 : static void fch_bucket_destroy(fch_bucket_t *bucket)
32 : : {
33 : : cmph_uint32 i;
34 : 0 : assert(bucket);
35 : 0 : for (i = 0; i < bucket->size; i++)
36 : : {
37 : 0 : free((bucket->entries + i)->value);
38 : : }
39 : 0 : free(bucket->entries);
40 : 0 : }
41 : :
42 : :
43 : 0 : static void fch_bucket_reserve(fch_bucket_t *bucket, cmph_uint32 size)
44 : : {
45 : 0 : assert(bucket);
46 : 0 : if (bucket->capacity < size)
47 : : {
48 : 0 : cmph_uint32 new_capacity = bucket->capacity + 1;
49 : : DEBUGP("Increasing current capacity %u to %u\n", bucket->capacity, size);
50 : 0 : while (new_capacity < size)
51 : : {
52 : 0 : new_capacity *= 2;
53 : : }
54 : 0 : bucket->entries = (fch_bucket_entry_t *)realloc(bucket->entries, sizeof(fch_bucket_entry_t)*new_capacity);
55 : 0 : assert(bucket->entries);
56 : 0 : bucket->capacity = new_capacity;
57 : : DEBUGP("Increased\n");
58 : : }
59 : 0 : }
60 : :
61 : 0 : static void fch_bucket_insert(fch_bucket_t *bucket, char *val, cmph_uint32 val_length)
62 : : {
63 : 0 : assert(bucket);
64 : 0 : fch_bucket_reserve(bucket, bucket->size + 1);
65 : 0 : (bucket->entries + bucket->size)->value = val;
66 : 0 : (bucket->entries + bucket->size)->length = val_length;
67 : 0 : ++(bucket->size);
68 : 0 : }
69 : :
70 : :
71 : 0 : static cmph_uint8 fch_bucket_is_empty(fch_bucket_t *bucket)
72 : : {
73 : 0 : assert(bucket);
74 : 0 : return (cmph_uint8)(bucket->size == 0);
75 : : }
76 : :
77 : 0 : static cmph_uint32 fch_bucket_size(fch_bucket_t *bucket)
78 : : {
79 : 0 : assert(bucket);
80 : 0 : return bucket->size;
81 : : }
82 : :
83 : 0 : static char * fch_bucket_get_key(fch_bucket_t *bucket, cmph_uint32 index_key)
84 : : {
85 : 0 : assert(bucket); assert(index_key < bucket->size);
86 : 0 : return (bucket->entries + index_key)->value;
87 : : }
88 : :
89 : 0 : static cmph_uint32 fch_bucket_get_length(fch_bucket_t *bucket, cmph_uint32 index_key)
90 : : {
91 : 0 : assert(bucket); assert(index_key < bucket->size);
92 : 0 : return (bucket->entries + index_key)->length;
93 : : }
94 : :
95 : 0 : static void fch_bucket_print(fch_bucket_t * bucket, cmph_uint32 index)
96 : : {
97 : : cmph_uint32 i;
98 : 0 : assert(bucket);
99 : 0 : fprintf(stderr, "Printing bucket %u ...\n", index);
100 : 0 : for (i = 0; i < bucket->size; i++)
101 : : {
102 : 0 : fprintf(stderr, " key: %s\n", (bucket->entries + i)->value);
103 : : }
104 : 0 : }
105 : :
106 : : //////////////////////////////////////////////////////////////////////////////////////
107 : :
108 : : struct __fch_buckets_t
109 : : {
110 : : fch_bucket_t * values;
111 : : cmph_uint32 nbuckets, max_size;
112 : :
113 : : };
114 : :
115 : 0 : fch_buckets_t * fch_buckets_new(cmph_uint32 nbuckets)
116 : : {
117 : : cmph_uint32 i;
118 : 0 : fch_buckets_t *buckets = (fch_buckets_t *)malloc(sizeof(fch_buckets_t));
119 : 0 : assert(buckets);
120 : 0 : buckets->values = (fch_bucket_t *)calloc((size_t)nbuckets, sizeof(fch_bucket_t));
121 : 0 : for (i = 0; i < nbuckets; i++) fch_bucket_new(buckets->values + i);
122 : 0 : assert(buckets->values);
123 : 0 : buckets->nbuckets = nbuckets;
124 : 0 : buckets->max_size = 0;
125 : 0 : return buckets;
126 : : }
127 : :
128 : 0 : cmph_uint8 fch_buckets_is_empty(fch_buckets_t * buckets, cmph_uint32 index)
129 : : {
130 : 0 : assert(index < buckets->nbuckets);
131 : 0 : return fch_bucket_is_empty(buckets->values + index);
132 : : }
133 : :
134 : 0 : void fch_buckets_insert(fch_buckets_t * buckets, cmph_uint32 index, char * key, cmph_uint32 length)
135 : : {
136 : 0 : assert(index < buckets->nbuckets);
137 : 0 : fch_bucket_insert(buckets->values + index, key, length);
138 : 0 : if (fch_bucket_size(buckets->values + index) > buckets->max_size)
139 : : {
140 : 0 : buckets->max_size = fch_bucket_size(buckets->values + index);
141 : : }
142 : 0 : }
143 : :
144 : 0 : cmph_uint32 fch_buckets_get_size(fch_buckets_t * buckets, cmph_uint32 index)
145 : : {
146 : 0 : assert(index < buckets->nbuckets);
147 : 0 : return fch_bucket_size(buckets->values + index);
148 : : }
149 : :
150 : :
151 : 0 : char * fch_buckets_get_key(fch_buckets_t * buckets, cmph_uint32 index, cmph_uint32 index_key)
152 : : {
153 : 0 : assert(index < buckets->nbuckets);
154 : 0 : return fch_bucket_get_key(buckets->values + index, index_key);
155 : : }
156 : :
157 : 0 : cmph_uint32 fch_buckets_get_keylength(fch_buckets_t * buckets, cmph_uint32 index, cmph_uint32 index_key)
158 : : {
159 : 0 : assert(index < buckets->nbuckets);
160 : 0 : return fch_bucket_get_length(buckets->values + index, index_key);
161 : : }
162 : :
163 : 0 : cmph_uint32 fch_buckets_get_max_size(fch_buckets_t * buckets)
164 : : {
165 : 0 : return buckets->max_size;
166 : : }
167 : :
168 : 0 : cmph_uint32 fch_buckets_get_nbuckets(fch_buckets_t * buckets)
169 : : {
170 : 0 : return buckets->nbuckets;
171 : : }
172 : :
173 : 0 : cmph_uint32 * fch_buckets_get_indexes_sorted_by_size(fch_buckets_t * buckets)
174 : : {
175 : 0 : cmph_uint32 i = 0;
176 : 0 : cmph_uint32 sum = 0, value;
177 : 0 : cmph_uint32 *nbuckets_size = (cmph_uint32 *) calloc((size_t)buckets->max_size + 1, sizeof(cmph_uint32));
178 : 0 : cmph_uint32 * sorted_indexes = (cmph_uint32 *) calloc((size_t)buckets->nbuckets, sizeof(cmph_uint32));
179 : :
180 : : // collect how many buckets for each size.
181 : 0 : for(i = 0; i < buckets->nbuckets; i++) nbuckets_size[fch_bucket_size(buckets->values + i)] ++;
182 : :
183 : : // calculating offset considering a decreasing order of buckets size.
184 : 0 : value = nbuckets_size[buckets->max_size];
185 : 0 : nbuckets_size[buckets->max_size] = sum;
186 : 0 : for(i = (int)buckets->max_size - 1; i >= 0; i--)
187 : : {
188 : 0 : sum += value;
189 : 0 : value = nbuckets_size[i];
190 : 0 : nbuckets_size[i] = sum;
191 : :
192 : : }
193 : : for(i = 0; i < buckets->nbuckets; i++)
194 : : {
195 : : sorted_indexes[nbuckets_size[fch_bucket_size(buckets->values + i)]] = (cmph_uint32)i;
196 : : nbuckets_size[fch_bucket_size(buckets->values + i)] ++;
197 : : }
198 : : free(nbuckets_size);
199 : : return sorted_indexes;
200 : : }
201 : :
202 : 0 : void fch_buckets_print(fch_buckets_t * buckets)
203 : : {
204 : : cmph_uint32 i;
205 : 0 : for (i = 0; i < buckets->nbuckets; i++) fch_bucket_print(buckets->values + i, i);
206 : 0 : }
207 : :
208 : 0 : void fch_buckets_destroy(fch_buckets_t * buckets)
209 : : {
210 : : cmph_uint32 i;
211 : 0 : for (i = 0; i < buckets->nbuckets; i++) fch_bucket_destroy(buckets->values + i);
212 : 0 : free(buckets->values);
213 : 0 : free(buckets);
214 : 0 : }
|