@@ -63,8 +63,8 @@ def __init__(self, data_dir, repo_dir):
63
63
self .db = data .DB (data_dir , readonly = True , dtscomp = self .dts_comp_support )
64
64
self .file_cache = {}
65
65
66
- def script (self , * args ):
67
- return script (* args , env = self .getEnv ())
66
+ def script (self , * args , input = None ):
67
+ return script (* args , input = input , env = self .getEnv ())
68
68
69
69
def scriptLines (self , * args ):
70
70
return scriptLines (* args , env = self .getEnv ())
@@ -403,20 +403,41 @@ def get_idents_defs(self, version, ident, family):
403
403
symbol_doccomments .append (SymbolInstance (path , docline ))
404
404
405
405
return symbol_definitions , symbol_references , symbol_doccomments
406
-
406
+
407
+ def get_files_and_zip (self , version , syms ):
408
+ batch = b"\n " .join ([f"{ version } :{ sym .path } " .encode () for sym in syms ])
409
+ batch_res = self .script ('get-files-batch' , input = batch )
410
+
411
+ # See https://git-scm.com/docs/git-cat-file#_batch_output for the format:
412
+ #
413
+ # <oid> SP <type> SP <size> LF
414
+ # <contents> LF
415
+ # <oid> SP <type> SP <size> LF
416
+ # <contents> LF
417
+ # <oid> SP <type> SP <size> LF
418
+ # <contents> LF
419
+ #
420
+ for sym in syms :
421
+ meta , batch_res = batch_res .split (b"\n " , 1 )
422
+ _ , _ , size = meta .split (b" " )
423
+ size = int (size ) + 1 # newline after each file
424
+ content = batch_res [:size ].split (b"\n " )
425
+ batch_res = batch_res [size :]
426
+ yield sym , content
427
+
428
+
407
429
def get_peeks_of_syms (self , version , symbol_definitions , symbol_references ):
408
430
409
431
peeks = {}
410
432
411
433
def request_peeks (syms ):
412
434
if len (syms ) > 100 :
413
435
return
414
- for sym in syms :
436
+
437
+ for sym , content in self .get_files_and_zip (version , syms ):
415
438
if sym .path not in peeks :
416
439
peeks [sym .path ] = {}
417
440
418
- content = self .scriptLines ('get-file' , version , "/" + sym .path )
419
-
420
441
if type (sym .line ) is int :
421
442
lines = (sym .line ,)
422
443
else :
@@ -455,6 +476,24 @@ def cmd_file(q, version, path, **kwargs):
455
476
code = q .query ("file" , version , path )
456
477
print (code )
457
478
479
+ def profile (q , family , version , ident ):
480
+ return q .query ('ident' , version , ident , family )
481
+
482
+ def cmd_profile (q , family , version , ident , ** kwargs ):
483
+ import cProfile
484
+ cProfile .runctx ('profile(q, family, version, ident)' ,
485
+ globals = {
486
+ "profile" : profile
487
+ },
488
+ locals = {
489
+ "q" : q ,
490
+ "family" : family ,
491
+ "version" : version ,
492
+ "ident" : ident ,
493
+ },
494
+ sort = 'tottime'
495
+ )
496
+
458
497
if __name__ == "__main__" :
459
498
import argparse
460
499
@@ -473,5 +512,10 @@ def cmd_file(q, version, path, **kwargs):
473
512
file_subparser .add_argument ('path' , type = str , help = "The path of the source file" )
474
513
file_subparser .set_defaults (func = cmd_file , q = query )
475
514
515
+ profile_subparser = subparsers .add_parser ('perf' , help = "Get a source file" )
516
+ profile_subparser .add_argument ('ident' , type = str , help = "The name of the identifier" )
517
+ profile_subparser .add_argument ('family' , type = str , help = "The file family requested" )
518
+ profile_subparser .set_defaults (func = cmd_profile , q = query )
519
+
476
520
args = parser .parse_args ()
477
521
args .func (** vars (args ))
0 commit comments