예제 #1
0
/* Return the right kind ('k','v','i') of entry from bucket b at offset i.
 *  b must be activated.  Returns NULL on error.
 */
static PyObject *
getBucketEntry(Bucket *b, int i, char kind)
{
    PyObject *result = NULL;

    assert(b);
    assert(0 <= i && i < b->len);

    switch (kind) {

        case 'k':
            COPY_KEY_TO_OBJECT(result, b->keys[i]);
            break;

        case 'v':
            COPY_VALUE_TO_OBJECT(result, b->values[i]);
            break;

        case 'i': {
            PyObject *key;
            PyObject *value;;

            COPY_KEY_TO_OBJECT(key, b->keys[i]);
            if (!key) break;

            COPY_VALUE_TO_OBJECT(value, b->values[i]);
            if (!value) {
                Py_DECREF(key);
                break;
            }

            result = PyTuple_New(2);
            if (result) {
                PyTuple_SET_ITEM(result, 0, key);
                PyTuple_SET_ITEM(result, 1, value);
            }
            else {
                Py_DECREF(key);
                Py_DECREF(value);
            }
            break;
        }

        default:
            PyErr_SetString(PyExc_AssertionError,
                            "getBucketEntry: unknown kind");
            break;
    }
    return result;
}
예제 #2
0
/*
** _bucket_get
**
** Search a bucket for a given key.
**
** Arguments
**     self	The bucket
**     keyarg	The key to look for
**     has_key	Boolean; if true, return a true/false result; else return
**              the value associated with the key.
**
** Return
**     If has_key:
**         Returns the Python int 0 if the key is absent, else returns
**         has_key itself as a Python int.  A BTree caller generally passes
**         the depth of the bucket for has_key, so a true result returns
**         the bucket depth then.
**         Note that has_key should be tree when searching set buckets.
**     If not has_key:
**         If the key is present, returns the associated value, and the
**         caller owns the reference.  Else returns NULL and sets KeyError.
**     Whether or not has_key:
**         If a comparison sets an exception, returns NULL.
*/
static PyObject *
_bucket_get(Bucket *self, PyObject *keyarg, int has_key)
{
    int i, cmp;
    KEY_TYPE key;
    PyObject *r = NULL;
    int copied = 1;

    COPY_KEY_FROM_ARG(key, keyarg, copied);
    UNLESS (copied) return NULL;

    PER_USE_OR_RETURN(self, NULL);

    BUCKET_SEARCH(i, cmp, self, key, goto Done);
    if (has_key)
    	r = PyInt_FromLong(cmp ? 0 : has_key);
    else {
        if (cmp == 0) {
            COPY_VALUE_TO_OBJECT(r, self->values[i]);
        }
        else
            PyErr_SetObject(PyExc_KeyError, keyarg);
    }

Done:
  PER_ALLOW_DEACTIVATION(self);
  PER_ACCESSED(self);
  return r;
}