/usr/share/pyshared/obnamlib/repo_tree.py is in obnam 1.6.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | # Copyright 2010 Lars Wirzenius
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import larch
import tracing
import obnamlib
class RepositoryTree(object):
'''A B-tree within an obnamlib.Repository.
For read-only operation, call init_forest before doing anything.
For read-write operation, call start_changes before doing anything,
and commit afterwards. In between, self.tree is the new tree to be
modified. Note that self.tree is NOT available after init_forest.
After init_forest or start_changes, self.forest is the opened forest.
Unlike self.tree, it will not go away after commit.
'''
def __init__(self, fs, dirname, key_bytes, node_size, upload_queue_size,
lru_size, repo):
self.fs = fs
self.dirname = dirname
self.key_bytes = key_bytes
self.node_size = node_size
self.upload_queue_size = upload_queue_size
self.lru_size = lru_size
self.repo = repo
self.forest = None
self.forest_allows_writes = False
self.tree = None
self.keep_just_one_tree = False
def init_forest(self, allow_writes=False):
if self.forest is None:
tracing.trace('initializing forest dirname=%s', self.dirname)
assert self.tree is None
if not self.fs.exists(self.dirname):
tracing.trace('%s does not exist', self.dirname)
return False
self.forest = larch.open_forest(key_size=self.key_bytes,
node_size=self.node_size,
dirname=self.dirname,
upload_max=self.upload_queue_size,
lru_size=self.lru_size,
vfs=self.fs,
allow_writes=allow_writes)
self.forest_allows_writes = allow_writes
return True
def start_changes(self, create_tree=True):
tracing.trace('start changes for %s', self.dirname)
if self.forest is None or not self.forest_allows_writes:
if not self.fs.exists(self.dirname):
need_init = True
else:
filenames = self.fs.listdir(self.dirname)
need_init = filenames == [] or filenames == ['lock']
if need_init:
if not self.fs.exists(self.dirname):
tracing.trace('create %s', self.dirname)
self.fs.mkdir(self.dirname)
self.repo.hooks.call('repository-toplevel-init', self.repo,
self.dirname)
self.forest = None
self.init_forest(allow_writes=True)
assert self.forest is not None
assert self.forest_allows_writes, \
'it is "%s"' % repr(self.forest_allows_writes)
if self.tree is None and create_tree:
if self.forest.trees:
self.tree = self.forest.new_tree(self.forest.trees[-1])
tracing.trace('use newest tree %s (of %d)', self.tree.root.id,
len(self.forest.trees))
else:
self.tree = self.forest.new_tree()
tracing.trace('new tree root id %s', self.tree.root.id)
def commit(self):
tracing.trace('committing')
if self.forest:
if self.keep_just_one_tree:
while len(self.forest.trees) > 1:
tracing.trace('not keeping tree with root id %s',
self.forest.trees[0].root.id)
self.forest.remove_tree(self.forest.trees[0])
self.forest.commit()
self.tree = None
|