Rev 62: Implement a DeltaIndex wrapper. in http://bzr.arbash-meinel.com/plugins/groupcompress_rabin
John Arbash Meinel
john at arbash-meinel.com
Sat Feb 28 04:24:49 GMT 2009
At http://bzr.arbash-meinel.com/plugins/groupcompress_rabin
------------------------------------------------------------
revno: 62
revision-id: john at arbash-meinel.com-20090228042448-nfhhzpjuqic78bfr
parent: john at arbash-meinel.com-20090228040012-lbkwky6vtdmhjepx
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: groupcompress_rabin
timestamp: Fri 2009-02-27 22:24:48 -0600
message:
Implement a DeltaIndex wrapper.
This splits out the create_delta_index from the create_delta code.
Which should also help for profiling purposes.
-------------- next part --------------
=== modified file '_groupcompress_c.pyx'
--- a/_groupcompress_c.pyx 2009-02-27 20:18:47 +0000
+++ b/_groupcompress_c.pyx 2009-02-28 04:24:48 +0000
@@ -75,6 +75,77 @@
# free(val[0])
# val[0] = NULL
+cdef class DeltaIndex:
+
+ cdef object _source
+ cdef delta_index *_index
+
+ def __repr__(self):
+ if self._index == NULL:
+ return '%s(NULL)' % (self.__class__.__name__,)
+ return '%s(%d)' % (self.__class__.__name__,
+ len(self._source))
+
+ def __init__(self, source):
+ self._source = None
+ self._index = NULL
+
+ self._create_delta_index(source)
+
+ def _create_delta_index(self, source):
+ cdef char *c_source
+ cdef Py_ssize_t c_source_size
+
+ if not PyString_CheckExact(source):
+ raise TypeError('source is not a str')
+
+ self._source = source
+ c_source = PyString_AS_STRING(source)
+ c_source_size = PyString_GET_SIZE(source)
+
+ # TODO: Are usage is ultimately going to be different than the one that
+ # was originally designed. Specifically, we are going to want to
+ # be able to update the index by hashing future data. It should
+ # fit just fine into the structure. But for now, we just wrap
+ # create_delta_index (For example, we could always reserve enough
+ # space to hash a 4MB string, etc.)
+ self._index = create_delta_index(c_source, c_source_size)
+ # TODO: Handle if _index == NULL
+
+ cdef _ensure_no_index(self):
+ if self._index != NULL:
+ free_delta_index(self._index)
+ self._index = NULL
+
+ def __dealloc__(self):
+ self._ensure_no_index()
+
+ def make_delta(self, target_bytes, max_delta_size=0):
+ """Create a delta from the current source to the target bytes."""
+ cdef char *target
+ cdef Py_ssize_t target_size
+ cdef void * delta
+ cdef unsigned long delta_size
+
+ assert self._index != NULL
+
+ if not PyString_CheckExact(target_bytes):
+ raise TypeError('target is not a str')
+
+ target = PyString_AS_STRING(target_bytes)
+ target_size = PyString_GET_SIZE(target_bytes)
+
+ # TODO: inline some of create_delta so we at least don't have to double
+ # malloc, and can instead use PyString_FromStringAndSize, to
+ # allocate the bytes into the final string
+ delta = create_delta(self._index, target, target_size,
+ &delta_size, max_delta_size)
+ result = None
+ if delta:
+ result = PyString_FromStringAndSize(<char *>delta, delta_size)
+ free(delta)
+ return result
+
def make_delta(source_bytes, target_bytes):
"""Create a delta from source_bytes => target_bytes."""
=== modified file 'tests/test__groupcompress_c.py'
--- a/tests/test__groupcompress_c.py 2009-02-27 18:43:07 +0000
+++ b/tests/test__groupcompress_c.py 2009-02-28 04:24:48 +0000
@@ -69,8 +69,14 @@
self.requireFeature(CompiledGroupCompress)
from bzrlib.plugins.groupcompress_rabin import _groupcompress_c
self._gc_module = _groupcompress_c
- self.make_delta = _groupcompress_c.make_delta
- self.apply_delta = _groupcompress_c.apply_delta
+
+
+class TestMakeAndApplyDelta(Test_GroupCompress):
+
+ def setUp(self):
+ super(TestMakeAndApplyDelta, self).setUp()
+ self.make_delta = self._gc_module.make_delta
+ self.apply_delta = self._gc_module.apply_delta
def test_make_delta_is_typesafe(self):
self.make_delta('a string', 'another string')
@@ -120,3 +126,15 @@
target = self.apply_delta(_text2,
'NM\x90/\x1ebe matched\nagainst other text\n')
self.assertEqual(_text1, target)
+
+
+class TestDeltaIndex(Test_GroupCompress):
+
+ def test_repr(self):
+ di = self._gc_module.DeltaIndex('test text\n')
+ self.assertEqual('DeltaIndex(10)', repr(di))
+
+ def test_make_delta(self):
+ di = self._gc_module.DeltaIndex(_text1)
+ delta = di.make_delta(_text2)
+ self.assertEqual('MN\x90/\x1fdiffer from\nagainst other text\n', delta)
More information about the bazaar-commits
mailing list