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 list_async (self , primary_namespace : "str" ,secondary_namespace : "str" ) -> "typing.List[str]" :
11+ pass
12+
13+ @abstractmethod
14+ def list_sync (self , primary_namespace : "str" ,secondary_namespace : "str" ) -> "typing.List[str]" :
15+ pass
16+
17+ @abstractmethod
18+ async def read_async (self , primary_namespace : "str" ,secondary_namespace : "str" ,key : "str" ) -> "typing.List[int]" :
19+ pass
20+
21+ @abstractmethod
22+ def read_sync (self , primary_namespace : "str" ,secondary_namespace : "str" ,key : "str" ) -> "typing.List[int]" :
23+ pass
24+
25+ @abstractmethod
26+ async def remove_async (self , primary_namespace : "str" ,secondary_namespace : "str" ,key : "str" ,lazy : "bool" ) -> None :
27+ pass
28+
29+ @abstractmethod
30+ def remove_sync (self , primary_namespace : "str" ,secondary_namespace : "str" ,key : "str" ,lazy : "bool" ) -> None :
31+ pass
32+
33+ @abstractmethod
34+ async def write_async (self , primary_namespace : "str" ,secondary_namespace : "str" ,key : "str" ,buf : "typing.List[int]" ) -> None :
35+ pass
36+
37+ @abstractmethod
38+ def write_sync (self , primary_namespace : "str" ,secondary_namespace : "str" ,key : "str" ,buf : "typing.List[int]" ) -> None :
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+ # KVStoreSync methods
59+ def list_sync (self , primary_namespace : str , secondary_namespace : str ) -> List [str ]:
60+ with self ._lock :
61+ namespace_key = (primary_namespace , secondary_namespace )
62+ if namespace_key in self .storage :
63+ return list (self .storage [namespace_key ].keys ())
64+ return []
65+
66+ def read_sync (self , primary_namespace : str , secondary_namespace : str , key : str ) -> List [int ]:
67+ with self ._lock :
68+ print (f"[{ self .name } ] READ: { primary_namespace } /{ secondary_namespace } /{ key } " )
69+ namespace_key = (primary_namespace , secondary_namespace )
70+
71+ if namespace_key not in self .storage :
72+ print (f" -> namespace not found, keys: { list (self .storage .keys ())} " )
73+ raise IoError .NotFound (f"Namespace not found: { primary_namespace } /{ secondary_namespace } " )
74+
75+ if key not in self .storage [namespace_key ]:
76+ print (f" -> key not found, keys: { list (self .storage [namespace_key ].keys ())} " )
77+ raise IoError .NotFound (f"Key not found: { key } " )
78+
79+ data = self .storage [namespace_key ][key ]
80+ print (f" -> returning { len (data )} bytes" )
81+ return data
82+
83+ def write_sync (self , primary_namespace : str , secondary_namespace : str , key : str , buf : List [int ]) -> None :
84+ with self ._lock :
85+ namespace_key = (primary_namespace , secondary_namespace )
86+ if namespace_key not in self .storage :
87+ self .storage [namespace_key ] = {}
88+
89+ self .storage [namespace_key ][key ] = buf .copy ()
90+
91+ def remove_sync (self , primary_namespace : str , secondary_namespace : str , key : str , lazy : bool ) -> None :
92+ with self ._lock :
93+ namespace_key = (primary_namespace , secondary_namespace )
94+ if namespace_key not in self .storage :
95+ raise IoError .NotFound (f"Namespace not found: { primary_namespace } /{ secondary_namespace } " )
96+
97+ if key not in self .storage [namespace_key ]:
98+ raise IoError .NotFound (f"Key not found: { key } " )
99+
100+ del self .storage [namespace_key ][key ]
101+
102+ if not self .storage [namespace_key ]:
103+ del self .storage [namespace_key ]
104+
105+ # KVStore methods
106+ async def list_async (self , primary_namespace : str , secondary_namespace : str ) -> List [str ]:
107+ return self .list_sync (primary_namespace , secondary_namespace )
108+
109+ async def read_async (self , primary_namespace : str , secondary_namespace : str , key : str ) -> List [int ]:
110+ return self .read_sync (primary_namespace , secondary_namespace , key )
111+
112+ async def write_async (self , primary_namespace : str , secondary_namespace : str , key : str , buf : List [int ]) -> None :
113+ self .write_sync (primary_namespace , secondary_namespace , key , buf )
114+
115+ async def remove_async (self , primary_namespace : str , secondary_namespace : str , key : str , lazy : bool ) -> None :
116+ self .remove_sync (primary_namespace , secondary_namespace , key , lazy )
117+
118+
0 commit comments