CUBRID Engine  latest
api_value_indexer.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * api_value_indexer.c -
21  */
22 
23 #include "config.h"
24 #include <string.h>
25 #include <assert.h>
26 #include "api_util.h"
27 #include "api_common.h"
28 
32 
33 /* array based VALUE_INDEXER implementation */
35 {
37  int nvalue;
40 };
41 
42 /* linked list based VALUE_INDEXER implementation */
44 {
48 };
49 
51 {
53  int nelems;
54  dlisth elems; /* list of LIST_VAI_ELEM */
55  /* speed boost caching */
56  int cache_idx;
58 };
59 
60 /* array based VALUE_INDEXER implementation */
61 static int ai_api_check (VALUE_INDEXER * indexer, int index, CHECK_PURPOSE pup);
62 static int ai_api_length (VALUE_INDEXER * indexer, int *len);
63 static int ai_api_get (VALUE_INDEXER * indexer, int index, VALUE_AREA ** rva, API_VALUE ** rv);
64 static int ai_api_set (VALUE_INDEXER * indexer, int index, VALUE_AREA * va, API_VALUE * dv);
65 static int ai_api_map (VALUE_INDEXER * indexer, int (*mapf) (void *, int, VALUE_AREA *, API_VALUE *), void *arg);
66 static int ai_api_insert (VALUE_INDEXER * indexer, int index, VALUE_AREA * va, API_VALUE * dval);
67 static int ai_api_delete (VALUE_INDEXER * indexer, int index, VALUE_AREA ** rva, API_VALUE ** dbval);
68 static void ai_api_destroy (VALUE_INDEXER * indexer, void (*df) (VALUE_AREA * va, API_VALUE * db));
69 
70 /* linked list based VALUE_INDEXER implementation */
71 static int li_api_check (VALUE_INDEXER * indexer, int index, CHECK_PURPOSE pup);
72 static int li_api_length (VALUE_INDEXER * indexer, int *len);
73 static int li_api_get (VALUE_INDEXER * indexer, int index, VALUE_AREA ** rva, API_VALUE ** rv);
74 static int li_api_set (VALUE_INDEXER * indexer, int index, VALUE_AREA * va, API_VALUE * val);
75 static int li_api_map (VALUE_INDEXER * indexer, int (*mapf) (void *, int, VALUE_AREA *, API_VALUE *), void *arg);
76 static int li_api_insert (VALUE_INDEXER * indexer, int index, VALUE_AREA * va, API_VALUE * dval);
77 static int li_api_delete (VALUE_INDEXER * indexer, int index, VALUE_AREA ** rva, API_VALUE ** dbval);
78 static void li_api_destroy (VALUE_INDEXER * indexer, void (*df) (VALUE_AREA * va, API_VALUE * db));
79 
80 /* ------------------------------------------------------------------------- */
81 /* array based VALUE_INDEXER implementation */
82 
83 /*
84  * ai_api_check - check if the given index is valid for the CHECK_PURPOSE
85  * return: NO_ERROR if successful, error code otherwise
86  * indexer(in): VALUE_INDEXER
87  * index(in): index
88  * pup(in): CHECK_PURPOSE
89  */
90 static int
92 {
93  ARRAY_INDEXER *ai = (ARRAY_INDEXER *) indexer;
94 
95  assert (ai != NULL);
96 
97  if (index < 0 || index >= ai->nvalue)
98  {
99  return ER_INTERFACE_GENERIC;
100  }
101 
102  return NO_ERROR;
103 }
104 
105 /*
106  * ai_api_length - get number of elements in the indexer
107  * return: NO_ERROR if successful, error code otherwise
108  * indexer(in): VALUE_INDEXER
109  * len(out): number of elements
110  */
111 static int
112 ai_api_length (VALUE_INDEXER * indexer, int *len)
113 {
114  ARRAY_INDEXER *ai = (ARRAY_INDEXER *) indexer;
115  assert (ai != NULL);
116  assert (len != NULL);
117  *len = ai->nvalue;
118  return NO_ERROR;
119 }
120 
121 /*
122  * ai_api_get - get element
123  * return: NO_ERROR if successful, error code otherwise
124  * indexer(in): VALUE_INDEXER
125  * index(in): index of the item
126  * rva(out): VALUE_AREA
127  * rv(out): API_VALUE
128  */
129 static int
130 ai_api_get (VALUE_INDEXER * indexer, int index, VALUE_AREA ** rva, API_VALUE ** rv)
131 {
132  ARRAY_INDEXER *ai = (ARRAY_INDEXER *) indexer;
133  assert (ai != NULL);
134  assert (rva != NULL);
135  assert (rv != NULL);
136 
137  *rva = ai->vs_map[index];
138  *rv = ai->values[index];
139  return NO_ERROR;
140 }
141 
142 /*
143  * ai_api_set - set VALUE_AREA and API_VALUE to given index
144  * return: NO_ERROR if successful, error code otherwise
145  * indexer(in): VALUE_INDEXER
146  * index(int): index of the item
147  * va(in): pointer to VALUE_AREA
148  * val(in): pointer to API_VALUE
149  */
150 static int
151 ai_api_set (VALUE_INDEXER * indexer, int index, VALUE_AREA * va, API_VALUE * val)
152 {
153  ARRAY_INDEXER *ai = (ARRAY_INDEXER *) indexer;
154  assert (ai != NULL);
155  ai->vs_map[index] = va;
156  ai->values[index] = val;
157  return NO_ERROR;
158 }
159 
160 /*
161  * ai_api_map - call mapf for each element in indexer in order
162  * return: NO_ERROR if successful, error code otherwise
163  * indexer(in): VALUE_INDEXER
164  * mapf(in): map function
165  * arg(in): argument of the mapf
166  */
167 static int
168 ai_api_map (VALUE_INDEXER * indexer, int (*mapf) (void *, int, VALUE_AREA *, API_VALUE *), void *arg)
169 {
170  ARRAY_INDEXER *ai = (ARRAY_INDEXER *) indexer;
171  int i, res;
172  assert (ai != NULL);
173  assert (mapf != NULL);
174  for (i = 0; i < ai->nvalue; i++)
175  {
176  res = mapf (arg, i, ai->vs_map[i], ai->values[i]);
177  if (res != NO_ERROR)
178  return res;
179  }
180  return NO_ERROR;
181 }
182 
183 /*
184  * ai_api_insert - insert a new element after given index position
185  * return: NO_ERROR if successful, error code otherwise
186  * indexer(in): VALUE_INDEXER
187  * index(in): index of element
188  * va(in): pointer to VALUE_AREA
189  * dval(in): pointer to API_VALUE
190  * NOTE
191  * To insert the element to the top front of position the indexer, index -1 is used.
192  */
193 static int
194 ai_api_insert (VALUE_INDEXER * indexer, int index, VALUE_AREA * va, API_VALUE * dval)
195 {
197 }
198 
199 /*
200  * ai_api_delete - delete existing element at the given position
201  * return: NO_ERROR if successful, error code otherwise
202  * indexer(in): VALUE_INDEXER
203  * index(in): index of the element
204  * rva(out): pointer to VALUE_AREA
205  * dbval(out): pointer to API_VALUE
206  */
207 static int
208 ai_api_delete (VALUE_INDEXER * indexer, int index, VALUE_AREA ** rva, API_VALUE ** dbval)
209 {
211 }
212 
213 /*
214  * ai_api_destroy -destroy value indexer
215  * return: void
216  * indexer(in): VALUE_INDEXER
217  * df(in): element destroy function
218  *
219  */
220 static void
221 ai_api_destroy (VALUE_INDEXER * indexer, void (*df) (VALUE_AREA * va, API_VALUE * db))
222 {
223  ARRAY_INDEXER *ai = (ARRAY_INDEXER *) indexer;
224  int i;
225 
226  assert (ai != NULL);
227 
228  if (df != NULL)
229  {
230  for (i = 0; i < ai->nvalue; i++)
231  {
232  df (ai->vs_map[i], ai->values[i]);
233  }
234  }
235  API_FREE (ai->vs_map);
236  API_FREE (ai->values);
237  API_FREE (ai);
238 }
239 
241  ai_api_check,
243  ai_api_get,
244  ai_api_set,
245  ai_api_map,
249 };
250 
251 
252 
253 /* ------------------------------------------------------------------------- */
254 /* linked list based VALUE_INDEXER implementation */
255 
256 /*
257  * li_api_check - check if the given index is valid for the CHECK_PURPOSE
258  * return: NO_ERROR if successful, error code otherwise
259  * indexer(in): VALUE_INDEXER
260  * index(in): index
261  * pup(in): CHECK_PURPOSE
262  */
263 static int
265 {
266  LIST_INDEXER *li = (LIST_INDEXER *) indexer;
267  int valid_index = 0;
268  assert (li != NULL);
269 
270  valid_index = index >= 0 && index < li->nelems;
271  if ((pup & CHECK_FOR_INSERT) && !valid_index && index == -1)
272  valid_index = 1;
273 
274  if (!valid_index)
275  return ER_INTERFACE_GENERIC;
276  else
277  return NO_ERROR;
278 }
279 
280 /*
281  * li_api_length - get number of elements in the indexer
282  * return: NO_ERROR if successful, error code otherwise
283  * indexer(in): VALUE_INDEXER
284  * len(out): number of elements
285  */
286 static int
287 li_api_length (VALUE_INDEXER * indexer, int *len)
288 {
289  LIST_INDEXER *li = (LIST_INDEXER *) indexer;
290  assert (li != NULL);
291  assert (len != NULL);
292  *len = li->nelems;
293  return NO_ERROR;
294 }
295 
296 /*
297  * li_getf - get element at the given index position
298  * return: NO_ERROR if successful, error code otherwise
299  * li(in): LIST_INDEXER instance
300  * index(in): index
301  * NOTE
302  * cache_idx and cache_elem is used and re-adjusted
303  */
304 static LIST_INDEXER_ELEM *
306 {
307  dlisth *h;
308  int ds, dc, de;
309  int i, inc;
310 
311  assert (li != NULL);
312  assert (index >= 0 && index < li->nelems);
313 
314  /* fast check */
315  if (index == li->cache_idx)
316  return li->cache_elem;
317  else if (index == 0)
318  {
319  li->cache_idx = index;
320  li->cache_elem = (LIST_INDEXER_ELEM *) (li->elems.next);
321  return li->cache_elem;
322  }
323  else if (index == li->nelems - 1)
324  {
325  li->cache_idx = index;
326  li->cache_elem = (LIST_INDEXER_ELEM *) (li->elems.prev);
327  return li->cache_elem;
328  }
329 
330  /* list traverse */
331  ds = index;
332  dc = index > li->cache_idx ? index - li->cache_idx : li->cache_idx - index;
333  de = li->nelems - index;
334  /*
335  * find the minimum element from {ds, dc, de} and
336  * calcuate the direction form the element to index
337  */
338  if (ds > dc)
339  {
340  if (de > dc)
341  {
342  i = li->cache_idx;
343  inc = index > li->cache_idx ? 1 : -1;
344  h = (dlisth *) li->cache_elem;
345  }
346  else
347  {
348  i = li->nelems - 1;
349  inc = -1;
350  h = li->elems.prev; /* last elem */
351  }
352  }
353  else
354  {
355  if (de > ds)
356  {
357  i = 0;
358  inc = 1;
359  h = li->elems.next; /* first elem */
360  }
361  else
362  {
363  i = li->nelems - 1;
364  inc = -1;
365  h = li->elems.prev;
366  }
367  }
368  assert (i > index ? inc == -1 : inc == 1);
369  while (i != index)
370  {
371  if (inc > 0)
372  h = h->next;
373  else
374  h = h->prev;
375  i += inc;
376  }
377 
378  assert (h != &li->elems);
379  li->cache_idx = index;
380  li->cache_elem = (LIST_INDEXER_ELEM *) h;
381  return (LIST_INDEXER_ELEM *) h;
382 }
383 
384 
385 /*
386  * li_api_get - get element
387  * return: NO_ERROR if successful, error code otherwise
388  * indexer(in): VALUE_INDEXER
389  * index(in): index of the item
390  * rva(out): VALUE_AREA
391  * rv(out): API_VALUE
392  */
393 static int
394 li_api_get (VALUE_INDEXER * indexer, int index, VALUE_AREA ** rva, API_VALUE ** rv)
395 {
396  LIST_INDEXER *li = (LIST_INDEXER *) indexer;
398 
399  assert (li != NULL);
400  assert (index >= 0 && index < li->nelems);
401  assert (rva != NULL);
402  assert (rv != NULL);
403 
404  e = li_getf (li, index);
405  assert (e != NULL);
406  *rva = e->va;
407  *rv = e->value;
408  return NO_ERROR;
409 }
410 
411 /*
412  * li_api_set - set VALUE_AREA and API_VALUE to given index
413  * return: NO_ERROR if successful, error code otherwise
414  * indexer(in): VALUE_INDEXER
415  * index(int): index of the item
416  * va(in): pointer to VALUE_AREA
417  * val(in): pointer to API_VALUE
418  */
419 static int
420 li_api_set (VALUE_INDEXER * indexer, int index, VALUE_AREA * va, API_VALUE * dval)
421 {
422  LIST_INDEXER *li = (LIST_INDEXER *) indexer;
424 
425  assert (li != NULL);
426  assert (index >= 0 && index < li->nelems);
427 
428  e = li_getf (li, index);
429  assert (e != NULL);
430  e->va = va;
431  e->value = dval;
432  return NO_ERROR;
433 }
434 
436 {
437  int (*mapf) (void *, int, VALUE_AREA *, API_VALUE *);
438  void *arg;
439  int index;
440 };
441 
442 /*
443  * li_mapf - this is a helper function of li_api_map (type is dlist_map_func)
444  * return: NO_ERROR if successful, error code otherwise
445  * h(h): dlisth
446  * arg(in): linked list element
447  * cont(out): continuation marker
448  */
449 static int
450 li_mapf (dlisth * h, void *arg, int *cont)
451 {
453  struct li_mapf_arg *ar = (struct li_mapf_arg *) arg;
454  int res;
455  assert (e != NULL);
456  assert (ar != NULL);
457  res = ar->mapf (ar->arg, ar->index, e->va, e->value);
458  if (res == NO_ERROR)
459  {
460  *cont = 1;
461  ar->index++;
462  return NO_ERROR;
463  }
464  *cont = 0;
465  return res;
466 }
467 
468 /*
469  * li_api_map - call mapf for each element in indexer in order
470  * return: NO_ERROR if successful, error code otherwise
471  * indexer(in): VALUE_INDEXER
472  * mapf(in): map function
473  * arg(in): argument of the mapf
474  */
475 static int
476 li_api_map (VALUE_INDEXER * indexer, int (*mapf) (void *, int, VALUE_AREA *, API_VALUE *), void *arg)
477 {
478  LIST_INDEXER *li = (LIST_INDEXER *) indexer;
479  struct li_mapf_arg ARG;
480  int res;
481 
482  assert (li != NULL);
483  assert (mapf != NULL);
484 
485  ARG.mapf = mapf;
486  ARG.arg = arg;
487  ARG.index = 0;
488  res = dlisth_map (&li->elems, li_mapf, &ARG);
489  return res;
490 }
491 
492 /*
493  * li_api_delete - delete existing element at the given position
494  * return: NO_ERROR if successful, error code otherwise
495  * indexer(in): VALUE_INDEXER
496  * index(in): index of the element
497  * rva(out): pointer to VALUE_AREA
498  * dbval(out): pointer to API_VALUE
499  */
500 static int
501 li_api_delete (VALUE_INDEXER * indexer, int index, VALUE_AREA ** rva, API_VALUE ** dbval)
502 {
503  LIST_INDEXER *li = (LIST_INDEXER *) indexer;
505 
506  assert (li != NULL);
507  assert (li->nelems > 0);
508  assert (index >= 0 && index < li->nelems);
509  assert (rva != NULL);
510  assert (dbval != NULL);
511 
512  assert (li->cache_idx >= 0 && li->cache_elem != NULL);
513  e = li_getf (li, index);
514  assert (e != NULL);
515 
516  *rva = e->va;
517  *dbval = e->value;
518  li->nelems--;
519  /* ajust cache */
520  if (li->nelems > 0)
521  {
522  if (index < li->cache_idx)
523  {
524  li->cache_idx--;
525  }
526  else if (index == li->cache_idx)
527  {
528  if (index > 0)
529  {
530  li->cache_idx = index - 1;
531  li->cache_elem = (LIST_INDEXER_ELEM *) (((dlisth *) e)->prev);
532  }
533  else
534  {
535  li->cache_elem = (LIST_INDEXER_ELEM *) (((dlisth *) e)->next);
536  }
537  }
538  }
539  else
540  {
541  li->cache_idx = -1;
542  li->cache_elem = NULL;
543  }
544  dlisth_delete ((dlisth *) e);
545  API_FREE (e);
546  return NO_ERROR;
547 }
548 
549 /*
550  * li_api_insert - insert a new element after given index position
551  * return: NO_ERROR if successful, error code otherwise
552  * indexer(in): VALUE_INDEXER
553  * index(in): index of element
554  * va(in): pointer to VALUE_AREA
555  * dval(in): pointer to API_VALUE
556  * NOTE
557  * To insert the element to the top front of position the indexer, index -1 is used.
558  */
559 static int
560 li_api_insert (VALUE_INDEXER * indexer, int index, VALUE_AREA * va, API_VALUE * dval)
561 {
562  LIST_INDEXER *li = (LIST_INDEXER *) indexer;
564  dlisth *h;
565 
566  assert (li != NULL);
567  assert (index >= -1 && index < li->nelems);
568 
569  e = API_MALLOC (sizeof (*e));
570  if (e == NULL)
572  dlisth_init (&e->header);
573  e->va = va;
574  e->value = dval;
575  if (index == -1)
576  h = &li->elems;
577  else
578  h = (dlisth *) li_getf (li, index);
579  assert (h != NULL);
580  dlisth_insert_after ((dlisth *) e, h);
581  li->nelems++;
582  /* ajust cache */
583  if (index == -1 && li->cache_idx == -1)
584  {
585  li->cache_idx = 0;
586  li->cache_elem = e;
587  }
588  else if (index < li->cache_idx)
589  {
590  li->cache_idx++;
591  }
592  return NO_ERROR;
593 }
594 
595 /*
596  * li_api_destroy - destroy value indexer
597  * return: void
598  * indexer(in): VALUE_INDEXER
599  * df(in): element destroy function
600  */
601 static void
602 li_api_destroy (VALUE_INDEXER * indexer, void (*df) (VALUE_AREA * va, API_VALUE * db))
603 {
604  LIST_INDEXER *li = (LIST_INDEXER *) indexer;
605 
606  assert (li != NULL);
607  while (!dlisth_is_empty (&li->elems))
608  {
610  if (df)
611  df (e->va, e->value);
612  dlisth_delete ((dlisth *) e);
613  API_FREE (e);
614  }
615  API_FREE (li);
616 }
617 
619  li_api_check,
621  li_api_get,
622  li_api_set,
623  li_api_map,
627 };
628 
629 /* ------------------------------------------------------------------------- */
630 /* EXPORTED FUNCTION */
631 
632 /*
633  * array_indexer_create - create a new array indexer
634  * return: NO_ERROR if successful, error code otherwise
635  * nvalue(in): number of elements in the indexer
636  * rvi(out): pointer to VALUE_INDEXER
637  * NOTE
638  * array value indexer has fixed elements of (NULL, NULL) VALUE_AREA and
639  * API_VALUE pair initially. insert() and delete() operation is not defined.
640  */
641 int
643 {
644  ARRAY_INDEXER *ai;
645 
646  assert (rvi != NULL);
647  assert (nvalue > 0);
648  ai = API_MALLOC (sizeof (*ai));
649  if (ai == NULL)
652  ai->nvalue = nvalue;
653  ai->vs_map = API_CALLOC (nvalue, sizeof (void *));
654  if (ai->vs_map == NULL)
655  {
656  API_FREE (ai);
658  }
659  ai->values = API_CALLOC (nvalue, sizeof (API_VALUE *));
660  if (ai->values == NULL)
661  {
662  API_FREE (ai->vs_map);
663  API_FREE (ai);
665  }
666  *rvi = (VALUE_INDEXER *) ai;
667  return NO_ERROR;
668 }
669 
670 /*
671  * list_indexer_create - create a new list based indexer
672  * return: NO_ERROR if successful, error code otherwise
673  * rvi(out): pointer to the VALUE_INDEXER
674  */
675 int
677 {
678  LIST_INDEXER *li;
679  assert (rvi != NULL);
680  li = API_MALLOC (sizeof (*li));
681  if (li == NULL)
684  li->nelems = 0;
685  dlisth_init (&li->elems);
686  li->cache_idx = -1;
687  li->cache_elem = NULL;
688  *rvi = (VALUE_INDEXER *) li;
689  return NO_ERROR;
690 }
dlisth * prev
Definition: api_util.h:34
#define dlisth_insert_after(ih, bh)
Definition: api_util.h:68
dlisth * next
Definition: api_util.h:33
#define NO_ERROR
Definition: error_code.h:46
static int ai_api_length(VALUE_INDEXER *indexer, int *len)
static VALUE_INDEXER_IFS LIST_INDEXER_IFS_
static int li_api_length(VALUE_INDEXER *indexer, int *len)
#define ER_INTERFACE_NOT_SUPPORTED_OPERATION
Definition: error_code.h:1177
VALUE_INDEXER indexer
#define API_CALLOC(n, s)
Definition: api_util.h:110
int(* mapf)(void *, int, VALUE_AREA *, API_VALUE *)
enum check_purpose_s CHECK_PURPOSE
static LIST_INDEXER_ELEM * li_getf(LIST_INDEXER *li, int index)
static int ai_api_delete(VALUE_INDEXER *indexer, int index, VALUE_AREA **rva, API_VALUE **dbval)
static int li_api_get(VALUE_INDEXER *indexer, int index, VALUE_AREA **rva, API_VALUE **rv)
VALUE_AREA ** vs_map
LIST_INDEXER_ELEM * cache_elem
static VALUE_INDEXER_IFS ARRAY_INDEXER_IFS_
int array_indexer_create(int nvalue, VALUE_INDEXER **rvi)
struct VALUE_AREA VALUE_AREA
Definition: api_common.h:42
#define assert(x)
static int ai_api_insert(VALUE_INDEXER *indexer, int index, VALUE_AREA *va, API_VALUE *dval)
#define ER_INTERFACE_GENERIC
Definition: error_code.h:1179
VALUE_INDEXER indexer
static int li_api_check(VALUE_INDEXER *indexer, int index, CHECK_PURPOSE pup)
#define dlisth_delete(h_)
Definition: api_util.h:50
static int rv
Definition: area_alloc.c:52
struct API_VALUE API_VALUE
Definition: api_common.h:43
static void ai_api_destroy(VALUE_INDEXER *indexer, void(*df)(VALUE_AREA *va, API_VALUE *db))
#define NULL
Definition: freelistheap.h:34
if(extra_options)
Definition: dynamic_load.c:958
#define API_FREE(p)
Definition: api_util.h:112
static int ai_api_set(VALUE_INDEXER *indexer, int index, VALUE_AREA *va, API_VALUE *dv)
int dlisth_map(dlisth *h, dlist_map_func func, void *arg)
Definition: api_util.c:138
static int ai_api_check(VALUE_INDEXER *indexer, int index, CHECK_PURPOSE pup)
static void li_api_destroy(VALUE_INDEXER *indexer, void(*df)(VALUE_AREA *va, API_VALUE *db))
static int li_api_insert(VALUE_INDEXER *indexer, int index, VALUE_AREA *va, API_VALUE *dval)
int list_indexer_create(VALUE_INDEXER **rvi)
static int li_api_map(VALUE_INDEXER *indexer, int(*mapf)(void *, int, VALUE_AREA *, API_VALUE *), void *arg)
static int li_api_delete(VALUE_INDEXER *indexer, int index, VALUE_AREA **rva, API_VALUE **dbval)
int i
Definition: dynamic_load.c:954
#define API_MALLOC(s)
Definition: api_util.h:111
#define dlisth_is_empty(h)
Definition: api_util.h:48
#define dlisth_init(h)
Definition: api_util.h:42
static int ai_api_map(VALUE_INDEXER *indexer, int(*mapf)(void *, int, VALUE_AREA *, API_VALUE *), void *arg)
static int li_mapf(dlisth *h, void *arg, int *cont)
VALUE_INDEXER_IFS * ifs
Definition: api_common.h:208
static int ai_api_get(VALUE_INDEXER *indexer, int index, VALUE_AREA **rva, API_VALUE **rv)
API_VALUE ** values
static int li_api_set(VALUE_INDEXER *indexer, int index, VALUE_AREA *va, API_VALUE *val)
#define ER_INTERFACE_NO_MORE_MEMORY
Definition: error_code.h:1198