shep

Multi-state key stores using bit masks for python3
git clone git://git.defalsify.org/shep.git
Log | Files | Refs | LICENSE

commit 78a3df73bbf175805d950bd28a455c9e4085a82b
parent 320f56b3c1f89a0c3455b783d3f1dbb3c3a4a60d
Author: lash <dev@holbrook.no>
Date:   Mon, 31 Jan 2022 08:38:14 +0000

Complete base and alias inserts

Diffstat:
Mschiz/error.py | 4++++
Mschiz/state.py | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Mtests/test_state.py | 35++++++++++++++++++++++++++++++++++-
3 files changed, 108 insertions(+), 11 deletions(-)

diff --git a/schiz/error.py b/schiz/error.py @@ -1,2 +1,6 @@ class StateExists(Exception): pass + + +class StateInvalid(Exception): + pass diff --git a/schiz/state.py b/schiz/state.py @@ -3,7 +3,10 @@ import enum import logging # local imports -from .error import StateExists +from schiz.error import ( + StateExists, + StateInvalid, + ) logg = logging.getLogger(__name__) @@ -12,27 +15,84 @@ class State: def __init__(self, bits): self.__bits = bits + self.__limit = (1 << bits) - 1 self.__c = 0 self.__reverse = {} - def _persist(self): + def __store(self): pass + + def __is_pure(self, v): + c = 1 + for i in range(self.__bits): + if c & v > 0: + break + c <<= 1 + return c == v - def add(self, name): - if self.__c == self.__bits: - raise OverflowError(self.__c + 1) - - v = 1 << self.__c - - k = name.upper() + def __check_name(self, k): + k = k.upper() try: getattr(self, k) raise StateExists(k) except AttributeError: pass + return k - setattr(self, k, v) + def __check_cover(self, v): + z = 0 + c = 1 + for i in range(self.__bits): + if c & v > 0: + if self.__reverse.get(c) == None: + raise StateInvalid(v) + c <<= 1 + return c == v + + + def __check_value(self, v): + v = int(v) + if self.__reverse.get(v): + raise StateValueExists(v) + if v > self.__limit: + raise OverflowError(v) + return v + + + def __check(self, k, v): + k = self.__check_name(k) + v = self.__check_value(v) + return (k, v,) + + + def __set(self, k, v): + setattr(self, k, v) + self.__reverse[v] = k self.__c += 1 + + + def add(self, k): + v = 1 << self.__c + (k, v) = self.__check(k, v) + self.__set(k, v) + + + def alias(self, k, v): + (k, v) = self.__check(k, v) + if self.__is_pure(v): + raise ValueError('use add to add pure values') + self.__check_cover(v) + self.__set(k, v) + + +# def all(self): +# l = [] +# for k in dir(self): +# if k[0] == '_': +# continue +# if k.upper() != k: +# continue +# l.append(k) diff --git a/tests/test_state.py b/tests/test_state.py @@ -3,7 +3,10 @@ import unittest # local imports from schiz import State -from schiz.error import StateExists +from schiz.error import ( + StateExists, + StateInvalid, + ) class TestState(unittest.TestCase): @@ -31,5 +34,35 @@ class TestState(unittest.TestCase): states.add('foo') + def test_alias(self): + states = State(2) + states.add('foo') + states.add('bar') + states.alias('baz', states.FOO | states.BAR) + self.assertEqual(states.BAZ, 3) + + + def test_alias_limit(self): + states = State(2) + states.add('foo') + states.add('bar') + states.alias('baz', states.FOO | states.BAR) + + + def test_alias_nopure(self): + states = State(3) + with self.assertRaises(ValueError): + states.alias('foo', 4) + + + def test_alias_cover(self): + states = State(3) + states.add('foo') + states.add('bar') + with self.assertRaises(StateInvalid): + states.alias('baz', 5) + + + if __name__ == '__main__': unittest.main()