1+ import threading
2+
3+ from abc import ABC , abstractmethod
4+ from typing import List
5+
6+ from ldk_node import IoError
7+
8+ class AbstractKvStore (ABC ):
9+ @abstractmethod
10+ async def read_async (self , primary_namespace : "str" ,secondary_namespace : "str" ,key : "str" ) -> "List[int]" :
11+ pass
12+
13+ @abstractmethod
14+ async def write_async (self , primary_namespace : "str" ,secondary_namespace : "str" ,key : "str" ,buf : "List[int]" ) -> None :
15+ pass
16+
17+ @abstractmethod
18+ async def remove_async (self , primary_namespace : "str" ,secondary_namespace : "str" ,key : "str" ,lazy : "bool" ) -> None :
19+ pass
20+
21+ @abstractmethod
22+ async def list_async (self , primary_namespace : "str" ,secondary_namespace : "str" ) -> "List[str]" :
23+ pass
24+
25+ @abstractmethod
26+ def read (self , primary_namespace : "str" ,secondary_namespace : "str" ,key : "str" ) -> "List[int]" :
27+ pass
28+
29+ @abstractmethod
30+ def write (self , primary_namespace : "str" ,secondary_namespace : "str" ,key : "str" ,buf : "List[int]" ) -> None :
31+ pass
32+
33+ @abstractmethod
34+ def remove (self , primary_namespace : "str" ,secondary_namespace : "str" ,key : "str" ,lazy : "bool" ) -> None :
35+ pass
36+
37+ @abstractmethod
38+ def list (self , primary_namespace : "str" ,secondary_namespace : "str" ) -> "List[str]" :
39+ pass
40+
41+ class TestKvStore (AbstractKvStore ):
42+ def __init__ (self , name : str ):
43+ self .name = name
44+ # Storage structure: {(primary_ns, secondary_ns): {key: [bytes]}}
45+ self .storage = {}
46+ self ._lock = threading .Lock ()
47+
48+ def dump (self ):
49+ print (f"\n [{ self .name } ] Store contents:" )
50+ for (primary_ns , secondary_ns ), keys_dict in self .storage .items ():
51+ print (f" Namespace: ({ primary_ns !r} , { secondary_ns !r} )" )
52+ for key , data in keys_dict .items ():
53+ print (f" Key: { key !r} -> { len (data )} bytes" )
54+ # Optionally show first few bytes
55+ preview = data [:20 ] if len (data ) > 20 else data
56+ print (f" Data preview: { preview } ..." )
57+
58+ def read (self , primary_namespace : str , secondary_namespace : str , key : str ) -> List [int ]:
59+ with self ._lock :
60+ namespace_key = (primary_namespace , secondary_namespace )
61+
62+ if namespace_key not in self .storage :
63+ raise IoError .NotFound ()
64+
65+ if key not in self .storage [namespace_key ]:
66+ raise IoError .NotFound ()
67+
68+ return list (self .storage [namespace_key ][key ])
69+
70+ def write (self , primary_namespace : str , secondary_namespace : str , key : str , buf : List [int ]) -> None :
71+ with self ._lock :
72+ namespace_key = (primary_namespace , secondary_namespace )
73+ if namespace_key not in self .storage :
74+ self .storage [namespace_key ] = {}
75+
76+ self .storage [namespace_key ][key ] = list (buf )
77+
78+ def remove (self , primary_namespace : str , secondary_namespace : str , key : str , lazy : bool ) -> None :
79+ with self ._lock :
80+ namespace_key = (primary_namespace , secondary_namespace )
81+ if namespace_key not in self .storage :
82+ raise IoError .NotFound ()
83+
84+ if key not in self .storage [namespace_key ]:
85+ raise IoError .NotFound ()
86+
87+ del self .storage [namespace_key ][key ]
88+
89+ if not self .storage [namespace_key ]:
90+ del self .storage [namespace_key ]
91+
92+ def list (self , primary_namespace : str , secondary_namespace : str ) -> List [str ]:
93+ with self ._lock :
94+ namespace_key = (primary_namespace , secondary_namespace )
95+ if namespace_key in self .storage :
96+ return sorted (self .storage [namespace_key ].keys ())
97+ return []
98+
99+ async def read_async (self , primary_namespace : str , secondary_namespace : str , key : str ) -> List [int ]:
100+ return self .read (primary_namespace , secondary_namespace , key )
101+
102+ async def write_async (self , primary_namespace : str , secondary_namespace : str , key : str , buf : List [int ]) -> None :
103+ self .write (primary_namespace , secondary_namespace , key , buf )
104+
105+ async def remove_async (self , primary_namespace : str , secondary_namespace : str , key : str , lazy : bool ) -> None :
106+ self .remove (primary_namespace , secondary_namespace , key , lazy )
107+
108+ async def list_async (self , primary_namespace : str , secondary_namespace : str ) -> List [str ]:
109+ return self .list (primary_namespace , secondary_namespace )
110+
0 commit comments