33from typing import TYPE_CHECKING
44
55from dissect .database .ese .btree import BTree
6- from dissect .database .ese .exception import NoNeighbourPageError
6+ from dissect .database .ese .exception import KeyNotFoundError , NoNeighbourPageError
77from dissect .database .ese .record import Record
88
99if TYPE_CHECKING :
@@ -64,7 +64,28 @@ def reset(self) -> None:
6464 if self ._secondary :
6565 self ._secondary .reset ()
6666
67- def search (self , ** kwargs : RecordValue ) -> Record :
67+ def make_key (self , * args : RecordValue , ** kwargs : RecordValue ) -> bytes :
68+ """Generate a key for this index from the given values.
69+
70+ Args:
71+ *args: The values to generate a key for.
72+ **kwargs: The columns and values to generate a key for.
73+
74+ Returns:
75+ The generated key as bytes.
76+ """
77+ if not args and not kwargs :
78+ raise ValueError ("At least one value must be provided" )
79+
80+ if args and kwargs :
81+ raise ValueError ("Cannot mix positional and keyword arguments in make_key" )
82+
83+ if args and not len (args ) == 1 and not isinstance (args [0 ], list ):
84+ raise ValueError ("When using positional arguments, provide a single list of values" )
85+
86+ return self .index .make_key (args [0 ] if args else kwargs )
87+
88+ def search (self , * args : RecordValue , ** kwargs : RecordValue ) -> Record :
6889 """Search the index for the requested values.
6990
7091 Searching modifies the cursor state. Searching again will search from the current position.
@@ -76,7 +97,7 @@ def search(self, **kwargs: RecordValue) -> Record:
7697 Returns:
7798 A :class:`~dissect.database.ese.record.Record` object of the found record.
7899 """
79- key = self .index . make_key (kwargs )
100+ key = self .make_key (* args , ** kwargs )
80101 return self .search_key (key , exact = True )
81102
82103 def search_key (self , key : bytes , exact : bool = True ) -> Record :
@@ -90,13 +111,13 @@ def search_key(self, key: bytes, exact: bool = True) -> Record:
90111 self ._primary .search (key , exact )
91112 return self ._record ()
92113
93- def seek (self , ** kwargs : RecordValue ) -> None :
114+ def seek (self , * args : RecordValue , * *kwargs : RecordValue ) -> None :
94115 """Seek to the record with the given values.
95116
96117 Args:
97118 **kwargs: The columns and values to seek to.
98119 """
99- key = self .index . make_key (kwargs )
120+ key = self .make_key (* args , ** kwargs )
100121 self .search_key (key , exact = False )
101122
102123 def seek_key (self , key : bytes ) -> None :
@@ -130,7 +151,10 @@ def find_all(self, **kwargs: RecordValue) -> Iterator[Record]:
130151 other_columns = kwargs
131152
132153 # We need at least an exact match on the indexed columns
133- self .search (** indexed_columns )
154+ try :
155+ self .search (** indexed_columns )
156+ except KeyNotFoundError :
157+ return
134158
135159 current_key = self ._primary .node ().key
136160
0 commit comments