Copilot commented on code in PR #794:
URL: 
https://github.com/apache/skywalking-banyandb/pull/794#discussion_r2388601250


##########
banyand/trace/part.go:
##########
@@ -457,14 +457,14 @@ func (mp *memPart) mustInitFromTraces(ts *traces) {
                }
 
                if uncompressedSpansSizeBytes >= maxUncompressedSpanSize || tid 
!= tidPrev {
-                       bsw.MustWriteTrace(tidPrev, ts.spans[indexPrev:i], 
ts.tags[indexPrev:i], ts.timestamps[indexPrev:i])
+                       bsw.MustWriteTrace(tidPrev, ts.spans[indexPrev:i], 
ts.tags[indexPrev:i], ts.timestamps[indexPrev:i], ts.spanIDs[indexPrev:i])
                        tidPrev = tid
                        indexPrev = i
                        uncompressedSpansSizeBytes = 0
                }
                uncompressedSpansSizeBytes += uint64(len(ts.spans[i]))
        }
-       bsw.MustWriteTrace(tidPrev, ts.spans[indexPrev:], ts.tags[indexPrev:], 
ts.timestamps[indexPrev:])
+       bsw.MustWriteTrace(tidPrev, ts.spans[indexPrev:], ts.tags[indexPrev:], 
ts.timestamps[indexPrev:], ts.spanIDs[indexPrev:])

Review Comment:
   The slice operation `ts.spanIDs[indexPrev:i]` and `ts.spanIDs[indexPrev:]` 
could cause a panic if `ts.spanIDs` is shorter than expected. There should be a 
length check to ensure `ts.spanIDs` has at least the same number of elements as 
`ts.spans` before slicing.



##########
banyand/trace/block.go:
##########
@@ -275,7 +283,14 @@ func mustWriteSpansTo(sm *dataBlock, spans [][]byte, 
spanWriter *writer) {
        defer bigValuePool.Release(bb)
 
        sm.offset = spanWriter.bytesWritten
-       for _, span := range spans {
+       for i, span := range spans {
+               var spanID string
+               if i < len(spanIDs) {
+                       spanID = spanIDs[i]

Review Comment:
   The code allows `spanIDs` to be shorter than `spans`, resulting in empty 
span IDs being written for some spans. This inconsistency could cause issues 
during deserialization. Either ensure `spanIDs` has the same length as `spans` 
or handle the mismatch explicitly.



##########
pkg/query/logical/trace/trace_plan_distributed.go:
##########
@@ -170,12 +175,19 @@ func (p *distributedPlan) Execute(ctx context.Context) 
(iter.Iterator[model.Trac
        }
        sortIter := sort.NewItemIter(ct, p.desc)
        var result []*tracev1.InternalTrace
-       seen := make(map[string]bool)
+       seen := make(map[string]*tracev1.InternalTrace)
        for sortIter.Next() {
                trace := sortIter.Val().InternalTrace
-               if !seen[trace.TraceId] {
-                       seen[trace.TraceId] = true
+               if _, ok := seen[trace.TraceId]; !ok {
+                       seen[trace.TraceId] = trace
                        result = append(result, trace)
+               } else {
+                       for _, spanID := range trace.SpanIds {
+                               if 
!slices.Contains(seen[trace.TraceId].SpanIds, spanID) {
+                                       seen[trace.TraceId].SpanIds = 
append(seen[trace.TraceId].SpanIds, spanID)
+                                       seen[trace.TraceId].Spans = 
append(seen[trace.TraceId].Spans, trace.Spans...)
+                               }

Review Comment:
   Line 188 appends all spans from `trace.Spans` for every unique span ID 
found, which will result in duplicate spans being added multiple times. It 
should only append the specific span that corresponds to the current span ID 
being processed.



##########
banyand/trace/write_standalone.go:
##########
@@ -199,12 +204,17 @@ func processTraces(schemaRepo *schemaRepo, tracesInTable 
*tracesInTable, writeEv
                        len(is.indexRuleLocators), 
len(stm.GetSchema().GetTags()))
        }
 
+       return nil
+}
+
+func buildTagsAndMap(stm *trace, tracesInTable *tracesInTable, req 
*tracev1.WriteRequest) ([]*tagValue, map[string]*tagValue) {
        tags := make([]*tagValue, 0, len(stm.schema.Tags))
        tagMap := make(map[string]*tagValue, len(stm.schema.Tags))
        tagSpecs := stm.GetSchema().GetTags()
+
        for i := range tagSpecs {
                tagSpec := tagSpecs[i]
-               if tagSpec.Name == stm.schema.TraceIdTagName {
+               if tagSpec.Name == stm.schema.TraceIdTagName || tagSpec.Name == 
stm.schema.SpanIdTagName {

Review Comment:
   The condition skips both trace ID and span ID tags when building the tag 
map, but span ID is still needed for processing. Only trace ID should be 
skipped here, or there should be separate handling for span ID extraction.



##########
banyand/trace/part.go:
##########
@@ -457,14 +457,14 @@ func (mp *memPart) mustInitFromTraces(ts *traces) {
                }
 
                if uncompressedSpansSizeBytes >= maxUncompressedSpanSize || tid 
!= tidPrev {
-                       bsw.MustWriteTrace(tidPrev, ts.spans[indexPrev:i], 
ts.tags[indexPrev:i], ts.timestamps[indexPrev:i])
+                       bsw.MustWriteTrace(tidPrev, ts.spans[indexPrev:i], 
ts.tags[indexPrev:i], ts.timestamps[indexPrev:i], ts.spanIDs[indexPrev:i])

Review Comment:
   The slice operation `ts.spanIDs[indexPrev:i]` and `ts.spanIDs[indexPrev:]` 
could cause a panic if `ts.spanIDs` is shorter than expected. There should be a 
length check to ensure `ts.spanIDs` has at least the same number of elements as 
`ts.spans` before slicing.



##########
pkg/query/logical/trace/trace_plan_tag_filter.go:
##########
@@ -309,3 +320,60 @@ func (t *traceTagFilterPlan) Children() []logical.Plan {
 func (t *traceTagFilterPlan) Schema() logical.Schema {
        return t.s
 }
+
+type spanIDFilter struct {
+       targetSpanIDs []string
+}
+
+func newSpanIDFilter(spanIDs []string) *spanIDFilter {
+       return &spanIDFilter{
+               targetSpanIDs: spanIDs,
+       }
+}
+
+func (sf *spanIDFilter) matchSpanID(spanID string) bool {
+       for _, targetSpanID := range sf.targetSpanIDs {
+               if spanID == targetSpanID {
+                       return true
+               }
+       }
+       return false

Review Comment:
   The linear search through `targetSpanIDs` could be inefficient for large 
numbers of span IDs. Consider using a map[string]bool for O(1) lookup 
performance instead of O(n) linear search.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to