85
85
self._nodes_by_key = None
86
86
self._key_length = key_elements
87
self._optimize_for_size = False
88
89
def _check_key(self, key):
89
90
"""Raise BadIndexKey if key is not a valid key for this index."""
278
279
(len(result.getvalue()), expected_bytes))
282
def set_optimize(self, for_size=True):
283
"""Change how the builder tries to optimize the result.
285
:param for_size: Tell the builder to try and make the index as small as
289
# GraphIndexBuilder itself doesn't pay attention to the flag yet, but
291
self._optimize_for_size = for_size
282
294
class GraphIndex(object):
283
295
"""An index for data with embedded graphs.
366
378
self._keys_by_offset = {}
367
379
# ready-to-return key:value or key:value, node_ref_lists
369
self._nodes_by_key = {}
381
self._nodes_by_key = None
371
383
pos = stream.tell()
372
384
lines = stream.read().split('\n')
382
394
node_value = value
383
395
self._nodes[key] = node_value
384
if self._key_length > 1:
385
# TODO: We may want to do this lazily, but if we are calling
386
# _buffer_all, we are likely to be doing
387
# iter_entries_prefix
388
key_dict = self._nodes_by_key
389
if self.node_ref_lists:
390
key_value = key, node_value[0], node_value[1]
392
key_value = key, node_value
393
# For a key of (foo, bar, baz) create
394
# _nodes_by_key[foo][bar][baz] = key_value
395
for subkey in key[:-1]:
396
key_dict = key_dict.setdefault(subkey, {})
397
key_dict[key[-1]] = key_value
398
396
# cache the keys for quick set intersections
399
397
self._keys = set(self._nodes)
400
398
if trailers != 1:
401
399
# there must be one line - the empty trailer line.
402
400
raise errors.BadIndexData(self)
402
def _get_nodes_by_key(self):
403
if self._nodes_by_key is None:
405
if self.node_ref_lists:
406
for key, (value, references) in self._nodes.iteritems():
407
key_dict = nodes_by_key
408
for subkey in key[:-1]:
409
key_dict = key_dict.setdefault(subkey, {})
410
key_dict[key[-1]] = key, value, references
412
for key, value in self._nodes.iteritems():
413
key_dict = nodes_by_key
414
for subkey in key[:-1]:
415
key_dict = key_dict.setdefault(subkey, {})
416
key_dict[key[-1]] = key, value
417
self._nodes_by_key = nodes_by_key
418
return self._nodes_by_key
404
420
def iter_all_entries(self):
405
421
"""Iterate over all keys within the index.
600
617
if len(key) != self._key_length:
601
618
raise errors.BadIndexKey(key)
602
619
# find what it refers to:
603
key_dict = self._nodes_by_key
620
key_dict = nodes_by_key
604
621
elements = list(key)
605
622
# find the subdict whose contents should be returned.
973
990
raise errors.BadIndexData(self)
974
991
# keys are tuples. Each element is a string that may occur many
975
992
# times, so we intern them to save space. AB, RC, 200807
976
key = tuple(intern(element) for element in elements[:self._key_length])
993
key = tuple([intern(element) for element in elements[:self._key_length]])
977
994
if first_key is None:
979
996
absent, references, value = elements[-3:]