void skiplist_delete(struct skiplist *list,char* data) { int i; struct skipnode *update[MAXLEVEL+1], *x; x = list->hdr; for (i = list->level; i >= 0; i--) { while (x->forward[i] != NIL && cmp_lt(x->forward[i]->key, data)) x = x->forward[i]; update[i] = x; } x = x->forward[0]; if (x == NIL || !cmp_eq(x->key, data)) return; for (i = 0; i <= list->level; i++) { if (update[i]->forward[i] != x) break; update[i]->forward[i] = x->forward[i]; } free (x); while ((list->level > 0) && (list->hdr->forward[list->level] == NIL)) list->level--; }
static VALUE cmp_between(VALUE x, VALUE min, VALUE max) { if (RTEST(cmp_lt(x, min))) return Qfalse; if (RTEST(cmp_gt(x, max))) return Qfalse; return Qtrue; }
static mrb_value cmp_lt_m(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_get_args(mrb, "o", &y); return cmp_lt(mrb, x, y); }
static mrb_value cmp_between(mrb_state *mrb, mrb_value x) { mrb_value min, max; mrb_get_args(mrb, "oo", &min, &max); if (mrb_test(cmp_lt(mrb, x, min))) return mrb_false_value(); if (mrb_test(cmp_gt(mrb, x, max))) return mrb_false_value(); return mrb_true_value(); }
int skiplist_insert(struct skiplist *list,struct slice *sk,UINT val,OPT opt) { int i, new_level; struct skipnode *update[MAXLEVEL+1]; struct skipnode *x; char *key=sk->data; if(!skiplist_notfull(list)) return 0; x = list->hdr; for (i = list->level; i >= 0; i--) { while (x->forward[i] != NIL && cmp_lt(x->forward[i]->key, key)) x = x->forward[i]; update[i] = x; } x = x->forward[0]; if (x != NIL && cmp_eq(x->key, key)){ x->val = val; x->opt = opt; return(1); } for (new_level = 0; rand() < RAND_MAX/2 && new_level < MAXLEVEL; new_level++); if (new_level > list->level) { for (i = list->level + 1; i <= new_level; i++) update[i] = NIL; list->level = new_level; } if ((x =pool_alloc(list,sizeof(struct skipnode) + new_level*sizeof(struct skipnode *))) == 0) __DEBUG("%s","memory *ERROR*"); memcpy(x->key,key,sk->len); x->val=val; x->opt=opt; for (i = 0; i <= new_level; i++) { x->forward[i] = update[i]->forward[i]; update[i]->forward[i] = x; } list->count++; return(1); }
struct skipnode *skiplist_lookup(struct skiplist *list,char* data) { int i; struct skipnode *x = list->hdr; for (i = list->level; i >= 0; i--) { while (x->forward[i] != NIL && cmp_lt(x->forward[i]->key, data)) x = x->forward[i]; } x = x->forward[0]; if (x != NIL && cmp_eq(x->key, data)) return (x); return NULL; }
static int _siftup(PyListObject *heap, Py_ssize_t pos) { Py_ssize_t startpos, endpos, childpos, rightpos; int cmp; PyObject *newitem, *tmp; assert(PyList_Check(heap)); endpos = PyList_GET_SIZE(heap); startpos = pos; if (pos >= endpos) { PyErr_SetString(PyExc_IndexError, "index out of range"); return -1; } newitem = PyList_GET_ITEM(heap, pos); Py_INCREF(newitem); /* Bubble up the smaller child until hitting a leaf. */ childpos = 2*pos + 1; /* leftmost child position */ while (childpos < endpos) { /* Set childpos to index of smaller child. */ rightpos = childpos + 1; if (rightpos < endpos) { cmp = cmp_lt( PyList_GET_ITEM(heap, childpos), PyList_GET_ITEM(heap, rightpos)); if (cmp == -1) { Py_DECREF(newitem); return -1; } if (cmp == 0) childpos = rightpos; } /* Move the smaller child up. */ tmp = PyList_GET_ITEM(heap, childpos); Py_INCREF(tmp); Py_DECREF(PyList_GET_ITEM(heap, pos)); PyList_SET_ITEM(heap, pos, tmp); pos = childpos; childpos = 2*pos + 1; } /* The leaf at pos is empty now. Put newitem there, and and bubble it up to its final resting place (by sifting its parents down). */ Py_DECREF(PyList_GET_ITEM(heap, pos)); PyList_SET_ITEM(heap, pos, newitem); return _siftdown(heap, startpos, pos); }
static int _siftup(PyListObject *heap, Py_ssize_t pos) { Py_ssize_t startpos, endpos, childpos, rightpos, limit; PyObject *tmp1, *tmp2; int cmp; assert(PyList_Check(heap)); endpos = PyList_GET_SIZE(heap); startpos = pos; if (pos >= endpos) { PyErr_SetString(PyExc_IndexError, "index out of range"); return -1; } /* Bubble up the smaller child until hitting a leaf. */ limit = endpos / 2; /* smallest pos that has no child */ while (pos < limit) { /* Set childpos to index of smaller child. */ childpos = 2*pos + 1; /* leftmost child position */ rightpos = childpos + 1; if (rightpos < endpos) { cmp = cmp_lt( PyList_GET_ITEM(heap, childpos), PyList_GET_ITEM(heap, rightpos)); if (cmp == -1) return -1; if (cmp == 0) childpos = rightpos; if (endpos != PyList_GET_SIZE(heap)) { PyErr_SetString(PyExc_RuntimeError, "list changed size during iteration"); return -1; } } /* Move the smaller child up. */ tmp1 = PyList_GET_ITEM(heap, childpos); tmp2 = PyList_GET_ITEM(heap, pos); PyList_SET_ITEM(heap, childpos, tmp2); PyList_SET_ITEM(heap, pos, tmp1); pos = childpos; } /* Bubble it up to its final resting place (by sifting its parents down). */ return _siftdown(heap, startpos, pos); }
static int _siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) { PyObject *newitem, *parent; Py_ssize_t parentpos, size; int cmp; assert(PyList_Check(heap)); size = PyList_GET_SIZE(heap); if (pos >= size) { PyErr_SetString(PyExc_IndexError, "index out of range"); return -1; } /* Follow the path to the root, moving parents down until finding a place newitem fits. */ newitem = PyList_GET_ITEM(heap, pos); while (pos > startpos) { parentpos = (pos - 1) >> 1; parent = PyList_GET_ITEM(heap, parentpos); cmp = cmp_lt(newitem, parent); if (cmp == -1) return -1; if (size != PyList_GET_SIZE(heap)) { PyErr_SetString(PyExc_RuntimeError, "list changed size during iteration"); return -1; } if (cmp == 0) break; parent = PyList_GET_ITEM(heap, parentpos); newitem = PyList_GET_ITEM(heap, pos); PyList_SET_ITEM(heap, parentpos, newitem); PyList_SET_ITEM(heap, pos, parent); pos = parentpos; } return 0; }
static int _siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) { PyObject *newitem, *parent; int cmp; Py_ssize_t parentpos; assert(PyList_Check(heap)); if (pos >= PyList_GET_SIZE(heap)) { PyErr_SetString(PyExc_IndexError, "index out of range"); return -1; } newitem = PyList_GET_ITEM(heap, pos); Py_INCREF(newitem); /* Follow the path to the root, moving parents down until finding a place newitem fits. */ while (pos > startpos){ parentpos = (pos - 1) >> 1; parent = PyList_GET_ITEM(heap, parentpos); cmp = cmp_lt(newitem, parent); if (cmp == -1) { Py_DECREF(newitem); return -1; } if (cmp == 0) break; Py_INCREF(parent); Py_DECREF(PyList_GET_ITEM(heap, pos)); PyList_SET_ITEM(heap, pos, parent); pos = parentpos; } Py_DECREF(PyList_GET_ITEM(heap, pos)); PyList_SET_ITEM(heap, pos, newitem); return 0; }
static PyObject * nsmallest(PyObject *self, PyObject *args) { PyObject *heap=NULL, *elem, *iterable, *los, *it, *oldelem; Py_ssize_t i, n; int cmp; if (!PyArg_ParseTuple(args, "nO:nsmallest", &n, &iterable)) return NULL; it = PyObject_GetIter(iterable); if (it == NULL) return NULL; heap = PyList_New(0); if (heap == NULL) goto fail; for (i=0 ; i<n ; i++ ){ elem = PyIter_Next(it); if (elem == NULL) { if (PyErr_Occurred()) goto fail; else goto sortit; } if (PyList_Append(heap, elem) == -1) { Py_DECREF(elem); goto fail; } Py_DECREF(elem); } n = PyList_GET_SIZE(heap); if (n == 0) goto sortit; for (i=n/2-1 ; i>=0 ; i--) if(_siftupmax((PyListObject *)heap, i) == -1) goto fail; los = PyList_GET_ITEM(heap, 0); while (1) { elem = PyIter_Next(it); if (elem == NULL) { if (PyErr_Occurred()) goto fail; else goto sortit; } cmp = cmp_lt(elem, los); if (cmp == -1) { Py_DECREF(elem); goto fail; } if (cmp == 0) { Py_DECREF(elem); continue; } oldelem = PyList_GET_ITEM(heap, 0); PyList_SET_ITEM(heap, 0, elem); Py_DECREF(oldelem); if (_siftupmax((PyListObject *)heap, 0) == -1) goto fail; los = PyList_GET_ITEM(heap, 0); } sortit: if (PyList_Sort(heap) == -1) goto fail; Py_DECREF(it); return heap; fail: Py_DECREF(it); Py_XDECREF(heap); return NULL; }