summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2016-03-13 09:50:05 +0200
committerLars Wirzenius <liw@liw.fi>2016-03-13 10:01:29 +0200
commit553bc915c294f40b25f64c26b3fe88b80e0a740e (patch)
tree6fb655778b9f27ba35c9cbdfce7a52029410b388
parentc2eea0c73763be273e8964f8d4d24d002227e6d3 (diff)
downloadobnam-553bc915c294f40b25f64c26b3fe88b80e0a740e.tar.gz
Use short key names in DIR objects on disk
This should save a bit of disk space. Previously, the full key name as a string was used, and that led to a lot of repetition. This is a backwards incompatible change.
-rw-r--r--NEWS5
-rw-r--r--obnamlib/fmt_ga/dirobj.py52
-rw-r--r--obnamlib/fmt_ga/dirobj_tests.py8
3 files changed, 60 insertions, 5 deletions
diff --git a/NEWS b/NEWS
index ed097486..507c52f2 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,11 @@ not use it unless you're willing to lose your backup.
Version 1.20, not yet released
---------------------------------
+* Those using the experimental green-albatross repository format will
+ have to start over with fresh repositories. This release contains
+ backwards incompatible changes that mean existing repositories no
+ longer work. Sorry, but that's what experimental means.
+
Minor changes:
* Lars Wirzenius changed `obnam forget` so that if there is nothing to
diff --git a/obnamlib/fmt_ga/dirobj.py b/obnamlib/fmt_ga/dirobj.py
index da67abb9..f115872d 100644
--- a/obnamlib/fmt_ga/dirobj.py
+++ b/obnamlib/fmt_ga/dirobj.py
@@ -19,6 +19,33 @@
import obnamlib
+_short_key_names = {
+ obnamlib.REPO_FILE_TEST_KEY: 'T',
+ obnamlib.REPO_FILE_USERNAME: 'U',
+ obnamlib.REPO_FILE_GROUPNAME: 'G',
+ obnamlib.REPO_FILE_SYMLINK_TARGET: 'S',
+ obnamlib.REPO_FILE_XATTR_BLOB: 'X',
+ obnamlib.REPO_FILE_MD5: '5',
+ obnamlib.REPO_FILE_MODE: 'M',
+ obnamlib.REPO_FILE_MTIME_SEC: 'ms',
+ obnamlib.REPO_FILE_MTIME_NSEC: 'mn',
+ obnamlib.REPO_FILE_ATIME_SEC: 'as',
+ obnamlib.REPO_FILE_ATIME_NSEC: 'an',
+ obnamlib.REPO_FILE_NLINK: 'N',
+ obnamlib.REPO_FILE_SIZE: 's',
+ obnamlib.REPO_FILE_UID: 'u',
+ obnamlib.REPO_FILE_GID: 'g',
+ obnamlib.REPO_FILE_BLOCKS: 'B',
+ obnamlib.REPO_FILE_DEV: 'D',
+ obnamlib.REPO_FILE_INO: 'I',
+}
+
+# Let's make sure we have no duplicate values.
+assert len(_short_key_names) == len(_short_key_names.values())
+
+_key_from_short = dict((v, k) for k, v in _short_key_names.items())
+
+
class GADirectory(object):
def __init__(self):
@@ -61,15 +88,30 @@ class GADirectory(object):
return self._dict['metadata'].keys()
def get_file_key(self, basename, key):
- key_name = obnamlib.repo_key_name(key)
- return self._dict['metadata'][basename].get(key_name)
+ short_name = self.get_short_key_name(key)
+ return self._dict['metadata'][basename].get(short_name)
def set_file_key(self, basename, key, value):
- key_name = obnamlib.repo_key_name(key)
- old_value = self._dict['metadata'][basename].get(key_name, None)
+ short_name = self.get_short_key_name(key)
+ old_value = self._dict['metadata'][basename].get(short_name, None)
if value != old_value:
self._require_mutable()
- self._dict['metadata'][basename][key_name] = value
+ self._dict['metadata'][basename][short_name] = value
+
+ def get_short_key_name(self, key):
+ '''Translate a key id to a short key name.
+
+ This is similar to obnamlib.repo_key_name, but the name is
+ guaranteed to be short, while still being unique. The length
+ matters, as these names will be used a lot.
+
+ '''
+
+ return _short_key_names[key]
+
+ def get_key_from_short_name(self, short_name):
+ '''Inverse of get_short_key_name.'''
+ return _key_from_short[short_name]
def get_file_chunk_ids(self, basename):
return self._dict['metadata'][basename]['chunk-ids']
diff --git a/obnamlib/fmt_ga/dirobj_tests.py b/obnamlib/fmt_ga/dirobj_tests.py
index b43324cc..7c223e3d 100644
--- a/obnamlib/fmt_ga/dirobj_tests.py
+++ b/obnamlib/fmt_ga/dirobj_tests.py
@@ -72,6 +72,14 @@ class GADirectoryTests(unittest.TestCase):
obnamlib.GAImmutableError,
dir_obj.remove_file, 'README')
+ def test_maps_file_key_to_short_name_and_back(self):
+ key = obnamlib.REPO_FILE_SIZE
+
+ dir_obj = obnamlib.GADirectory()
+ short = dir_obj.get_short_key_name(key)
+ key2 = dir_obj.get_key_from_short_name(short)
+ self.assertEqual(key, key2)
+
def test_gets_file_key_when_unset(self):
dir_obj = obnamlib.GADirectory()
dir_obj.add_file('README')