diff options
author | Lars Wirzenius <liw@liw.fi> | 2011-04-12 13:37:04 +0100 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2011-04-12 13:37:04 +0100 |
commit | ed3dad684a7edf557a406735b423326d95aac34a (patch) | |
tree | 2466f18bf79dabef6c32a05e36adf19231874f1d | |
parent | 13b89c1dfdb32162cdbddec65297b94e04ff42fd (diff) | |
download | obnam-ed3dad684a7edf557a406735b423326d95aac34a.tar.gz |
Change ClientList to have a three part key.
The third part is new: it's a subkey, so we can store
more metadata about clients in the list, particularly
the client's own public key id.
-rw-r--r-- | obnamlib/clientlist.py | 37 | ||||
-rw-r--r-- | obnamlib/clientlist_tests.py | 7 |
2 files changed, 26 insertions, 18 deletions
diff --git a/obnamlib/clientlist.py b/obnamlib/clientlist.py index c25ef6f2..2ab09f91 100644 --- a/obnamlib/clientlist.py +++ b/obnamlib/clientlist.py @@ -35,13 +35,18 @@ class ClientList(obnamlib.RepositoryTree): The client's identifier is a random, unique 64-bit integer. ''' + + # subkey values + CLIENT_NAME = 0 + SUBKEY_MAX = 255 def __init__(self, fs, node_size, upload_queue_size, lru_size, hooks): self.hash_len = len(self.hashfunc('')) - self.fmt = '!%dsQ' % self.hash_len - self.key_bytes = len(self.key('', 0)) - self.minkey = self.hashkey('\x00' * self.hash_len, 0) - self.maxkey = self.hashkey('\xff' * self.hash_len, obnamlib.MAX_ID) + self.fmt = '!%dsQB' % self.hash_len + self.key_bytes = len(self.key('', 0, 0)) + self.minkey = self.hashkey('\x00' * self.hash_len, 0, 0) + self.maxkey = self.hashkey('\xff' * self.hash_len, obnamlib.MAX_ID, + self.SUBKEY_MAX) obnamlib.RepositoryTree.__init__(self, fs, 'clientlist', self.key_bytes, node_size, upload_queue_size, lru_size, hooks) @@ -50,12 +55,12 @@ class ClientList(obnamlib.RepositoryTree): def hashfunc(self, string): return hashlib.new('md5', string).digest() - def hashkey(self, namehash, client_id): - return struct.pack(self.fmt, namehash, client_id) + def hashkey(self, namehash, client_id, subkey): + return struct.pack(self.fmt, namehash, client_id, subkey) - def key(self, client_name, client_id): + def key(self, client_name, client_id, subkey): h = self.hashfunc(client_name) - return self.hashkey(h, client_id) + return self.hashkey(h, client_id, subkey) def unkey(self, key): return struct.unpack(self.fmt, key) @@ -71,11 +76,11 @@ class ClientList(obnamlib.RepositoryTree): return [] def find_client_id(self, t, client_name): - minkey = self.key(client_name, 0) - maxkey = self.key(client_name, obnamlib.MAX_ID) + minkey = self.key(client_name, 0, 0) + maxkey = self.key(client_name, obnamlib.MAX_ID, self.SUBKEY_MAX) for k, v in t.lookup_range(minkey, maxkey): - checksum, client_id = self.unkey(k) - if v == client_name: + checksum, client_id, subkey = self.unkey(k) + if subkey == self.CLIENT_NAME and v == client_name: return client_id return None @@ -90,16 +95,18 @@ class ClientList(obnamlib.RepositoryTree): if self.find_client_id(self.tree, client_name) is None: while True: candidate_id = self.random_id() - key = self.key(client_name, candidate_id) + key = self.key(client_name, candidate_id, self.CLIENT_NAME) try: self.tree.lookup(key) except KeyError: break - self.tree.insert(self.key(client_name, candidate_id), client_name) + key = self.key(client_name, candidate_id, self.CLIENT_NAME) + self.tree.insert(key, client_name) def remove_client(self, client_name): self.start_changes() client_id = self.find_client_id(self.tree, client_name) if client_id is not None: - self.tree.remove(self.key(client_name, client_id)) + key = self.key(client_name, client_id, self.CLIENT_NAME) + self.tree.remove(key) diff --git a/obnamlib/clientlist_tests.py b/obnamlib/clientlist_tests.py index d54f46ed..9c19aeaa 100644 --- a/obnamlib/clientlist_tests.py +++ b/obnamlib/clientlist_tests.py @@ -38,12 +38,13 @@ class ClientListTests(unittest.TestCase): def test_key_bytes_is_correct_length(self): self.assertEqual(self.list.key_bytes, - len(self.list.key('foo', 12765))) + len(self.list.key('foo', 12765, 0))) def test_unkey_unpacks_key_correctly(self): - key = self.list.key('client name', 12765) - client_hash, client_id = self.list.unkey(key) + key = self.list.key('client name', 12765, 42) + client_hash, client_id, subkey = self.list.unkey(key) self.assertEqual(client_id, 12765) + self.assertEqual(subkey, 42) def test_reports_none_as_id_for_nonexistent_client(self): self.assertEqual(self.list.get_client_id('foo'), None) |