Commit ef3e0f10 authored by Jim Fulton's avatar Jim Fulton

Added toString and fromString methods to fsBuckets as a faster

alternative to __getstate__ and __setstate__.

Also made it possible to add extra bucket methods.
parent 3806eaff
......@@ -1582,6 +1582,10 @@ static struct PyMethodDef Bucket_methods[] = {
{"iteritems", (PyCFunction) Bucket_iteritems, METH_KEYWORDS,
"B.iteritems([min[,max]]) -> an iterator over the (key, value) items of B"},
#ifdef EXTRA_BUCKET_METHODS
EXTRA_BUCKET_METHODS
#endif
#ifdef PERSISTENT
{"_p_resolveConflict", (PyCFunction) bucket__p_resolveConflict,
METH_VARARGS,
......
......@@ -67,4 +67,88 @@ typedef unsigned char char6[6];
(STATUS)=0; }
#define NORMALIZE_VALUE(V, MIN)
#include "Python.h"
static PyObject *bucket_toString(PyObject *self);
static PyObject *bucket_fromString(PyObject *self, PyObject *state);
#define EXTRA_BUCKET_METHODS \
{"toString", (PyCFunction) bucket_toString, METH_NOARGS, \
"toString() -- Return the state as a string"}, \
{"fromString", (PyCFunction) bucket_fromString, METH_O, \
"fromString(s) -- Set the state of the object from a string"}, \
#include "BTreeModuleTemplate.c"
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;
}
static PyObject *
bucket_fromString(PyObject *oself, PyObject *state)
{
Bucket *self = (Bucket *)oself;
int len;
KEY_TYPE *keys;
VALUE_TYPE *values;
len = PyString_Size(state);
if (len < 0)
return NULL;
if (len%8)
{
PyErr_SetString(PyExc_ValueError, "state string of wrong size");
return NULL;
}
len /= 8;
if (self->next) {
Py_DECREF(self->next);
self->next = NULL;
}
if (len > self->size) {
keys = BTree_Realloc(self->keys, sizeof(KEY_TYPE)*len);
if (keys == NULL)
return NULL;
values = BTree_Realloc(self->values, sizeof(VALUE_TYPE)*len);
if (values == NULL)
return NULL;
self->keys = keys;
self->values = values;
self->size = len;
}
memcpy(self->keys, PyString_AS_STRING(state), len*2);
memcpy(self->values, PyString_AS_STRING(state)+len*2, len*6);
self->len = len;
Py_INCREF(self);
return (PyObject *)self;
}
##############################################################################
#
# Copyright (c) 2010 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
import unittest
from zope.testing import doctest
def test_fsbucket_string_conversion():
"""
fsBuckets have toString and fromString methods that can be used to
get and set their state very efficiently:
>>> from BTrees.fsBTree import fsBucket
>>> b = fsBucket([(c*2, c*6) for c in 'abcdef'])
>>> import pprint
>>> b.toString()
'aabbccddeeffaaaaaabbbbbbccccccddddddeeeeeeffffff'
>>> b2 = fsBucket().fromString(b.toString())
>>> b.__getstate__() == b2.__getstate__()
True
"""
def test_suite():
return doctest.DocTestSuite()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment