diff --git a/swh/objstorage/backends/winery/__init__.py b/swh/objstorage/backends/winery/__init__.py new file mode 100644 --- /dev/null +++ b/swh/objstorage/backends/winery/__init__.py @@ -0,0 +1,66 @@ +# Copyright (C) 2021 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +import abc + +from swh.objstorage.exc import Error, ObjNotFoundError +from swh.objstorage.objstorage import ObjStorage, compute_hash + + +class WineryObjStorageDriver(object): + pass + + +class WineryObjStorage(ObjStorage, metaclass=abc.ABCMeta): + """ObjStorage that connect to a winery object storage + + https://wiki.softwareheritage.org/wiki/A_practical_approach_to_efficiently_store_100_billions_small_objects_in_Ceph + + Args: + kwargs: extra arguments are passed through to the winery + """ + + def __init__( + self, **kwargs, + ): + super().__init__(**kwargs) + self.driver = WineryObjStorageDriver() + + def check_config(self, *, check_write): + return True + + def __contains__(self, obj_id, *args, **kwargs): + return obj_id in self.driver + + def add(self, content, obj_id=None, check_presence=True, *args, **kwargs): + if check_presence is True: + if obj_id in self.driver: + return obj_id + if obj_id is None: + obj_id = compute_hash(content) + self.driver[obj_id] = content + return obj_id + + def get(self, obj_id, *args, **kwargs): + if obj_id not in self.driver: + raise ObjNotFoundError(obj_id) + return self.driver[obj_id] + + def check(self, obj_id, *args, **kwargs): + if obj_id not in self.driver: + raise ObjNotFoundError(obj_id) + if obj_id != compute_hash(self.driver[obj_id]): + raise Error(obj_id) + + def delete(self, obj_id, *args, **kwargs): + super().delete(obj_id) # Check delete permission + if obj_id not in self.driver: + raise ObjNotFoundError(obj_id) + del self.driver[obj_id] + return True + + def __iter__(self): + for k in sorted(self.driver.keys()): + yield k diff --git a/swh/objstorage/tests/test_objstorage_winery.py b/swh/objstorage/tests/test_objstorage_winery.py new file mode 100644 --- /dev/null +++ b/swh/objstorage/tests/test_objstorage_winery.py @@ -0,0 +1,18 @@ +# Copyright (C) 2021 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information +import unittest + +from ..backends.winery import WineryObjStorage +from .objstorage_testing import ObjStorageTestFixture + + +class TestWineryObjStorage(ObjStorageTestFixture, unittest.TestCase): + compression = "none" + + def setUp(self): + super().setUp() + self.url = "http://127.0.0.1/test" + self.storage = WineryObjStorage() + self.storage.driver = {}