示例#1
0
static PyObject *
bucket_toString(PyObject *oself)
{
  Bucket *self = (Bucket *)oself;
  PyObject *items = NULL;
  int len;

  PER_USE_OR_RETURN(self, NULL);

  len = self->len;

  items = PyString_FromStringAndSize(NULL, len*8);
  if (items == NULL)
    goto err;
  memcpy(PyString_AS_STRING(items),       self->keys,   len*2);
  memcpy(PyString_AS_STRING(items)+len*2, self->values, len*6);
  
  PER_UNUSE(self);
  return items;
  
 err:
  PER_UNUSE(self);
  Py_XDECREF(items);
  return NULL;
}
示例#2
0
static Py_ssize_t
BTreeItems_length_or_nonzero(BTreeItems *self, int nonzero)
{
    Py_ssize_t r;
    Bucket *b, *next;

    b = self->firstbucket;
    if (b == NULL)
	return 0;

    r = self->last + 1 - self->first;

    if (nonzero && r > 0)
	/* Short-circuit if all we care about is nonempty */
	return 1;

    if (b == self->lastbucket)
	return r;

    Py_INCREF(b);
    PER_USE_OR_RETURN(b, -1);
    while ((next = b->next)) {
	r += b->len;
	if (nonzero && r > 0)
	    /* Short-circuit if all we care about is nonempty */
	    break;

	if (next == self->lastbucket)
	    break; /* we already counted the last bucket */

	Py_INCREF(next);
	PER_UNUSE(b);
	Py_DECREF(b);
	b = next;
	PER_USE_OR_RETURN(b, -1);
    }
    PER_UNUSE(b);
    Py_DECREF(b);

    return r >= 0 ? r : 0;
}
示例#3
0
/*
** BTreeItems_item
**
** Arguments:	self	a BTreeItems structure
**		i	Which item to inspect
**
** Returns:	the BTreeItems_item_BTree of self->kind, i
**		(ie pulls the ith item out)
*/
static PyObject *
BTreeItems_item(BTreeItems *self, Py_ssize_t i)
{
    PyObject *result;

    if (BTreeItems_seek(self, i) < 0) return NULL;

    PER_USE_OR_RETURN(self->currentbucket, NULL);
    result = getBucketEntry(self->currentbucket, self->currentoffset,
                            self->kind);
    PER_UNUSE(self->currentbucket);
    return result;
}
示例#4
0
static PyObject *
TreeSet_setstate(BTree *self, PyObject *args)
{
  int r;

  if (!PyArg_ParseTuple(args,"O",&args)) return NULL;

  PER_PREVENT_DEACTIVATION(self);
  r=_BTree_setstate(self, args, 1);
  PER_UNUSE(self);

  if (r < 0) return NULL;
  Py_INCREF(Py_None);
  return Py_None;
}
示例#5
0
static int
nextBTreeItems(SetIteration *i)
{
  if (i->position >= 0)
    {
      if (i->position)
        {
          DECREF_KEY(i->key);
          DECREF_VALUE(i->value);
        }

      if (BTreeItems_seek(ITEMS(i->set), i->position) >= 0)
        {
          Bucket *currentbucket;

          currentbucket = BUCKET(ITEMS(i->set)->currentbucket);
          UNLESS(PER_USE(currentbucket))
            {
              /* Mark iteration terminated, so that finiSetIteration doesn't
               * try to redundantly decref the key and value
               */
              i->position = -1;
              return -1;
            }

          COPY_KEY(i->key, currentbucket->keys[ITEMS(i->set)->currentoffset]);
          INCREF_KEY(i->key);

          COPY_VALUE(i->value,
                     currentbucket->values[ITEMS(i->set)->currentoffset]);
          INCREF_VALUE(i->value);

          i->position ++;

          PER_UNUSE(currentbucket);
        }
      else
        {
示例#6
0
/*
** BTreeItems_seek
**
** Find the ith position in the BTreeItems.
**
** Arguments:  	self	The BTree
**		i	the index to seek to, in 0 .. len(self)-1, or in
**                      -len(self) .. -1, as for indexing a Python sequence.
**
**
** Returns 0 if successful, -1 on failure to seek (like out-of-bounds).
** Upon successful return, index i is at offset self->currentoffset in bucket
** self->currentbucket.
*/
static int
BTreeItems_seek(BTreeItems *self, Py_ssize_t i)
{
    int delta, pseudoindex, currentoffset;
    Bucket *b, *currentbucket;
    int error;

    pseudoindex = self->pseudoindex;
    currentoffset = self->currentoffset;
    currentbucket = self->currentbucket;
    if (currentbucket == NULL) goto no_match;

    delta = i - pseudoindex;
    while (delta > 0) {         /* move right */
        int max;
        /* Want to move right delta positions; the most we can move right in
         * this bucket is currentbucket->len - currentoffset - 1 positions.
         */
        PER_USE_OR_RETURN(currentbucket, -1);
        max = currentbucket->len - currentoffset - 1;
        b = currentbucket->next;
        PER_UNUSE(currentbucket);
        if (delta <= max) {
            currentoffset += delta;
            pseudoindex += delta;
            if (currentbucket == self->lastbucket
                && currentoffset > self->last) goto no_match;
            break;
        }
        /* Move to start of next bucket. */
        if (currentbucket == self->lastbucket || b == NULL) goto no_match;
        currentbucket = b;
        pseudoindex += max + 1;
        delta -= max + 1;
        currentoffset = 0;
    }
    while (delta < 0) {         /* move left */
        int status;
        /* Want to move left -delta positions; the most we can move left in
         * this bucket is currentoffset positions.
         */
        if ((-delta) <= currentoffset) {
            currentoffset += delta;
            pseudoindex += delta;
            if (currentbucket == self->firstbucket
                && currentoffset < self->first) goto no_match;
            break;
        }
        /* Move to end of previous bucket. */
        if (currentbucket == self->firstbucket) goto no_match;
        status = PreviousBucket(&currentbucket, self->firstbucket);
        if (status == 0)
            goto no_match;
        else if (status < 0)
            return -1;
        pseudoindex -= currentoffset + 1;
        delta += currentoffset + 1;
        PER_USE_OR_RETURN(currentbucket, -1);
        currentoffset = currentbucket->len - 1;
        PER_UNUSE(currentbucket);
    }

    assert(pseudoindex == i);

    /* Alas, the user may have mutated the bucket since the last time we
     * were called, and if they deleted stuff, we may be pointing into
     * trash memory now.
     */
    PER_USE_OR_RETURN(currentbucket, -1);
    error = currentoffset < 0 || currentoffset >= currentbucket->len;
    PER_UNUSE(currentbucket);
    if (error) {
	PyErr_SetString(PyExc_RuntimeError,
	                "the bucket being iterated changed size");
	return -1;
    }

    Py_INCREF(currentbucket);
    Py_DECREF(self->currentbucket);
    self->currentbucket = currentbucket;
    self->currentoffset = currentoffset;
    self->pseudoindex = pseudoindex;
    return 0;

no_match:
    IndexError(i);
    return -1;
}