From 3f99844ae80f461b2b5856ea2c22b437e5407544 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Tue, 28 Jan 2025 10:37:40 -0800 Subject: [PATCH] replace lru_cache with specialized cache handling at the entry list level Signed-off-by: Andrew Whitehead --- .../python/aries_askar/bindings/handle.py | 10 ++++++++- wrappers/python/aries_askar/bindings/lib.py | 22 +++++++++++++++++++ wrappers/python/aries_askar/store.py | 13 +---------- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/wrappers/python/aries_askar/bindings/handle.py b/wrappers/python/aries_askar/bindings/handle.py index 29ca951b..4cfa5780 100644 --- a/wrappers/python/aries_askar/bindings/handle.py +++ b/wrappers/python/aries_askar/bindings/handle.py @@ -18,7 +18,7 @@ c_void_p, ) -from .lib import ByteBuffer, Lib, StrBuffer, finalize_struct +from .lib import ByteBuffer, Lib, StrBuffer, entry_cache, finalize_struct LOGGER = logging.getLogger(__name__) @@ -124,6 +124,7 @@ class EntryListHandle(ArcHandle): _dtor_ = "askar_entry_list_free" + @entry_cache def get_category(self, index: int) -> str: """Get the entry category.""" cat = StrBuffer() @@ -136,6 +137,7 @@ def get_category(self, index: int) -> str: ) return str(cat) + @entry_cache def get_name(self, index: int) -> str: """Get the entry name.""" name = StrBuffer() @@ -148,6 +150,7 @@ def get_name(self, index: int) -> str: ) return str(name) + @entry_cache def get_value(self, index: int) -> memoryview: """Get the entry value.""" val = ByteBuffer() @@ -160,6 +163,7 @@ def get_value(self, index: int) -> memoryview: ) return val.view + @entry_cache def get_tags(self, index: int) -> dict: """Get the entry tags.""" tags = StrBuffer() @@ -185,6 +189,7 @@ class KeyEntryListHandle(ArcHandle): _dtor_ = "askar_key_entry_list_free" + @entry_cache def get_algorithm(self, index: int) -> str: """Get the key algorithm.""" name = StrBuffer() @@ -197,6 +202,7 @@ def get_algorithm(self, index: int) -> str: ) return str(name) + @entry_cache def get_name(self, index: int) -> str: """Get the key name.""" name = StrBuffer() @@ -209,6 +215,7 @@ def get_name(self, index: int) -> str: ) return str(name) + @entry_cache def get_metadata(self, index: int) -> str: """Get for the key metadata.""" metadata = StrBuffer() @@ -221,6 +228,7 @@ def get_metadata(self, index: int) -> str: ) return str(metadata) + @entry_cache def get_tags(self, index: int) -> dict: """Get the key tags.""" tags = StrBuffer() diff --git a/wrappers/python/aries_askar/bindings/lib.py b/wrappers/python/aries_askar/bindings/lib.py index ab87cdb8..f0be5312 100644 --- a/wrappers/python/aries_askar/bindings/lib.py +++ b/wrappers/python/aries_askar/bindings/lib.py @@ -1,6 +1,7 @@ """Library instance and allocated buffer handling.""" import asyncio +import functools import itertools import logging import os @@ -48,6 +49,27 @@ } +def entry_cache(fn): + """Cache results for properties of individual entries.""" + + @functools.wraps(fn) + def wrapper(self, index: int): + if not hasattr(self, "_ecache"): + setattr(self, "_ecache", {}) + cache = self._ecache + ckey = (fn, index) + if ckey in cache: + return cache[ckey] + res = fn(self, index) + cache[ckey] = res + if isinstance(res, dict): + # make sure the cached copy is not mutated + res = dict(res) + return res + + return wrapper + + def _convert_log_level(level: Union[str, int, None]): if level is None or level == "-1": return -1 diff --git a/wrappers/python/aries_askar/store.py b/wrappers/python/aries_askar/store.py index 44409abc..3052632a 100644 --- a/wrappers/python/aries_askar/store.py +++ b/wrappers/python/aries_askar/store.py @@ -5,7 +5,6 @@ except ImportError: import json -from functools import lru_cache from typing import Optional, Sequence, Union from . import bindings @@ -32,25 +31,21 @@ def __init__(self, lst: EntryListHandle, pos: int): self._pos = pos @property - @lru_cache(maxsize=None) def category(self) -> str: """Accessor for the entry category.""" return self._list.get_category(self._pos) @property - @lru_cache(maxsize=None) def name(self) -> str: """Accessor for the entry name.""" return self._list.get_name(self._pos) @property - @lru_cache(maxsize=None) def value(self) -> bytes: """Accessor for the entry value.""" return bytes(self.raw_value) @property - @lru_cache(maxsize=None) def raw_value(self) -> memoryview: """Accessor for the entry raw value.""" return self._list.get_value(self._pos) @@ -61,7 +56,6 @@ def value_json(self) -> dict: return json.loads(self.value) @property - @lru_cache(maxsize=None) def tags(self) -> dict: """Accessor for the entry tags.""" return self._list.get_tags(self._pos) @@ -152,31 +146,26 @@ def __init__(self, lst: KeyEntryListHandle, pos: int): self._pos = pos @property - @lru_cache(maxsize=None) def algorithm(self) -> str: """Accessor for the key entry algorithm.""" return self._list.get_algorithm(self._pos) @property - @lru_cache(maxsize=None) def name(self) -> str: """Accessor for the key entry name.""" return self._list.get_name(self._pos) @property - @lru_cache(maxsize=None) def metadata(self) -> str: """Accessor for the key entry metadata.""" return self._list.get_metadata(self._pos) @property - @lru_cache(maxsize=None) def key(self) -> Key: - """Accessor for the entry metadata.""" + """Accessor for the key instance.""" return Key(self._list.load_key(self._pos)) @property - @lru_cache(maxsize=None) def tags(self) -> dict: """Accessor for the entry tags.""" return self._list.get_tags(self._pos)