Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
diogok committed Dec 4, 2019
0 parents commit 6a9a63d
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist
__pycache__
Empty file added README.md
Empty file.
83 changes: 83 additions & 0 deletions py_matching_pattern/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@

from threading import Lock
from copy import deepcopy
from uuid import uuid4

class InvalidKeySize(Exception):
pass

class InvalidKeyCount(Exception):
pass

class KeyNotFound(Exception):
pass

class PatternMatchStore:

default =None

def __init__(self,keysize=1):
if keysize < 1:
raise InvalidKeySize

self.__db = {}
self.__stage = {}
self.__keysize=keysize
self.__lock = Lock()

self.default=uuid4()

def put(self,keys=[],value=None):
if(len(keys)<self.__keysize):
raise InvalidKeyCount

node=self.__stage
for n in range(self.__keysize):
key=keys[n]
if n == self.__keysize - 1:
node[key]=value
else:
if key not in node:
node[key]={}
node=node[key]

def clean(self):
self.__stage={}

def commit(self):
self.__lock.acquire(blocking=True,timeout=-1)
self.__db=deepcopy(self.__stage)
self.__lock.release()

def get(self,keys=[]):
if(len(keys)<self.__keysize):
raise InvalidKeyCount

self.__lock.acquire(blocking=True,timeout=-1)
value = self.__get(keys=keys)
self.__lock.release()

if value is None:
raise KeyNotFound

return value

def __default_filled(self,keys,n):
return (keys[:n]+([self.default]*(self.__keysize-n)))

def __get(self,keys=[]):
node=self.__db
for n in range(self.__keysize):
key=keys[n]

if key in node:
if n+1 == self.__keysize:
return node[key]
node=node[key]
continue
else:
if n > 0:
return self.__get(keys=self.__default_filled(keys=keys,n=n))

break
return None
9 changes: 9 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from setuptools import setup
import os

setup(
name="py_matching_pattern",
version=os.getenv("VERSION"),
packages=["py_matching_pattern"],
url='https://github.com/diogok/py_matching_pattern',
)
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#pass
82 changes: 82 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import unittest
import py_matching_pattern as core

class CoreTest(unittest.TestCase):

def test_basic(self):
mm = core.PatternMatchStore(keysize=3)
_=mm.default

mm.put(keys=["a","b","c"],value=1)
mm.put(keys=["a","b","b"],value=2)
mm.put(keys=["a","b",_],value=3)
mm.put(keys=["a",_,_],value=4)
mm.put(keys=["a",None,"c"],value=5)

mm.commit()

self.assertEqual(1,mm.get(keys=["a","b","c"]))
self.assertEqual(2,mm.get(keys=["a","b","b"]))
self.assertEqual(3,mm.get(keys=["a","b","d"]))
self.assertEqual(4,mm.get(keys=["a","c","d"]))
self.assertEqual(5,mm.get(keys=["a",None,"c"]))

def test_basic_unordered(self):
mm = core.PatternMatchStore(keysize=3)
d=mm.default

mm.put(keys=["a","b",d],value=3)
mm.put(keys=["a",'b',"b"],value=2)
mm.put(keys=["a",d,d],value=4)
mm.put(keys=["a","b","c"],value=1)

mm.commit()

self.assertEqual(1,mm.get(keys=["a","b","c"]))
self.assertEqual(2,mm.get(keys=["a","b","b"]))
self.assertEqual(3,mm.get(keys=["a","b","d"]))
self.assertEqual(4,mm.get(keys=["a","c","d"]))

def test_basic_clean(self):
mm = core.PatternMatchStore(keysize=3)

mm.put(keys=["a","b","c"],value=1)
mm.commit()
self.assertEqual(1,mm.get(keys=["a","b","c"]))

mm.clean()
mm.commit()
with self.assertRaises(core.KeyNotFound):
mm.get(keys=["a","b","c"])

def test_uncommited(self):
mm = core.PatternMatchStore(keysize=3)

mm.put(keys=["a","b","c"],value=1)
with self.assertRaises(core.KeyNotFound):
mm.get(keys=["a","b","c"])

def test_uncommited_clean(self):
mm = core.PatternMatchStore(keysize=3)

mm.put(keys=["a","b","c"],value=1)
mm.commit()
self.assertEqual(1,mm.get(keys=["a","b","c"]))

mm.clean()
self.assertEqual(1,mm.get(keys=["a","b","c"]))

def test_validate_all_leaf_have_default(self):
pass

def test_validate_conflicts(self):
pass

def test_invalid_keycount(self):
pass

def test_invalid_keysize(self):
pass

def test_value_not_found(self):
pass

0 comments on commit 6a9a63d

Please sign in to comment.