mruby/c VM Source Code release 3.4
Loading...
Searching...
No Matches
keyvalue.c
Go to the documentation of this file.
1
47
48/***** Feature test switches ************************************************/
49/***** System headers *******************************************************/
50//@cond
51#include "vm_config.h"
52#include <stdlib.h>
53#include <string.h>
54//@endcond
55
56/***** Local headers ********************************************************/
57#include "mrubyc.h"
58
59/***** Constat values *******************************************************/
60#if !defined(MRBC_KV_SIZE_INIT)
61#define MRBC_KV_SIZE_INIT 2
62#endif
63#if !defined(MRBC_KV_SIZE_INCREMENT)
64#define MRBC_KV_SIZE_INCREMENT 5
65#endif
66
67/***** Macros ***************************************************************/
68/***** Typedefs *************************************************************/
69/***** Function prototypes **************************************************/
70/***** Local variables ******************************************************/
71/***** Global variables *****************************************************/
72/***** Signal catching functions ********************************************/
73/***** Local functions ******************************************************/
74//================================================================
81static int binary_search(mrbc_kv_handle *kvh, mrbc_sym sym_id)
82{
83 int left = 0;
84 int right = kvh->n_stored - 1;
85 if( right < 0 ) return -1;
86
87 while( left < right ) {
88 int mid = (left + right) / 2;
89 if( kvh->data[mid].sym_id < sym_id ) {
90 left = mid + 1;
91 } else {
92 right = mid;
93 }
94 }
95
96 return left;
97}
98
99
100/***** Global functions *****************************************************/
101
102//================================================================
109mrbc_kv_handle * mrbc_kv_new(struct VM *vm, int size)
110{
111 mrbc_kv_handle *kvh = mrbc_alloc(vm, sizeof(mrbc_kv_handle));
112 if( !kvh ) return NULL; // ENOMEM
113
114 if( mrbc_kv_init_handle( vm, kvh, size ) != 0 ) {
115 mrbc_raw_free( kvh );
116 return NULL;
117 }
118
119 return kvh;
120}
121
122
123//================================================================
131int mrbc_kv_init_handle(struct VM *vm, mrbc_kv_handle *kvh, int size)
132{
133 kvh->data_size = size;
134 kvh->n_stored = 0;
135
136 if( size == 0 ) {
137 // save VM address temporary.
138 kvh->vm = vm;
139
140 } else {
141 // Allocate data buffer.
142 kvh->data = mrbc_alloc(vm, sizeof(mrbc_kv) * size);
143 if( !kvh->data ) return -1; // ENOMEM
144
145#if defined(MRBC_DEBUG)
146 memcpy( kvh->data->obj_mark_, "KV", 2 );
147#endif
148 }
149
150 return 0;
151}
152
153
154//================================================================
160{
162 mrbc_raw_free(kvh);
163}
164
165
166//================================================================
172{
173 if( kvh->data_size == 0 ) return;
174
175 mrbc_kv_clear(kvh);
176 kvh->data_size = 0;
177 mrbc_raw_free(kvh->data);
178}
179
180
181#if defined(MRBC_ALLOC_VMID)
182//================================================================
187void mrbc_kv_clear_vm_id(mrbc_kv_handle *kvh)
188{
189 if( kvh->data_size == 0 ) return;
190
191 mrbc_kv *p1 = kvh->data;
192 const mrbc_kv *p2 = p1 + kvh->n_stored;
193
194 mrbc_set_vm_id( p1, 0 );
195
196 while( p1 < p2 ) {
197 mrbc_clear_vm_id(&p1->value);
198 p1++;
199 }
200}
201#endif
202
203
204//================================================================
212{
213 if( size <= 0 ) size = 1;
214
215 mrbc_kv *data = mrbc_raw_realloc(kvh->data, sizeof(mrbc_kv) * size);
216 if( !data ) return E_NOMEMORY_ERROR; // ENOMEM
217
218 kvh->data = data;
219 kvh->data_size = size;
220
221 return 0;
222}
223
224
225//================================================================
234{
235 int idx = binary_search(kvh, sym_id);
236 if( idx < 0 ) {
237 idx = 0;
238 goto INSERT_VALUE;
239 }
240
241 // replace value ?
242 if( kvh->data[idx].sym_id == sym_id ) {
243 mrbc_decref( &kvh->data[idx].value );
244 kvh->data[idx].value = *set_val;
245 return 0;
246 }
247
248 if( kvh->data[idx].sym_id < sym_id ) {
249 idx++;
250 }
251
252 INSERT_VALUE:
253 // need alloc?
254 if( kvh->data_size == 0 ) {
255 kvh->data = mrbc_alloc(kvh->vm, sizeof(mrbc_kv) * MRBC_KV_SIZE_INIT);
256 if( kvh->data == NULL ) return E_NOMEMORY_ERROR; // ENOMEM
258
259#if defined(MRBC_DEBUG)
260 memcpy( kvh->data->obj_mark_, "KV", 2 );
261#endif
262
263 // need resize?
264 } else if( kvh->n_stored >= kvh->data_size ) {
265 if( mrbc_kv_resize(kvh, kvh->data_size + MRBC_KV_SIZE_INCREMENT) != 0 ) {
266 return E_NOMEMORY_ERROR; // ENOMEM
267 }
268 }
269
270 // need move data?
271 if( idx < kvh->n_stored ) {
272 int size = sizeof(mrbc_kv) * (kvh->n_stored - idx);
273 memmove( &kvh->data[idx+1], &kvh->data[idx], size );
274 }
275
276 kvh->data[idx].sym_id = sym_id;
277 kvh->data[idx].value = *set_val;
278 kvh->n_stored++;
279
280 return 0;
281}
282
283
284
285//================================================================
293{
294 int idx = binary_search(kvh, sym_id);
295 if( idx < 0 ) return NULL;
296 if( kvh->data[idx].sym_id != sym_id ) return NULL;
297
298 return &kvh->data[idx].value;
299}
300
301
302#if 0
303//================================================================
311int mrbc_kv_append(mrbc_kv_handle *kvh, mrbc_sym sym_id, mrbc_value *set_val)
312{
313 // need alloc?
314 if( kvh->data_size == 0 ) {
315 kvh->data = mrbc_alloc(kvh->vm, sizeof(mrbc_kv) * MRBC_KV_SIZE_INIT);
316 if( kvh->data == NULL ) return E_NOMEMORY_ERROR; // ENOMEM
318
319#if defined(MRBC_DEBUG)
320 memcpy( kvh->data->obj_mark_, "KV", 2 );
321#endif
322
323 // need resize?
324 } else if( kvh->n_stored >= kvh->data_size ) {
325 if( mrbc_kv_resize(kvh, kvh->data_size + MRBC_KV_SIZE_INCREMENT) != 0 ) {
326 return E_NOMEMORY_ERROR; // ENOMEM
327 }
328 }
329
330 kvh->data[kvh->n_stored].sym_id = sym_id;
331 kvh->data[kvh->n_stored].value = *set_val;
332 kvh->n_stored++;
333
334 return 0;
335}
336
337
338
339static int compare_key( const void *kv1, const void *kv2 )
340{
341 return ((mrbc_kv *)kv1)->sym_id - ((mrbc_kv *)kv2)->sym_id;
342}
343
344//================================================================
350int mrbc_kv_reorder(mrbc_kv_handle *kvh)
351{
352 if( kvh->data_size == 0 ) return 0;
353
354 qsort( kvh->data, kvh->n_stored, sizeof(mrbc_kv), compare_key );
355
356 return 0;
357}
358#endif
359
360
361//================================================================
369{
370 int idx = binary_search(kvh, sym_id);
371 if( idx < 0 ) return 0;
372 if( kvh->data[idx].sym_id != sym_id ) return 0;
373
374 mrbc_decref( &kvh->data[idx].value );
375 kvh->n_stored--;
376 memmove( kvh->data + idx, kvh->data + idx + 1,
377 sizeof(mrbc_kv) * (kvh->n_stored - idx) );
378
379 return 0;
380}
381
382
383
384//================================================================
390{
391 mrbc_kv *p1 = kvh->data;
392 const mrbc_kv *p2 = p1 + kvh->n_stored;
393 while( p1 < p2 ) {
394 mrbc_decref(&p1->value);
395 p1++;
396 }
397
398 kvh->n_stored = 0;
399}
400
401
402//================================================================
409{
411
412 while( mrbc_kv_i_has_next( &ite ) ) {
413 mrbc_kv *kv = mrbc_kv_i_next( &ite );
414 mrbc_incref( &kv->value );
415 mrbc_kv_set( dst, kv->sym_id, &kv->value );
416 }
417}
void * mrbc_raw_realloc(void *ptr, unsigned int size)
Definition alloc.c:796
void mrbc_raw_free(void *ptr)
Definition alloc.c:695
#define MRBC_KV_SIZE_INIT
Definition keyvalue.c:61
void mrbc_kv_delete(mrbc_kv_handle *kvh)
Definition keyvalue.c:159
int mrbc_kv_resize(mrbc_kv_handle *kvh, int size)
Definition keyvalue.c:211
void mrbc_kv_dup(const mrbc_kv_handle *src, mrbc_kv_handle *dst)
Definition keyvalue.c:408
static int binary_search(mrbc_kv_handle *kvh, mrbc_sym sym_id)
Definition keyvalue.c:81
mrbc_kv_handle * mrbc_kv_new(struct VM *vm, int size)
Definition keyvalue.c:109
int mrbc_kv_init_handle(struct VM *vm, mrbc_kv_handle *kvh, int size)
Definition keyvalue.c:131
void mrbc_kv_delete_data(mrbc_kv_handle *kvh)
Definition keyvalue.c:171
#define MRBC_KV_SIZE_INCREMENT
Definition keyvalue.c:64
void mrbc_kv_clear(mrbc_kv_handle *kvh)
Definition keyvalue.c:389
int mrbc_kv_remove(mrbc_kv_handle *kvh, mrbc_sym sym_id)
Definition keyvalue.c:368
mrbc_value * mrbc_kv_get(mrbc_kv_handle *kvh, mrbc_sym sym_id)
Definition keyvalue.c:292
int mrbc_kv_set(mrbc_kv_handle *kvh, mrbc_sym sym_id, mrbc_value *set_val)
Definition keyvalue.c:233
static mrbc_kv * mrbc_kv_i_next(mrbc_kv_iterator *ite)
Definition keyvalue.h:152
struct RKeyValueHandle mrbc_kv_handle
Key-Value handle.
static int mrbc_kv_i_has_next(const mrbc_kv_iterator *ite)
Definition keyvalue.h:136
struct RKeyValue mrbc_kv
Key-Value data.
struct RKeyValueIterator mrbc_kv_iterator
Key-Value iterator.
static mrbc_kv_iterator mrbc_kv_iterator_new(const mrbc_kv_handle *h)
Definition keyvalue.h:115
Include at once the necessary header files.
uint16_t n_stored
num of stored.
Definition keyvalue.h:54
struct VM * vm
pointer to VM (if data_size == 0)
Definition keyvalue.h:57
mrbc_kv * data
pointer to allocated memory.
Definition keyvalue.h:56
uint16_t data_size
data buffer size.
Definition keyvalue.h:53
mrbc_sym sym_id
symbol ID as key.
Definition keyvalue.h:42
mrbc_value value
stored value.
Definition keyvalue.h:43
Virtual Machine.
Definition vm.h:140
static void mrbc_decref(mrbc_value *v)
Definition value.h:604
static void mrbc_incref(mrbc_value *v)
Definition value.h:589
@ E_NOMEMORY_ERROR
Definition value.h:108
int16_t mrbc_sym
mruby/c symbol ID
Definition value.h:59
struct RObject mrbc_value
Definition value.h:174
Global configuration of mruby/c VM's.