@@ -279,13 +279,13 @@ func FilterProfileData(
279279
280280 // We want to filter by function name case-insensitive, so we need to lowercase the query.
281281 // We lower case the query here, so we don't have to do it for every sample.
282- filterQuery = strings .ToLower (filterQuery )
282+ filterQueryBytes := [] byte ( strings .ToLower (filterQuery ) )
283283 res := make ([]arrow.Record , 0 , len (records ))
284284 allValues := int64 (0 )
285285 allFiltered := int64 (0 )
286286
287287 for _ , r := range records {
288- filteredRecord , valueSum , filteredSum , err := filterRecord (ctx , tracer , pool , r , filterQuery )
288+ filteredRecord , valueSum , filteredSum , err := filterRecord (ctx , tracer , pool , r , filterQueryBytes )
289289 if err != nil {
290290 return nil , 0 , fmt .Errorf ("filter record: %w" , err )
291291 }
@@ -303,7 +303,7 @@ func filterRecord(
303303 tracer trace.Tracer ,
304304 pool memory.Allocator ,
305305 rec arrow.Record ,
306- filterQuery string ,
306+ filterQueryBytes [] byte ,
307307) (arrow.Record , int64 , int64 , error ) {
308308 r := profile .NewRecordReader (rec )
309309
@@ -316,16 +316,29 @@ func filterRecord(
316316 w := profile .NewWriter (pool , labelNames )
317317 defer w .RecordBuilder .Release ()
318318
319+ indexMatches := map [uint32 ]struct {}{}
320+ for i := 0 ; i < r .LineFunctionNameDict .Len (); i ++ {
321+ if bytes .Contains (bytes .ToLower (r .LineFunctionNameDict .Value (i )), filterQueryBytes ) {
322+ indexMatches [uint32 (i )] = struct {}{}
323+ }
324+ }
325+
326+ if len (indexMatches ) == 0 {
327+ return w .RecordBuilder .NewRecord (), math .Int64 .Sum (r .Value ), 0 , nil
328+ }
329+
319330 for i := 0 ; i < int (rec .NumRows ()); i ++ {
320331 lOffsetStart , lOffsetEnd := r .Locations .ValueOffsets (i )
321332 keepRow := false
322- for j := int (lOffsetStart ); j < int (lOffsetEnd ); j ++ {
323- llOffsetStart , llOffsetEnd := r .Lines .ValueOffsets (j )
324-
325- for k := int (llOffsetStart ); k < int (llOffsetEnd ); k ++ {
326- if r .LineFunctionNameIndices .IsValid (k ) && bytes .Contains (bytes .ToLower (r .LineFunctionNameDict .Value (int (r .LineFunctionNameIndices .Value (k )))), []byte (filterQuery )) {
327- keepRow = true
328- break
333+ if lOffsetStart < lOffsetEnd {
334+ firstStart , _ := r .Lines .ValueOffsets (int (lOffsetStart ))
335+ _ , lastEnd := r .Lines .ValueOffsets (int (lOffsetEnd - 1 ))
336+ for k := int (firstStart ); k < int (lastEnd ); k ++ {
337+ if r .LineFunctionNameIndices .IsValid (k ) {
338+ if _ , ok := indexMatches [r .LineFunctionNameIndices .Value (k )]; ok {
339+ keepRow = true
340+ break
341+ }
329342 }
330343 }
331344 }
0 commit comments