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