...since resolve() currently requires a full parent path and the root
refs are only applicable to a particular repository.
Use differing integers to identify repositories that may be
independent (with respect to refs, tags, etc.), and use (typically
small) integers rather than the repo path/address so that they'll be
short if we want to embed them directly in cache keys later.
Use realpath() for local repositories in order to detect when the same
repository is reachable by multiple paths. (Something similar could
eventually be done for remotes.)
Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Tested-by: Rob Browning <rlb@defaultvalue.org>
from __future__ import absolute_import
from __future__ import absolute_import
+from os.path import realpath
from functools import partial
from bup import client, git
from functools import partial
from bup import client, git
+_next_repo_id = 0
+_repo_ids = {}
+
+def _repo_id(key):
+ global _next_repo_id, _repo_ids
+ repo_id = _repo_ids.get(key)
+ if repo_id:
+ return repo_id
+ next_id = _next_repo_id = _next_repo_id + 1
+ _repo_ids[key] = next_id
+ return next_id
+
class LocalRepo:
def __init__(self, repo_dir=None):
class LocalRepo:
def __init__(self, repo_dir=None):
- self.repo_dir = repo_dir or git.repo()
+ self.repo_dir = realpath(repo_dir or git.repo())
self._cp = git.cp(self.repo_dir)
self.rev_list = partial(git.rev_list, repo_dir=self.repo_dir)
self._cp = git.cp(self.repo_dir)
self.rev_list = partial(git.rev_list, repo_dir=self.repo_dir)
+ self._id = _repo_id(self.repo_dir)
def __exit__(self, type, value, traceback):
self.close()
def __exit__(self, type, value, traceback):
self.close()
+ def id(self):
+ """Return an identifier that differs from any other repository that
+ doesn't share the same repository-specific information
+ (e.g. refs, tags, etc.)."""
+ return self._id
+
def cat(self, ref):
"""If ref does not exist, yield (None, None, None). Otherwise yield
(oidx, type, size), and then all of the data associated with
def cat(self, ref):
"""If ref does not exist, yield (None, None, None). Otherwise yield
(oidx, type, size), and then all of the data associated with
self.address = address
self.client = client.Client(address)
self.rev_list = self.client.rev_list
self.address = address
self.client = client.Client(address)
self.rev_list = self.client.rev_list
+ self._id = _repo_id(self.address)
def close(self):
if self.client:
def close(self):
if self.client:
def __exit__(self, type, value, traceback):
self.close()
def __exit__(self, type, value, traceback):
self.close()
+ def id(self):
+ """Return an identifier that differs from any other repository that
+ doesn't share the same repository-specific information
+ (e.g. refs, tags, etc.)."""
+ return self._id
+
def cat(self, ref):
"""If ref does not exist, yield (None, None, None). Otherwise yield
(oidx, type, size), and then all of the data associated with
def cat(self, ref):
"""If ref does not exist, yield (None, None, None). Otherwise yield
(oidx, type, size), and then all of the data associated with
def is_valid_cache_key(x):
"""Return logically true if x looks like it could be a valid cache key
(with respect to structure). Current valid cache entries:
def is_valid_cache_key(x):
"""Return logically true if x looks like it could be a valid cache key
(with respect to structure). Current valid cache entries:
- (path, parent, want_meta, dref) -> resolution
+ (repo-id, path, parent, want_meta, dref) -> resolution
commit_oid -> commit
commit_oid + ':r' -> rev-list
i.e. rev-list -> {'.', commit, '2012...', next_commit, ...}
commit_oid -> commit
commit_oid + ':r' -> rev-list
i.e. rev-list -> {'.', commit, '2012...', next_commit, ...}
# Suspect we may eventually add "(container_oid, name) -> ...", and others.
x_t = type(x)
if x_t is tuple:
# Suspect we may eventually add "(container_oid, name) -> ...", and others.
x_t = type(x)
if x_t is tuple:
if x_t is bytes:
if len(x) == 20:
return True
if x_t is bytes:
if len(x) == 20:
return True
yield x
def _resolve_path(repo, path, parent=None, want_meta=True, deref=False):
yield x
def _resolve_path(repo, path, parent=None, want_meta=True, deref=False):
- cache_key = (tuple(path), parent, not not want_meta, not not deref)
+ cache_key = (repo.id(), tuple(path), parent, bool(want_meta), bool(deref))
resolution = cache_get(cache_key)
if resolution:
return resolution
resolution = cache_get(cache_key)
if resolution:
return resolution