/********************************************************************** * * Special case support for subsets * */ static int binary_search_for_start(netsnmp_index *val, netsnmp_container *c) { binary_array_table *t = (binary_array_table*)c->container_data; size_t len = t->count; size_t half; size_t middle; size_t first = 0; int result = 0; if (!len) return -1; if (t->dirty) Sort_Array(c); while (len > 0) { half = len >> 1; middle = first; middle += half; if ((result = c->ncompare(t->data[middle], val)) < 0) { first = middle; ++first; len = len - half - 1; } else len = half; } if ((first >= t->count) || c->ncompare(t->data[first], val) != 0) return -1; return first; }
int netsnmp_binary_array_remove(netsnmp_container *c, const void *key, void **save) { binary_array_table *t = (binary_array_table*)c->container_data; int index = 0; if (save) *save = NULL; /* * if there is no data, return NULL; */ if (!t->count) return 0; /* * if the table is dirty, sort it. */ if (t->dirty) Sort_Array(c); /* * search */ if ((index = binary_search(key, c, 1)) == -1) return -1; return netsnmp_binary_array_remove_at(c, (size_t)index, save); }
NETSNMP_STATIC_INLINE void * netsnmp_binary_array_get(netsnmp_container *c, const void *key, int exact) { binary_array_table *t = (binary_array_table*)c->container_data; int index = 0; /* * if there is no data, return NULL; */ if (!t->count) return NULL; /* * if the table is dirty, sort it. */ if (t->dirty) Sort_Array(c); /* * if there is a key, search. Otherwise default is 0; */ if (key) { if ((index = binary_search(key, c, exact)) == -1) return NULL; } return t->data[index]; }
NETSNMP_STATIC_INLINE void netsnmp_binary_array_for_each(netsnmp_container *c, netsnmp_container_obj_func *fe, void *context, int sort) { binary_array_table *t = (binary_array_table*)c->container_data; size_t i; if (sort && t->dirty) Sort_Array(c); for (i = 0; i < t->count; ++i) (*fe) (t->data[i], context); }
NETSNMP_STATIC_INLINE void * netsnmp_binary_array_get(netsnmp_container *c, const void *key, int exact) { binary_array_table *t = (binary_array_table*)c->container_data; int index = 0; /* * if there is no data, return NULL; */ if (!t->count) return NULL; /* * if the table is dirty, sort it. */ if (t->dirty) Sort_Array(c); /* * if there is a key, search. Otherwise default is 0; */ if (key) { if ((index = binary_search(key, c, exact)) == -1) return NULL; if (!exact && c->flags & CONTAINER_KEY_ALLOW_DUPLICATES) { int result; /* * If duplicates are allowed, we have to be extra * sure that we didn't just increment to a duplicate, * thus causing a getnext loop. */ result = c->compare(t->data[index], key); while (result == 0) { DEBUGMSGTL(("container","skipping duplicate key in %s\n", c->container_name)); if (++index == t->count) return NULL; result = c->compare(t->data[index], key); } } } return t->data[index]; }
static int _ba_iterator_reset(binary_array_iterator *it) { binary_array_table* t = _ba_it2cont(it); if(NULL == t) { netsnmp_assert(NULL != t); return -1; } if (t->dirty) Sort_Array(it->base.container); /* * save sync count, to make sure container doesn't change while * iterator is in use. */ it->base.sync = it->base.container->sync; it->pos = 0; return 0; }
static int binary_search(const void *val, netsnmp_container *c, int exact) { binary_array_table *t = (binary_array_table*)c->container_data; size_t len = t->count; size_t half; size_t middle = 0; size_t first = 0; int result = 0; if (!len) return -1; if (c->flags & CONTAINER_KEY_UNSORTED) { if (!exact) { snmp_log(LOG_ERR, "non-exact search on unsorted container %s?!?\n", c->container_name); return -1; } return linear_search(val, c); } if (t->dirty) Sort_Array(c); while (len > 0) { half = len >> 1; middle = first; middle += half; if ((result = c->compare(t->data[middle], val)) < 0) { first = middle; ++first; len = len - half - 1; } else { if(result == 0) { first = middle; break; } len = half; } } if (first >= t->count) return -1; if(first != middle) { /* last compare wasn't against first, so get actual result */ result = c->compare(t->data[first], val); } if(result == 0) { if (!exact) { if (++first == t->count) first = -1; } } else { if(exact) first = -1; } return first; }