/* * hash_destroy - destroy static hash table * return: void * ht(in): hash table * dtor(in): element destructor function */ void hash_destroy (hash_table * ht, ht_destroyf dtor) { int i; assert (ht != NULL); if (ht == NULL) return; for (i = 0; i < ht->bucket_sz; i++) { dlisth *h, *header; h = header = &ht->buckets[i].head; h = h->next; while (h != header) { ht_elem *hte = (ht_elem *) h; h = h->next; dlisth_delete ((dlisth *) hte); if (dtor) dtor (hte->elem); API_FREE (hte); } } API_FREE (ht); }
/* * or_destroy - * return: * or(): */ static void or_destroy (OBJECT_RESULTSET * or) { BIND_HANDLE res_h; int res; assert (or != NULL); assert (or->res_bind != NULL); assert (or->rm_bind != NULL); res = or->bh_ifs->bind_to_handle (or->bh_ifs, (BH_BIND *) or->res_bind, &res_h); assert (res == NO_ERROR); res = or->bh_ifs->destroy_handle (or->bh_ifs, res_h); assert (res == NO_ERROR); assert (or->res_bind == NULL); assert (or->rm_bind == NULL); if (or->attr_index != NULL) { API_FREE (or->attr_index); } if (or->vt != NULL) { or->vt->ifs->destroy (or->vt); } API_FREE (or); }
/* * array_indexer_create - create a new array indexer * return: NO_ERROR if successful, error code otherwise * nvalue(in): number of elements in the indexer * rvi(out): pointer to VALUE_INDEXER * NOTE * array value indexer has fixed elements of (NULL, NULL) VALUE_AREA and * API_VALUE pair initially. insert() and delete() operation is not defined. */ int array_indexer_create (int nvalue, VALUE_INDEXER ** rvi) { ARRAY_INDEXER *ai; assert (rvi != NULL); assert (nvalue > 0); ai = API_MALLOC (sizeof (*ai)); if (ai == NULL) return ER_INTERFACE_NO_MORE_MEMORY; ai->indexer.ifs = &ARRAY_INDEXER_IFS_; ai->nvalue = nvalue; ai->vs_map = API_CALLOC (nvalue, sizeof (void *)); if (ai->vs_map == NULL) { API_FREE (ai); return ER_INTERFACE_NO_MORE_MEMORY; } ai->values = API_CALLOC (nvalue, sizeof (API_VALUE *)); if (ai->values == NULL) { API_FREE (ai->vs_map); API_FREE (ai); return ER_INTERFACE_NO_MORE_MEMORY; } *rvi = (VALUE_INDEXER *) ai; return NO_ERROR; }
/* * li_api_destroy - destroy value indexer * return: void * indexer(in): VALUE_INDEXER * df(in): element destroy function */ static void li_api_destroy (VALUE_INDEXER * indexer, void (*df) (VALUE_AREA * va, API_VALUE * db)) { LIST_INDEXER *li = (LIST_INDEXER *) indexer; assert (li != NULL); while (!dlisth_is_empty (&li->elems)) { LIST_INDEXER_ELEM *e = (LIST_INDEXER_ELEM *) li->elems.next; if (df) df (e->va, e->value); dlisth_delete ((dlisth *) e); API_FREE (e); } API_FREE (li); }
/* * orp_api_destroy - * return: * pool(): */ static void orp_api_destroy (API_OBJECT_RESULTSET_POOL * pool) { OBJECT_RESULTSET_POOL *p; assert (pool != NULL); p = (OBJECT_RESULTSET_POOL *) pool; hash_destroy (p->ht, NULL); API_FREE (p); }
/* * ai_api_destroy -destroy value indexer * return: void * indexer(in): VALUE_INDEXER * df(in): element destroy function * */ static void ai_api_destroy (VALUE_INDEXER * indexer, void (*df) (VALUE_AREA * va, API_VALUE * db)) { ARRAY_INDEXER *ai = (ARRAY_INDEXER *) indexer; int i; assert (ai != NULL); if (df != NULL) { for (i = 0; i < ai->nvalue; i++) { df (ai->vs_map[i], ai->values[i]); } } API_FREE (ai->vs_map); API_FREE (ai->values); API_FREE (ai); }
/* * li_api_delete - delete existing element at the given position * return: NO_ERROR if successful, error code otherwise * indexer(in): VALUE_INDEXER * index(in): index of the element * rva(out): pointer to VALUE_AREA * dbval(out): pointer to API_VALUE */ static int li_api_delete (VALUE_INDEXER * indexer, int index, VALUE_AREA ** rva, API_VALUE ** dbval) { LIST_INDEXER *li = (LIST_INDEXER *) indexer; LIST_INDEXER_ELEM *e; assert (li != NULL); assert (li->nelems > 0); assert (index >= 0 && index < li->nelems); assert (rva != NULL); assert (dbval != NULL); assert (li->cache_idx >= 0 && li->cache_elem != NULL); e = li_getf (li, index); assert (e != NULL); *rva = e->va; *dbval = e->value; li->nelems--; /* ajust cache */ if (li->nelems > 0) { if (index < li->cache_idx) { li->cache_idx--; } else if (index == li->cache_idx) { if (index > 0) { li->cache_idx = index - 1; li->cache_elem = (LIST_INDEXER_ELEM *) (((dlisth *) e)->prev); } else { li->cache_elem = (LIST_INDEXER_ELEM *) (((dlisth *) e)->next); } } } else { li->cache_idx = -1; li->cache_elem = NULL; } dlisth_delete ((dlisth *) e); API_FREE (e); return NO_ERROR; }
/* * hash_delete - delete hash entry from hash table and return element found * return: NO_ERROR if successful, error_code otherwise * ht(in): hash table * key(in): pointer to the key * relem(out): element found, or set to NULL * * NOTE * When element is not found then NO_ERROR returned with NULL relem value */ int hash_delete (hash_table * ht, void *key, void **relem) { int rc; unsigned int hcode; dlisth *h, *header; assert (ht != NULL); assert (relem != NULL); *relem = NULL; rc = ht->hashf (key, &hcode); if (rc != NO_ERROR) return rc; hcode = hcode % ht->bucket_sz; header = &ht->buckets[(size_t) hcode].head; for (h = header->next; h != header; h = h->next) { int r; ht_elem *hte = (ht_elem *) h; void *ekey; if ((rc = ht->keyf (hte->elem, &ekey)) != NO_ERROR) return rc; if ((rc = ht->comparef (key, ekey, &r)) == NO_ERROR && r == 0) { *relem = hte->elem; dlisth_delete (h); API_FREE (hte); return NO_ERROR; } else if (rc != NO_ERROR) return rc; } return NO_ERROR; }
/* * api_object_resultset_pool_create - * return: * ifs(): * conn(): * rpool(): */ int api_object_resultset_pool_create (BH_INTERFACE * ifs, BIND_HANDLE conn, API_OBJECT_RESULTSET_POOL ** rpool) { OBJECT_RESULTSET_POOL *pool; hash_table *ht; int res; assert (ifs != NULL); assert (rpool != NULL); pool = API_MALLOC (sizeof (*pool)); if (pool == NULL) { return ER_INTERFACE_NO_MORE_MEMORY; } ht = NULL; res = hash_new (64, orp_ht_hashf, orp_ht_keyf, orp_ht_comparef, &ht); if (res != NO_ERROR) { API_FREE (pool); return ER_INTERFACE_NO_MORE_MEMORY; } pool->pool.destroy = orp_api_destroy; pool->pool.oid_delete = orp_oid_delete; pool->pool.oid_get_classname = orp_oid_get_classname; pool->pool.get_object_resultset = orp_api_get_object_resultset; pool->bh_ifs = ifs; pool->conn = conn; pool->ht = ht; *rpool = (API_OBJECT_RESULTSET_POOL *) pool; return NO_ERROR; }
/* * or_create - * return: * oid(): * conn(): * bh_ifs(): * ror(): */ static int or_create (OID * oid, BIND_HANDLE conn, BH_INTERFACE * bh_ifs, OBJECT_RESULTSET ** ror) { OBJECT_RESULTSET *or; int res = NO_ERROR; BIND_HANDLE res_h, rm_h; assert (oid != NULL); assert (ror != NULL); /* create structure */ or = API_CALLOC (1, sizeof (*or)); if (or == NULL) { return ER_INTERFACE_NO_MORE_MEMORY; } or->oid = *oid; or->bh_ifs = bh_ifs; res = or_res_bind_create (or, &or->res_bind); if (res != NO_ERROR) { API_FREE (or); return res; } res = or_rm_bind_create (or, &or->rm_bind); if (res != NO_ERROR) { or_res_bind_destroy (or->res_bind); API_FREE (or); return res; } /* realize handles and setup dependency between them */ res = bh_ifs->alloc_handle (bh_ifs, (BH_BIND *) or->res_bind, &res_h); if (res != NO_ERROR) { or_res_bind_destroy (or->res_bind); or_rm_bind_destroy (or->rm_bind); API_FREE (or); return res; } res = bh_ifs->alloc_handle (bh_ifs, (BH_BIND *) or->rm_bind, &rm_h); if (res != NO_ERROR) { bh_ifs->destroy_handle (bh_ifs, res_h); or_rm_bind_destroy (or->rm_bind); API_FREE (or); return res; } res = bh_ifs->bind_graft (bh_ifs, (BH_BIND *) or->rm_bind, (BH_BIND *) or->res_bind); if (res != NO_ERROR) { bh_ifs->destroy_handle (bh_ifs, res_h); bh_ifs->destroy_handle (bh_ifs, rm_h); API_FREE (or); return res; } or->obj = db_object (oid); if (or->obj == NULL) { or_destroy (or); return ER_INTERFACE_GENERIC; } or->clz = db_get_class (or->obj); if (or->clz == NULL) { or_destroy (or); return ER_INTERFACE_GENERIC; } /* create object value bind table */ do { int i = 0; DB_ATTRIBUTE *attrs; or->deleted = 0; attrs = db_get_attributes (or->obj); if (attrs == NULL) { or_destroy (or); return ER_INTERFACE_GENERIC; } or->attrs = attrs; while (attrs) { i++; attrs = db_attribute_next (attrs); } or->nattrs = i; or->attr_index = API_CALLOC (i, sizeof (DB_ATTRIBUTE *)); if (or->attr_index == NULL) { or_destroy (or); return ER_INTERFACE_NO_MORE_MEMORY; } attrs = or->attrs; i = 0; while (attrs) { or->attr_index[i] = attrs; attrs = db_attribute_next (attrs); i++; } or->conn = conn; res = create_db_value_bind_table (i, or, 0, conn, vt_api_get_index_by_name, vt_api_get_db_value, vt_api_set_db_value, vt_api_init_domain, &or->vt); if (res != NO_ERROR) { or_destroy (or); return res; } } while (0); *ror = or; return NO_ERROR; }
/* * or_res_bind_destroy - * return: * res_bind(): */ static void or_res_bind_destroy (OBJECT_RES_BIND * res_bind) { assert (res_bind != NULL); API_FREE (res_bind); }
/* * or_rm_bind_destroy - * return: * rm_bind(): */ static void or_rm_bind_destroy (OBJECT_RM_BIND * rm_bind) { assert (rm_bind != NULL); API_FREE (rm_bind); }