]> arthur.barton.de Git - bup.git/commitdiff
vfs: flatten resolution cache key
authorRob Browning <rlb@defaultvalue.org>
Sat, 7 Jul 2018 17:20:47 +0000 (12:20 -0500)
committerRob Browning <rlb@defaultvalue.org>
Mon, 3 Sep 2018 18:30:10 +0000 (13:30 -0500)
This will require more storage if there are a lot of lookups with the
same parent and differing paths, but otherwise, without more
intentional structure sharing among paths, this should be better, and
we can always revisit the arrangement later.

Serializing the parent path segments should also make sure the same
parent (semantically-speaking) contributes the same hash to the key.
Previously, Metadata objects could prevent that, given their trivial,
pointer-based hashes.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Tested-by: Rob Browning <rlb@defaultvalue.org>
lib/bup/vfs.py

index 14598ffc33bdef32eaa1fbf36e96c52aca650536..1e2705c2eef597e2ce833c97d702c979563ca949 100644 (file)
@@ -253,20 +253,20 @@ def clear_cache():
 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:
-      (repo-id, path, parent, want_meta, dref) -> resolution
+      res:... -> resolution
       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:
-        return len(x) == 5
     if x_t is bytes:
         if len(x) == 20:
             return True
         if len(x) == 22 and x.endswith(b':r'):
             return True
+        if x.startswith('res:'):
+            return True
 
 def cache_get(key):
     global _cache
@@ -759,7 +759,10 @@ def contents(repo, item, names=None, want_meta=True):
         yield x
 
 def _resolve_path(repo, path, parent=None, want_meta=True, deref=False):
-    cache_key = (repo.id(), tuple(path), parent, bool(want_meta), bool(deref))
+    cache_key = b'res:%d%d%d:%s\0%s' \
+                % (bool(want_meta), bool(deref), repo.id(),
+                   ('/'.join(x[0] for x in parent) if parent else ''),
+                   '/'.join(path))
     resolution = cache_get(cache_key)
     if resolution:
         return resolution