This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch trace/sidx
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git

commit d82f5343a8ba5604e46c27cacdf9f03a477fc0f1
Author: Gao Hongtao <[email protected]>
AuthorDate: Sat Aug 30 20:33:47 2025 +0800

    Enhance query result handling by storing the original sidx order in the 
queryResult struct.
---
 banyand/trace/query.go | 63 +++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 55 insertions(+), 8 deletions(-)

diff --git a/banyand/trace/query.go b/banyand/trace/query.go
index 822d518c..07b70afd 100644
--- a/banyand/trace/query.go
+++ b/banyand/trace/query.go
@@ -133,8 +133,12 @@ func (t *trace) Query(ctx context.Context, tqo 
model.TraceQueryOptions) (model.T
                        if sidxErr != nil {
                                t.l.Warn().Err(sidxErr).Str("sidx", 
sidxName).Msg("sidx query failed, falling back to normal query")
                        } else if len(traceIDs) > 0 {
+                               // Store original sidx order before sorting for 
partIter
+                               result.originalSidxOrder = make([]string, 
len(traceIDs))
+                               copy(result.originalSidxOrder, traceIDs)
+
                                qo.traceIDs = traceIDs
-                               sort.Strings(qo.traceIDs)
+                               sort.Strings(qo.traceIDs) // Sort for partIter 
efficiency
                        }
                }
        }
@@ -201,13 +205,14 @@ func (t *trace) searchBlocks(ctx context.Context, result 
*queryResult, parts []*
 }
 
 type queryResult struct {
-       ctx           context.Context
-       tagProjection *model.TagProjection
-       data          []*blockCursor
-       snapshots     []*snapshot
-       segments      []storage.Segment[*tsTable, option]
-       hit           int
-       loaded        bool
+       ctx               context.Context
+       tagProjection     *model.TagProjection
+       data              []*blockCursor
+       snapshots         []*snapshot
+       segments          []storage.Segment[*tsTable, option]
+       originalSidxOrder []string // Store original sidx order for final 
sorting
+       hit               int
+       loaded            bool
 }
 
 func (qr *queryResult) Pull() *model.TraceResult {
@@ -263,6 +268,12 @@ func (qr *queryResult) Pull() *model.TraceResult {
                        qr.data = append(qr.data[:index], qr.data[index+1:]...)
                }
                qr.loaded = true
+
+               // Resort data according to original sidx order if available
+               if len(qr.originalSidxOrder) > 0 {
+                       qr.resortDataBySidxOrder()
+               }
+
                heap.Init(qr)
        }
        if len(qr.data) == 0 {
@@ -279,6 +290,42 @@ func (qr *queryResult) Pull() *model.TraceResult {
        return qr.merge()
 }
 
+// resortDataBySidxOrder reorders the data to match the original sidx order.
+func (qr *queryResult) resortDataBySidxOrder() {
+       if len(qr.originalSidxOrder) == 0 || len(qr.data) == 0 {
+               return
+       }
+
+       // Create a map from trace ID to its position in the original sidx order
+       traceIDToOrder := make(map[string]int)
+       for i, traceID := range qr.originalSidxOrder {
+               traceIDToOrder[traceID] = i
+       }
+
+       // Sort data according to the original sidx order
+       sort.Slice(qr.data, func(i, j int) bool {
+               traceIDi := qr.data[i].bm.traceID
+               traceIDj := qr.data[j].bm.traceID
+
+               orderi, existi := traceIDToOrder[traceIDi]
+               orderj, existj := traceIDToOrder[traceIDj]
+
+               // If both trace IDs are in the original order, use that 
ordering
+               if existi && existj {
+                       return orderi < orderj
+               }
+               // If only one is in the original order, prioritize it
+               if existi {
+                       return true
+               }
+               if existj {
+                       return false
+               }
+               // If neither is in the original order, use alphabetical 
ordering
+               return traceIDi < traceIDj
+       })
+}
+
 func (qr *queryResult) Release() {
        for i, v := range qr.data {
                releaseBlockCursor(v)

Reply via email to