| 801 | } |
| 802 | |
| 803 | func replaceSortAndHeadOrTailWithTop(seq dag.Seq) dag.Seq { |
| 804 | walkT(reflect.ValueOf(&seq), func(seq dag.Seq) dag.Seq { |
| 805 | for i := 0; i+1 < len(seq); i++ { |
| 806 | sort, ok := seq[i].(*dag.SortOp) |
| 807 | if !ok { |
| 808 | continue |
| 809 | } |
| 810 | var limit int |
| 811 | exprs := sort.Exprs |
| 812 | reverse := sort.Reverse |
| 813 | switch op := seq[i+1].(type) { |
| 814 | case *dag.HeadOp: |
| 815 | limit = op.Count |
| 816 | case *dag.TailOp: |
| 817 | limit = op.Count |
| 818 | for i, e := range exprs { |
| 819 | exprs[i].Order = !e.Order |
| 820 | } |
| 821 | reverse = !reverse |
| 822 | default: |
| 823 | continue |
| 824 | } |
| 825 | if limit > 1048576 { |
| 826 | // Limit memory consumption since top doesn't |
| 827 | // spill to disk. |
| 828 | continue |
| 829 | } |
| 830 | seq[i] = &dag.TopOp{ |
| 831 | Kind: "TopOp", |
| 832 | Limit: limit, |
| 833 | Exprs: exprs, |
| 834 | Reverse: reverse && len(exprs) == 0, |
| 835 | } |
| 836 | seq.Delete(i+1, i+2) |
| 837 | } |
| 838 | return seq |
| 839 | }) |
| 840 | return seq |
| 841 | } |
| 842 | |
| 843 | func walkT[T any](v reflect.Value, post func(T) T) { |
| 844 | switch v.Kind() { |