Rev 4728: Start using StaticTuple as part of the chk_map api. in http://bazaar.launchpad.net/~jameinel/bzr/2.1-static-tuple
John Arbash Meinel
john at arbash-meinel.com
Wed Sep 30 22:54:07 BST 2009
At http://bazaar.launchpad.net/~jameinel/bzr/2.1-static-tuple
------------------------------------------------------------
revno: 4728
revision-id: john at arbash-meinel.com-20090930215359-8gvb6appgkc7j8wz
parent: john at arbash-meinel.com-20090930212526-imvbkyikd9d3r4o6
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.1-static-tuple
timestamp: Wed 2009-09-30 16:53:59 -0500
message:
Start using StaticTuple as part of the chk_map api.
All tests now pass, because I changed the apis to not use the direct functions.
I'm not 100% sure about the performance impact, that needs to be profiled.
However, at least everything works, and potentially this will help
memory overhead. I'm not 100% sure about speed just yet.
-------------- next part --------------
=== modified file 'bzrlib/_btree_serializer_pyx.pyx'
--- a/bzrlib/_btree_serializer_pyx.pyx 2009-09-30 21:25:26 +0000
+++ b/bzrlib/_btree_serializer_pyx.pyx 2009-09-30 21:53:59 +0000
@@ -38,6 +38,8 @@
Py_ssize_t PyString_Size(object p)
Py_ssize_t PyString_GET_SIZE_ptr "PyString_GET_SIZE" (PyObject *)
char * PyString_AS_STRING_ptr "PyString_AS_STRING" (PyObject *)
+ char * PyString_AS_STRING(object)
+ Py_ssize_t PyString_GET_SIZE(object)
int PyString_AsStringAndSize_ptr(PyObject *, char **buf, Py_ssize_t *len)
void PyString_InternInPlace(PyObject **)
int PyTuple_CheckExact(object t)
@@ -66,6 +68,7 @@
# Steals a reference and Val must be a PyStringObject, no checking is done
void StaticTuple_SET_ITEM(object key, Py_ssize_t offset, object val)
object StaticTuple_GET_ITEM(object key, Py_ssize_t offset)
+ int StaticTuple_CheckExact(object)
# TODO: Find some way to import this from _dirstate_helpers
@@ -322,7 +325,6 @@
cdef Py_ssize_t flat_len
cdef Py_ssize_t key_len
cdef Py_ssize_t node_len
- cdef PyObject * val
cdef char * value
cdef Py_ssize_t value_len
cdef char * out
@@ -331,13 +333,12 @@
cdef int first_ref_list
cdef int first_reference
cdef int i
- cdef PyObject *ref_bit
cdef Py_ssize_t ref_bit_len
- if not PyTuple_CheckExact(node):
- raise TypeError('We expected a tuple() for node not: %s'
+ if not PyTuple_CheckExact(node) and not StaticTuple_CheckExact(node):
+ raise TypeError('We expected a tuple() or StaticTuple() for node not: %s'
% type(node))
- node_len = PyTuple_GET_SIZE(node)
+ node_len = len(node)
have_reference_lists = reference_lists
if have_reference_lists:
if node_len != 4:
@@ -347,7 +348,7 @@
raise ValueError('Without ref_lists, we need at least 3 entries not: %s'
% len(node))
# I don't expect that we can do faster than string.join()
- string_key = '\0'.join(<object>PyTuple_GET_ITEM_ptr_object(node, 1))
+ string_key = '\0'.join(node[1])# <object>PyTuple_GET_ITEM_ptr_object(node, 1))
# TODO: instead of using string joins, precompute the final string length,
# and then malloc a single string and copy everything in.
@@ -364,7 +365,7 @@
refs_len = 0
if have_reference_lists:
# Figure out how many bytes it will take to store the references
- ref_lists = <object>PyTuple_GET_ITEM_ptr_object(node, 3)
+ ref_lists = node[3]# <object>PyTuple_GET_ITEM_ptr_object(node, 3)
next_len = len(ref_lists) # TODO: use a Py function
if next_len > 0:
# If there are no nodes, we don't need to do any work
@@ -378,31 +379,32 @@
# references
refs_len = refs_len + (next_len - 1)
for reference in ref_list:
- if not PyTuple_CheckExact(reference):
+ if (not PyTuple_CheckExact(reference)
+ and not StaticTuple_CheckExact(reference)):
raise TypeError(
'We expect references to be tuples not: %s'
% type(reference))
- next_len = PyTuple_GET_SIZE(reference)
+ next_len = len(reference)
if next_len > 0:
# We will need (len - 1) '\x00' characters to
# separate the reference key
refs_len = refs_len + (next_len - 1)
for i from 0 <= i < next_len:
- ref_bit = PyTuple_GET_ITEM_ptr_object(reference, i)
- if not PyString_CheckExact_ptr(ref_bit):
+ ref_bit = reference[i]
+ if not PyString_CheckExact(ref_bit):
raise TypeError('We expect reference bits'
' to be strings not: %s'
% type(<object>ref_bit))
- refs_len = refs_len + PyString_GET_SIZE_ptr(ref_bit)
+ refs_len = refs_len + PyString_GET_SIZE(ref_bit)
# So we have the (key NULL refs NULL value LF)
key_len = PyString_Size(string_key)
- val = PyTuple_GET_ITEM_ptr_object(node, 2)
- if not PyString_CheckExact_ptr(val):
+ val = node[2] # PyTuple_GET_ITEM_ptr_object(node, 2)
+ if not PyString_CheckExact(val):
raise TypeError('Expected a plain str for value not: %s'
- % type(<object>val))
- value = PyString_AS_STRING_ptr(val)
- value_len = PyString_GET_SIZE_ptr(val)
+ % type(val))
+ value = PyString_AS_STRING(val)
+ value_len = PyString_GET_SIZE(val)
flat_len = (key_len + 1 + refs_len + 1 + value_len + 1)
line = PyString_FromStringAndSize(NULL, flat_len)
# Get a pointer to the new buffer
@@ -424,14 +426,14 @@
out[0] = c'\r'
out = out + 1
first_reference = 0
- next_len = PyTuple_GET_SIZE(reference)
+ next_len = len(reference)
for i from 0 <= i < next_len:
if i != 0:
out[0] = c'\x00'
out = out + 1
- ref_bit = PyTuple_GET_ITEM_ptr_object(reference, i)
- ref_bit_len = PyString_GET_SIZE_ptr(ref_bit)
- memcpy(out, PyString_AS_STRING_ptr(ref_bit), ref_bit_len)
+ ref_bit = reference[i] #PyTuple_GET_ITEM_ptr_object(reference, i)
+ ref_bit_len = PyString_GET_SIZE(ref_bit)
+ memcpy(out, PyString_AS_STRING(ref_bit), ref_bit_len)
out = out + ref_bit_len
out[0] = c'\0'
out = out + 1
=== modified file 'bzrlib/_chk_map_py.py'
--- a/bzrlib/_chk_map_py.py 2009-04-09 20:23:07 +0000
+++ b/bzrlib/_chk_map_py.py 2009-09-30 21:53:59 +0000
@@ -156,3 +156,5 @@
result._search_prefix = common_prefix
return result
+
+_key_type = tuple
=== modified file 'bzrlib/_chk_map_pyx.pyx'
--- a/bzrlib/_chk_map_pyx.pyx 2009-06-22 12:52:39 +0000
+++ b/bzrlib/_chk_map_pyx.pyx 2009-09-30 21:53:59 +0000
@@ -59,9 +59,31 @@
uLong crc32(uLong crc, Bytef *buf, uInt len)
-
+cdef extern from "_static_tuple_c.h":
+ void **StaticTuple_API
+ int import_static_tuple()
+
+ object StaticTuple_New(Py_ssize_t)
+ object StaticTuple_intern(object)
+ # Steals a reference and val must be a String or StaticTuple, no checking
+ # is done
+ void StaticTuple_SET_ITEM(object key, Py_ssize_t offset, object val)
+ object StaticTuple_GET_ITEM(object key, Py_ssize_t offset)
+ int StaticTuple_CheckExact(object)
+
+
+from bzrlib import _static_tuple_c
+# This sets up the StaticTuple C_API functionality
+if import_static_tuple() == -1 or StaticTuple_API == NULL:
+ raise ImportError('failed to import_static_tuple()')
+cdef object StaticTuple
+StaticTuple = _static_tuple_c.StaticTuple
+
+cdef object _LeafNode
_LeafNode = None
+cdef object _InternalNode
_InternalNode = None
+cdef object _unknown
_unknown = None
# We shouldn't just copy this from _dirstate_helpers_pyx
@@ -89,11 +111,11 @@
cdef uInt crc_val
cdef Py_ssize_t out_off
cdef char *c_out
- cdef PyObject *bit
+ # cdef PyObject *bit
- if not PyTuple_CheckExact(key):
+ if not PyTuple_CheckExact(key) and not StaticTuple_CheckExact(key):
raise TypeError('key %r is not a tuple' % (key,))
- num_bits = PyTuple_GET_SIZE(key)
+ num_bits = len(key)
# 4 bytes per crc32, and another 1 byte between bits
num_out_bytes = (9 * num_bits) - 1
out = PyString_FromStringAndSize(NULL, num_out_bytes)
@@ -105,11 +127,13 @@
# We use the _ptr variant, because GET_ITEM returns a borrowed
# reference, and Pyrex assumes that returned 'object' are a new
# reference
- bit = PyTuple_GET_ITEM_ptr(key, i)
- if not PyString_CheckExact_ptr(bit):
+ # XXX: This needs to be updated for PySequence_GetItem since both
+ # PyTuple and StaticTuple support that api
+ bit = key[i]# PyTuple_GET_ITEM_ptr(key, i)
+ if not PyString_CheckExact(bit):
raise TypeError('Bit %d of %r is not a string' % (i, key))
- c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)
- c_len = PyString_GET_SIZE_ptr(bit)
+ c_bit = <Bytef *>PyString_AS_STRING(bit)
+ c_len = PyString_GET_SIZE(bit)
crc_val = crc32(0, c_bit, c_len)
# Hex(val) order
sprintf(c_out, '%08X', crc_val)
@@ -127,11 +151,11 @@
cdef uInt crc_val
cdef Py_ssize_t out_off
cdef char *c_out
- cdef PyObject *bit
+ # cdef PyObject *bit
- if not PyTuple_CheckExact(key):
+ if not PyTuple_CheckExact(key) and not StaticTuple_CheckExact(key):
raise TypeError('key %r is not a tuple' % (key,))
- num_bits = PyTuple_GET_SIZE(key)
+ num_bits = len(key)
# 4 bytes per crc32, and another 1 byte between bits
num_out_bytes = (5 * num_bits) - 1
out = PyString_FromStringAndSize(NULL, num_out_bytes)
@@ -140,12 +164,12 @@
if i > 0:
c_out[0] = c'\x00'
c_out = c_out + 1
- bit = PyTuple_GET_ITEM_ptr(key, i)
- if not PyString_CheckExact_ptr(bit):
+ bit = key[i] # PyTuple_GET_ITEM_ptr(key, i)
+ if not PyString_CheckExact(bit):
raise TypeError('Bit %d of %r is not a string: %r' % (i, key,
- <object>bit))
- c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)
- c_len = PyString_GET_SIZE_ptr(bit)
+ bit))
+ c_bit = <Bytef *>PyString_AS_STRING(bit)
+ c_len = PyString_GET_SIZE(bit)
crc_val = crc32(0, c_bit, c_len)
# MSB order
c_out[0] = (crc_val >> 24) & 0xFF
@@ -265,12 +289,12 @@
if next_line == NULL:
raise ValueError('missing trailing newline')
cur = next_line + 1
- entry_bits = PyTuple_New(width)
+ entry_bits = StaticTuple_New(width)
for i from 0 <= i < num_prefix_bits:
entry = prefix_bits[i]
# SET_ITEM 'steals' a reference
Py_INCREF(entry)
- PyTuple_SET_ITEM(entry_bits, i, entry)
+ StaticTuple_SET_ITEM(entry_bits, i, entry)
value = PyString_FromStringAndSize(value_start, next_line - value_start)
# The next entry bit needs the 'tail' from the prefix, and first part
# of the line
@@ -288,7 +312,7 @@
memcpy(c_entry + prefix_tail_len, line_start, next_null - line_start)
Py_INCREF(entry)
i = num_prefix_bits
- PyTuple_SET_ITEM(entry_bits, i, entry)
+ StaticTuple_SET_ITEM(entry_bits, i, entry)
while next_null != last_null: # We have remaining bits
i = i + 1
if i > width:
@@ -301,11 +325,12 @@
entry = PyString_FromStringAndSize(entry_start,
next_null - entry_start)
Py_INCREF(entry)
- PyTuple_SET_ITEM(entry_bits, i, entry)
+ StaticTuple_SET_ITEM(entry_bits, i, entry)
if len(entry_bits) != width:
raise AssertionError(
'Incorrect number of elements (%d vs %d)'
% (len(entry_bits)+1, width + 1))
+ entry_bits = StaticTuple_intern(entry_bits)
PyDict_SetItem(items, entry_bits, value)
if len(items) != length:
raise ValueError("item count (%d) mismatch for key %s,"
@@ -384,7 +409,8 @@
memcpy(c_item_prefix + prefix_length, cur, next_null - cur)
flat_key = PyString_FromStringAndSize(next_null + 1,
next_line - next_null - 1)
- PyDict_SetItem(items, item_prefix, (flat_key,))
+ flat_key = StaticTuple(flat_key).intern()
+ PyDict_SetItem(items, item_prefix, flat_key)
cur = next_line + 1
assert len(items) > 0
result._items = items
@@ -399,3 +425,5 @@
result._search_prefix = PyString_FromStringAndSize(prefix, prefix_length)
return result
+
+_key_type = StaticTuple
=== modified file 'bzrlib/_static_tuple_c.c'
--- a/bzrlib/_static_tuple_c.c 2009-09-30 21:17:48 +0000
+++ b/bzrlib/_static_tuple_c.c 2009-09-30 21:53:59 +0000
@@ -712,6 +712,11 @@
PyModule_AddObject(m, "_empty_tuple", (PyObject *)_empty_tuple);
}
+static int
+_StaticTuple_CheckExact(PyObject *obj)
+{
+ return StaticTuple_CheckExact(obj);
+}
static void
setup_c_api(PyObject *m)
@@ -721,6 +726,8 @@
StaticTuple_API[StaticTuple_New_NUM] = (void *)StaticTuple_New;
StaticTuple_API[StaticTuple_intern_NUM] = (void *)StaticTuple_intern;
+ StaticTuple_API[StaticTuple_CheckExact_NUM] =
+ (void*)_StaticTuple_CheckExact;
c_api_object = PyCObject_FromVoidPtr((void *)StaticTuple_API, NULL);
if (c_api_object != NULL) {
PyModule_AddObject(m, "_C_API", c_api_object);
=== modified file 'bzrlib/_static_tuple_c.h'
--- a/bzrlib/_static_tuple_c.h 2009-09-30 21:17:48 +0000
+++ b/bzrlib/_static_tuple_c.h 2009-09-30 21:53:59 +0000
@@ -64,7 +64,7 @@
PyObject_VAR_HEAD
PyObject *table[1];
} KeyIntern;
-extern PyTypeObject StaticTuple_Type;
+// extern PyTypeObject StaticTuple_Type;
#define StaticTuple_CheckExact(op) (Py_TYPE(op) == &StaticTuple_Type)
#define StaticTuple_SET_ITEM(key, offset, val) \
@@ -75,9 +75,10 @@
/* C API Functions */
#define StaticTuple_New_NUM 0
#define StaticTuple_intern_NUM 1
+#define StaticTuple_CheckExact_NUM 2
/* Total number of C API Pointers */
-#define StaticTuple_API_pointers 2
+#define StaticTuple_API_pointers 3
#ifdef STATIC_TUPLE_MODULE
/* Used when compiling _static_tuple_c.c */
@@ -91,6 +92,9 @@
static PyObject *(*StaticTuple_New)(Py_ssize_t);
static PyObject *(*StaticTuple_intern)(PyObject *);
+#undef StaticTuple_CheckExact
+static int (*StaticTuple_CheckExact)(PyObject *);
+
/* Return -1 and set exception on error, 0 on success */
static int
@@ -116,6 +120,7 @@
StaticTuple_API = (void **)PyCObject_AsVoidPtr(c_api_object);
StaticTuple_New = StaticTuple_API[StaticTuple_New_NUM];
StaticTuple_intern = StaticTuple_API[StaticTuple_intern_NUM];
+ StaticTuple_CheckExact = StaticTuple_API[StaticTuple_CheckExact_NUM];
Py_DECREF(c_api_object);
return 0;
}
=== modified file 'bzrlib/chk_map.py'
--- a/bzrlib/chk_map.py 2009-08-04 14:10:09 +0000
+++ b/bzrlib/chk_map.py 2009-09-30 21:53:59 +0000
@@ -133,7 +133,7 @@
def _ensure_root(self):
"""Ensure that the root node is an object not a key."""
- if type(self._root_node) is tuple:
+ if type(self._root_node) in (_key_type, tuple):
# Demand-load the root
self._root_node = self._get_node(self._root_node)
@@ -147,7 +147,7 @@
:param node: A tuple key or node object.
:return: A node object.
"""
- if type(node) is tuple:
+ if type(node) in (tuple, _key_type):
bytes = self._read_bytes(node)
return _deserialise(bytes, node,
search_key_func=self._search_key_func)
@@ -486,7 +486,7 @@
def key(self):
"""Return the key for this map."""
- if type(self._root_node) is tuple:
+ if type(self._root_node) in (tuple, _key_type):
return self._root_node
else:
return self._root_node._key
@@ -516,7 +516,7 @@
def _node_key(self, node):
"""Get the key for a node whether it's a tuple or node."""
- if type(node) is tuple:
+ if type(node) in (tuple, _key_type):
return node
else:
return node._key
@@ -542,7 +542,7 @@
:return: The key of the root node.
"""
- if type(self._root_node) is tuple:
+ if type(self._root_node) in (tuple, _key_type):
# Already saved.
return self._root_node
keys = list(self._root_node.serialise(self._store))
@@ -1024,7 +1024,7 @@
# for whatever we are missing
shortcut = True
for prefix, node in self._items.iteritems():
- if node.__class__ is tuple:
+ if node.__class__ in (tuple, _key_type):
keys[node] = (prefix, None)
else:
yield node, None
@@ -1059,7 +1059,7 @@
# A given key can only match 1 child node, if it isn't
# there, then we can just return nothing
return
- if node.__class__ is tuple:
+ if node.__class__ in (tuple, _key_type):
keys[node] = (search_prefix, [key])
else:
# This is loaded, and the only thing that can match,
@@ -1092,7 +1092,7 @@
# We can ignore this one
continue
node_key_filter = prefix_to_keys[search_prefix]
- if node.__class__ is tuple:
+ if node.__class__ in (tuple, _key_type):
keys[node] = (search_prefix, node_key_filter)
else:
yield node, node_key_filter
@@ -1107,7 +1107,7 @@
if sub_prefix in length_filter:
node_key_filter.extend(prefix_to_keys[sub_prefix])
if node_key_filter: # this key matched something, yield it
- if node.__class__ is tuple:
+ if node.__class__ in (tuple, _key_type):
keys[node] = (prefix, node_key_filter)
else:
yield node, node_key_filter
@@ -1245,7 +1245,7 @@
:return: An iterable of the keys inserted by this operation.
"""
for node in self._items.itervalues():
- if type(node) is tuple:
+ if type(node) in (tuple, _key_type):
# Never deserialised.
continue
if node._key is not None:
@@ -1262,7 +1262,7 @@
lines.append('%s\n' % (self._search_prefix,))
prefix_len = len(self._search_prefix)
for prefix, node in sorted(self._items.items()):
- if type(node) is tuple:
+ if type(node) in (tuple, _key_type):
key = node[0]
else:
key = node._key[0]
@@ -1307,7 +1307,7 @@
raise AssertionError("unserialised nodes have no refs.")
refs = []
for value in self._items.itervalues():
- if type(value) is tuple:
+ if type(value) in (tuple, _key_type):
refs.append(value)
else:
refs.append(value.key())
@@ -1639,6 +1639,7 @@
_search_key_255,
_deserialise_leaf_node,
_deserialise_internal_node,
+ _key_type,
)
except ImportError:
from bzrlib._chk_map_py import (
@@ -1646,6 +1647,7 @@
_search_key_255,
_deserialise_leaf_node,
_deserialise_internal_node,
+ _key_type,
)
search_key_registry.register('hash-16-way', _search_key_16)
search_key_registry.register('hash-255-way', _search_key_255)
=== modified file 'bzrlib/tests/test_chk_map.py'
--- a/bzrlib/tests/test_chk_map.py 2009-07-16 23:28:49 +0000
+++ b/bzrlib/tests/test_chk_map.py 2009-09-30 21:53:59 +0000
@@ -831,13 +831,13 @@
# 'ab' and 'ac' nodes
chkmap.map(('aad',), 'v')
self.assertIsInstance(chkmap._root_node._items['aa'], InternalNode)
- self.assertIsInstance(chkmap._root_node._items['ab'], tuple)
- self.assertIsInstance(chkmap._root_node._items['ac'], tuple)
+ self.assertIsInstance(chkmap._root_node._items['ab'], (tuple, chk_map._key_type))
+ self.assertIsInstance(chkmap._root_node._items['ac'], (tuple, chk_map._key_type))
# Unmapping 'acd' can notice that 'aa' is an InternalNode and not have
# to map in 'ab'
chkmap.unmap(('acd',))
self.assertIsInstance(chkmap._root_node._items['aa'], InternalNode)
- self.assertIsInstance(chkmap._root_node._items['ab'], tuple)
+ self.assertIsInstance(chkmap._root_node._items['ab'], (tuple, chk_map._key_type))
def test_unmap_without_fitting_doesnt_page_in(self):
store = self.get_chk_bytes()
@@ -860,8 +860,9 @@
chkmap.map(('aaf',), 'v')
# At this point, the previous nodes should not be paged in, but the
# newly added nodes would be
- self.assertIsInstance(chkmap._root_node._items['aaa'], tuple)
- self.assertIsInstance(chkmap._root_node._items['aab'], tuple)
+ self.assertIsInstance(chkmap._root_node._items['aaa'], (tuple,
+ chk_map._key_type))
+ self.assertIsInstance(chkmap._root_node._items['aab'], (tuple, chk_map._key_type))
self.assertIsInstance(chkmap._root_node._items['aac'], LeafNode)
self.assertIsInstance(chkmap._root_node._items['aad'], LeafNode)
self.assertIsInstance(chkmap._root_node._items['aae'], LeafNode)
@@ -869,8 +870,8 @@
# Now unmapping one of the new nodes will use only the already-paged-in
# nodes to determine that we don't need to do more.
chkmap.unmap(('aaf',))
- self.assertIsInstance(chkmap._root_node._items['aaa'], tuple)
- self.assertIsInstance(chkmap._root_node._items['aab'], tuple)
+ self.assertIsInstance(chkmap._root_node._items['aaa'], (tuple, chk_map._key_type))
+ self.assertIsInstance(chkmap._root_node._items['aab'], (tuple, chk_map._key_type))
self.assertIsInstance(chkmap._root_node._items['aac'], LeafNode)
self.assertIsInstance(chkmap._root_node._items['aad'], LeafNode)
self.assertIsInstance(chkmap._root_node._items['aae'], LeafNode)
@@ -897,9 +898,12 @@
chkmap.map(('aad',), 'v')
# At this point, the previous nodes should not be paged in, but the
# newly added node would be
- self.assertIsInstance(chkmap._root_node._items['aaa'], tuple)
- self.assertIsInstance(chkmap._root_node._items['aab'], tuple)
- self.assertIsInstance(chkmap._root_node._items['aac'], tuple)
+ self.assertIsInstance(chkmap._root_node._items['aaa'], (tuple,
+ chk_map._key_type))
+ self.assertIsInstance(chkmap._root_node._items['aab'], (tuple,
+ chk_map._key_type))
+ self.assertIsInstance(chkmap._root_node._items['aac'], (tuple,
+ chk_map._key_type))
self.assertIsInstance(chkmap._root_node._items['aad'], LeafNode)
# Unmapping the new node will check the existing nodes to see if they
# would fit.
@@ -937,9 +941,12 @@
chkmap.map(('aad',), 'v')
# At this point, the previous nodes should not be paged in, but the
# newly added node would be
- self.assertIsInstance(chkmap._root_node._items['aaa'], tuple)
- self.assertIsInstance(chkmap._root_node._items['aab'], tuple)
- self.assertIsInstance(chkmap._root_node._items['aac'], tuple)
+ self.assertIsInstance(chkmap._root_node._items['aaa'], (tuple,
+ chk_map._key_type))
+ self.assertIsInstance(chkmap._root_node._items['aab'], (tuple,
+ chk_map._key_type))
+ self.assertIsInstance(chkmap._root_node._items['aac'], (tuple,
+ chk_map._key_type))
self.assertIsInstance(chkmap._root_node._items['aad'], LeafNode)
# Now clear the page cache, and only include 2 of the children in the
# cache
@@ -954,7 +961,8 @@
# Unmapping the new node will check the nodes from the page cache
# first, and not have to read in 'aaa'
chkmap.unmap(('aad',))
- self.assertIsInstance(chkmap._root_node._items['aaa'], tuple)
+ self.assertIsInstance(chkmap._root_node._items['aaa'], (tuple,
+ chk_map._key_type))
self.assertIsInstance(chkmap._root_node._items['aab'], LeafNode)
self.assertIsInstance(chkmap._root_node._items['aac'], LeafNode)
@@ -974,9 +982,12 @@
chkmap.map(('aaf',), 'val')
# At this point, the previous nodes should not be paged in, but the
# newly added node would be
- self.assertIsInstance(chkmap._root_node._items['aaa'], tuple)
- self.assertIsInstance(chkmap._root_node._items['aab'], tuple)
- self.assertIsInstance(chkmap._root_node._items['aac'], tuple)
+ self.assertIsInstance(chkmap._root_node._items['aaa'], (tuple,
+ chk_map._key_type))
+ self.assertIsInstance(chkmap._root_node._items['aab'], (tuple,
+ chk_map._key_type))
+ self.assertIsInstance(chkmap._root_node._items['aac'], (tuple,
+ chk_map._key_type))
self.assertIsInstance(chkmap._root_node._items['aad'], LeafNode)
self.assertIsInstance(chkmap._root_node._items['aae'], LeafNode)
self.assertIsInstance(chkmap._root_node._items['aaf'], LeafNode)
@@ -984,9 +995,12 @@
# Unmapping a new node will see the other nodes that are already in
# memory, and not need to page in anything else
chkmap.unmap(('aad',))
- self.assertIsInstance(chkmap._root_node._items['aaa'], tuple)
- self.assertIsInstance(chkmap._root_node._items['aab'], tuple)
- self.assertIsInstance(chkmap._root_node._items['aac'], tuple)
+ self.assertIsInstance(chkmap._root_node._items['aaa'], (tuple,
+ chk_map._key_type))
+ self.assertIsInstance(chkmap._root_node._items['aab'], (tuple,
+ chk_map._key_type))
+ self.assertIsInstance(chkmap._root_node._items['aac'], (tuple,
+ chk_map._key_type))
self.assertIsInstance(chkmap._root_node._items['aae'], LeafNode)
self.assertIsInstance(chkmap._root_node._items['aaf'], LeafNode)
@@ -1031,8 +1045,8 @@
{('a',): 'content here', ('b',): 'more content'},
chk_bytes=basis._store, maximum_size=10)
list(target.iter_changes(basis))
- self.assertIsInstance(target._root_node, tuple)
- self.assertIsInstance(basis._root_node, tuple)
+ self.assertIsInstance(target._root_node, (tuple, chk_map._key_type))
+ self.assertIsInstance(basis._root_node, (tuple, chk_map._key_type))
def test_iter_changes_ab_ab_changed_values_shown(self):
basis = self._get_map({('a',): 'content here', ('b',): 'more content'},
@@ -1932,7 +1946,7 @@
# Ensure test validity: nothing paged in below the root.
self.assertEqual(2,
len([value for value in node._items.values()
- if type(value) == tuple]))
+ if type(value) in (tuple, chk_map._key_type)]))
# now, mapping to k3 should add a k3 leaf
prefix, nodes = node.map(None, ('k3',), 'quux')
self.assertEqual("k", prefix)
@@ -1971,7 +1985,7 @@
# Ensure test validity: nothing paged in below the root.
self.assertEqual(2,
len([value for value in node._items.values()
- if type(value) == tuple]))
+ if type(value) in (tuple, chk_map._key_type)]))
# now, mapping to k23 causes k22 ('k2' in node) to split into k22 and
# k23, which for simplicity in the current implementation generates
# a new internal node between node, and k22/k23.
More information about the bazaar-commits
mailing list