/* Search for the bucket immediately preceding *current, in the bucket chain
 * starting at first.  current, *current and first must not be NULL.
 *
 * Return:
 *     1    *current holds the correct bucket; this is a borrowed reference
 *     0    no such bucket exists; *current unaltered
 *    -1    error; *current unaltered
 */
static int
PreviousBucket(Bucket **current, Bucket *first)
{
    Bucket *trailing = NULL;    /* first travels; trailing follows it */
    int result = 0;

    assert(current && *current && first);
    if (first == *current)
        return 0;

    do {
        trailing = first;
	PER_USE_OR_RETURN(first, -1);
        first = first->next;

    	((trailing)->state==cPersistent_STICKY_STATE
     	&&
     	((trailing)->state=cPersistent_UPTODATE_STATE));

    	PER_ACCESSED(trailing);

	if (first == *current) {
	    *current = trailing;
	    result = 1;
	    break;
	}
    } while (first);

    return result;
}
/*
** _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;
}
/* Search for the bucket immediately preceding *current, in the bucket chain
 * starting at first.  current, *current and first must not be NULL.
 *
 * Return:
 *     1    *current holds the correct bucket; this is a borrowed reference
 *     0    no such bucket exists; *current unaltered
 *    -1    error; *current unaltered
 */
static int
PreviousBucket(Bucket **current, Bucket *first)
{
    Bucket *trailing = NULL;    /* first travels; trailing follows it */
    int result = 0;

    assert(current && *current && first);
    if (first == *current)
        return 0;

    do {
        trailing = first;
	PER_USE_OR_RETURN(first, -1);
        first = first->next;
        PER_ALLOW_DEACTIVATION(trailing);
	PER_ACCESSED(trailing);

	if (first == *current) {
	    *current = trailing;
	    result = 1;
	    break;
	}
    } while (first);

    return result;
}