From b88b51305f7b96077e5ee0517248dc45029c9d4f Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sat, 13 Aug 2016 15:41:23 +0300 Subject: Add CowTree for storing chunk index data Also, add a a real implementation of LeafStore, with persistence. --- obnamlib/__init__.py | 2 ++ obnamlib/fmt_ga/__init__.py | 3 ++- obnamlib/fmt_ga/cowtree.py | 41 +++++++++++++++++++++++++++++++++ obnamlib/fmt_ga/cowtree_tests.py | 49 ++++++++++++++++++++++++++++++++++++++++ obnamlib/fmt_ga/leaf_store.py | 20 ++++++++++++++++ 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 obnamlib/fmt_ga/cowtree.py create mode 100644 obnamlib/fmt_ga/cowtree_tests.py diff --git a/obnamlib/__init__.py b/obnamlib/__init__.py index 9590fe7a..21428777 100644 --- a/obnamlib/__init__.py +++ b/obnamlib/__init__.py @@ -187,7 +187,9 @@ from .fmt_ga import ( GAChunkStore, GAChunkIndexes, InMemoryLeafStore, + LeafStore, CowLeaf, + CowTree, ) diff --git a/obnamlib/fmt_ga/__init__.py b/obnamlib/fmt_ga/__init__.py index 394d3c31..8797948a 100644 --- a/obnamlib/fmt_ga/__init__.py +++ b/obnamlib/fmt_ga/__init__.py @@ -17,8 +17,9 @@ from .client_list import GAClientList from .chunk_store import GAChunkStore -from .leaf_store import InMemoryLeafStore +from .leaf_store import InMemoryLeafStore, LeafStore from .leaf import CowLeaf +from .cowtree import CowTree from .indexes import GAChunkIndexes from .dirobj import GADirectory, GAImmutableError, create_gadirectory_from_dict from .tree import GATree diff --git a/obnamlib/fmt_ga/cowtree.py b/obnamlib/fmt_ga/cowtree.py new file mode 100644 index 00000000..7500b089 --- /dev/null +++ b/obnamlib/fmt_ga/cowtree.py @@ -0,0 +1,41 @@ +# Copyright 2016 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 . +# +# =*= License: GPL-3+ =*= + + +import obnamlib + + +class CowTree(object): + + def __init__(self): + self._store = None + self._leaf = obnamlib.CowLeaf() + + def set_leaf_store(self, leaf_store): + self._store = leaf_store + + def set_list_node(self, leaf_id): + self._leaf = self._store.get_leaf(leaf_id) + + def lookup(self, key): + return self._leaf.lookup(key) + + def insert(self, key, value): + self._leaf.insert(key, value) + + def commit(self): + return self._store.put_leaf(self._leaf) diff --git a/obnamlib/fmt_ga/cowtree_tests.py b/obnamlib/fmt_ga/cowtree_tests.py new file mode 100644 index 00000000..7e8dd114 --- /dev/null +++ b/obnamlib/fmt_ga/cowtree_tests.py @@ -0,0 +1,49 @@ +# Copyright 2016 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 . +# +# =*= License: GPL-3+ =*= + + +import unittest + +import obnamlib + + +class CowTreeTests(unittest.TestCase): + + def setUp(self): + self.ls = obnamlib.InMemoryLeafStore() + self.cow = obnamlib.CowTree() + self.cow.set_leaf_store(self.ls) + + def test_lookup_returns_none_if_key_is_missing(self): + self.assertEqual(self.cow.lookup(42), None) + + def test_returns_keyvalue_that_has_been_inserted(self): + key = 'fookey' + value = 'barvalue' + self.cow.insert(key, value) + self.assertEqual(self.cow.lookup(key), value) + + def test_commits_changes_persistently(self): + key = 'fookey' + value = 'barvalue' + self.cow.insert(key, value) + list_id = self.cow.commit() + + cow2 = obnamlib.CowTree() + cow2.set_leaf_store(self.ls) + cow2.set_list_node(list_id) + self.assertEqual(cow2.lookup(key), value) diff --git a/obnamlib/fmt_ga/leaf_store.py b/obnamlib/fmt_ga/leaf_store.py index 5a3a8627..b5cb5120 100644 --- a/obnamlib/fmt_ga/leaf_store.py +++ b/obnamlib/fmt_ga/leaf_store.py @@ -16,6 +16,9 @@ # =*= License: GPL-3+ =*= +import obnamlib + + class LeafStoreInterface(object): # pragma: no cover def put_leaf(self, leaf): @@ -38,3 +41,20 @@ class InMemoryLeafStore(LeafStoreInterface): def get_leaf(self, leaf_id): return self._leaves.get(leaf_id, None) + + +class LeafStore(LeafStoreInterface): # pragma: no cover + + def __init__(self): + self._blob_store = None + + def set_blob_store(self, blob_store): + self._blob_store = blob_store + + def put_leaf(self, leaf): + return self._blob_store.put_blob(leaf.as_dict()) + + def get_leaf(self, leaf_id): + leaf = obnamlib.CowLeaf() + leaf.from_dict(self._blob_store.get_blob(leaf_id)) + return leaf -- cgit v1.2.1