Skip to content

Commit 0caa958

Browse files
committed
Added ad_model collection to Python global provDB tool
Added functions for database filtering to Python tool that build the jx9 query from a list of filters and comparison ops Added functions to list keys and collections in the database to the Python tool
1 parent 6c927dc commit 0caa958

2 files changed

Lines changed: 102 additions & 0 deletions

File tree

scripts/provdb_analyze.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,101 @@ def summarizeProfile(fprofile):
178178
print("(name='%s') (total excl. time=%es) (count=%d) (avg. excl. time=%es) (runtime fraction=%e)" % (f,finfo['excl_time_tot'],finfo['count'],finfo['excl_time_mean'],finfo['frac_time']) )
179179

180180

181+
def getKeys(interface, collection):
182+
if(len(interface.getShards()) == 0):
183+
return None
184+
pvars = {'keys'}
185+
pcode = """$keys = [];
186+
$member = db_fetch('%s');
187+
if($member != NULL){
188+
foreach ( $member as $key , $value){
189+
if(is_numeric($value) || is_string($value)){
190+
array_push($keys, $key);
191+
}
192+
}
193+
}""" % collection
194+
ret = json.loads(interface.getShard(0).execute(pcode,pvars)['keys'])
195+
return ret
196+
197+
198+
def genFilterFunc(filter_list):
199+
if(len(filter_list) == 0):
200+
return None
201+
202+
filter_func = "function($f){return "
203+
for f in filter_list:
204+
if(isinstance(f,str)):
205+
filter_func += " " + f + " "
206+
elif(isinstance(f,tuple)):
207+
if(len(f) != 3):
208+
print("Expect filter to be a tuple containing a key, comparison operator and value")
209+
sys.exit(1)
210+
key = f[0]
211+
212+
v = f[2]
213+
if(isinstance(v,str)):
214+
v = "\"%s\"" % v
215+
216+
op = f[1]
217+
if(op == "contains"):
218+
#Special function: string contains
219+
filter_func += "substr_count($f[\"%s\"], %s) > 0" % (key,v)
220+
else:
221+
filter_func += "$f[\"%s\"] %s %s" % (key,op,v)
222+
223+
filter_func += "; }"
224+
return filter_func
225+
226+
def _listKeys(db,collection_name):
227+
j = json.loads(db.getCollection(collection_name).fetch(0))
228+
return j.keys()
229+
230+
def listKeys(interface, collection_name):
231+
if(interface.getNshards() == 0):
232+
return []
233+
return _listKeys(interface.getShard(0),collection_name)
234+
235+
def listGlobalKeys(interface, collection_name):
236+
return _listKeys(interface.getGlobalDB(),collection_name)
237+
238+
239+
#filter_list : a list of filters and logical operations
240+
#Filters have a tuple form: (key, comparison operator, value)
241+
# comparison operator can be ==, !=, <, >
242+
# special operator: "contains" for substring filtering
243+
#Logical operations between filters are input as strings, support "(", ")", "&&", "||"
244+
#Examples:
245+
# anom = anl.filterDatabase(pdb, 'anomalies', [ ('__id','==',0) ]) #__id == 0
246+
#
247+
# anom = anl.filterDatabase(pdb, 'anomalies', [ ('exit','==',1648661837676928), "&&", ("fid","==",490) ])
248+
#
249+
# anom = anl.filterDatabase(pdb, 'anomalies', [ '(' , ('fid','==', 490), "||", ("fid","==",491), ')' , '&&' , ("rid","==",0) ])
250+
#
251+
# anom = anl.filterDatabase(pdb, 'anomalies', [ ("func","contains","Kokkos") ])
252+
def filterDatabase(interface, collection_name, filter_list):
253+
if(interface.getNshards() == 0):
254+
return None
255+
256+
filter_func = genFilterFunc(filter_list)
257+
258+
print("Filtering with function: %s" % filter_func)
259+
260+
results = []
261+
for s in range(interface.getNshards()):
262+
results += [ json.loads(x) for x in interface.getShard(s).filter(collection_name, filter_func) ]
263+
return results
264+
265+
def filterGlobalDatabase(interface, collection_name, filter_list):
266+
filter_func = genFilterFunc(filter_list)
267+
268+
print("Filtering with function: %s" % filter_func)
269+
270+
return [ json.loads(x) for x in interface.getGlobalDB().filter(collection_name, filter_func) ]
271+
272+
273+
274+
275+
181276

182277
if __name__ == '__main__':
183278
argc = len(sys.argv)

scripts/provdb_interact.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ def getCollection(self, which_coll):
6666
sys.exit(1)
6767
return col
6868

69+
def listCollections(self):
70+
return ['anomalies','normalexecs','metadata']
6971

7072

7173
class provDBglobal(provDBclientBase):
@@ -77,6 +79,7 @@ def __init__(self,client,address,db_name,create=False):
7779
#Initialize collections
7880
self.func_stats = self._openCollection('func_stats',create=create)
7981
self.counter_stats = self._openCollection('counter_stats',create=create)
82+
self.ad_model = self._openCollection('ad_model',create=create)
8083

8184
def __del__(self):
8285
del self.func_stats
@@ -88,11 +91,15 @@ def getCollection(self, which_coll):
8891
col = self.func_stats
8992
elif which_coll == "counter_stats":
9093
col = self.counter_stats
94+
elif which_coll == "ad_model":
95+
col = self.ad_model
9196
else:
9297
print("Invalid collection")
9398
sys.exit(1)
9499
return col
95100

101+
def listCollections(self):
102+
return ['func_stats','counter_stats','ad_model']
96103

97104

98105

0 commit comments

Comments
 (0)