Beispiel #1
0
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--;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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);
}
Beispiel #4
0
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();
}
Beispiel #5
0
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);
}
Beispiel #6
0
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;
}