1
# groupcompress, a bzr plugin providing new compression logic.
2
# Copyright (C) 2008 Canonical Limited.
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License version 2 as published
6
# by the Free Software Foundation.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
"""Core compression logic for compressing streams of related files."""
21
from bzrlib import pack
22
from bzrlib.knit import _DirectPackAccess
23
from bzrlib.plugins.index2.repofmt import InMemoryBTree
24
from bzrlib.versionedfile import VersionedFiles
27
def make_pack_factory(graph, delta, keylength):
28
"""Create a factory for creating a pack based groupcompress.
30
This is only functional enough to run interface tests, it doesn't try to
31
provide a full pack environment.
33
:param graph: Store a graph.
34
:param delta: Delta compress contents.
35
:param keylength: How long should keys be.
37
def factory(transport):
38
parents = graph or delta
47
graph_index = InMemoryBTree(reference_lists=ref_length,
48
key_elements=keylength)
49
stream = transport.open_write_stream('newpack')
50
writer = pack.ContainerWriter(stream.write)
52
index = _GCGraphIndex(graph_index, lambda:True, parents=parents,
53
deltas=delta, add_callback=graph_index.add_nodes)
54
access = _DirectPackAccess({})
55
access.set_writer(writer, graph_index, (transport, 'newpack'))
56
result = GroupCompressVersionedFiles(index, access,
57
max_delta_chain=max_delta_chain)
58
result.stream = stream
59
result.writer = writer
64
def cleanup_pack_group(versioned_files):
65
versioned_files.stream.close()
66
versioned_files.writer.end()
69
class GroupCompressVersionedFiles(VersionedFiles):
70
"""A group-compress based VersionedFiles implementation."""
72
def __init__(self, index, access, max_delta_chain=-1):
73
"""Create a GroupCompressVersionedFiles object.
75
:param index: The index object storing access and graph data.
76
:param access: The access object storing raw data.
80
class _GCGraphIndex(object):
81
"""Mapper from GroupCompressVersionedFiles needs into GraphIndex storage."""
83
def __init__(self, graph_index, is_locked, deltas=False, parents=True,
85
"""Construct a _GCGraphIndex on a graph_index.
87
:param graph_index: An implementation of bzrlib.index.GraphIndex.
88
:param is_locked: A callback to check whether the object should answer
90
:param deltas: Allow delta-compressed records.
91
:param parents: If True, record knits parents, if not do not record
93
:param add_callback: If not None, allow additions to the index and call
94
this callback with a list of added GraphIndex nodes:
95
[(node, value, node_refs), ...]
96
:param is_locked: A callback, returns True if the index is locked and
99
self._add_callback = add_callback
100
self._graph_index = graph_index
101
self._deltas = deltas
102
self._parents = parents
103
if deltas and not parents:
104
# XXX: TODO: Delta tree and parent graph should be conceptually
106
raise KnitCorrupt(self, "Cannot do delta compression without "
108
self.has_graph = parents
109
self._is_locked = is_locked