openGauss之排序算子实现的代码走读

一.  前言   

​      本文主要走读openGauss来了解openGauss中排序算子是如何实现的。

二. 排序算子实现过程代码走读

       排序算子的实现入口在ExecSort中,以简单的order by为例,其代码的实现过程主要如下所示:

ExecSort
    if (!node->sort_Done) {
        for (;;) {
            slot = ExecProcNode(outer_node);  // 获取元组
            tuplesort_puttupleslot(tuple_sortstate, slot);  // 往内存中暂存元组
                puttuple_common(state, &stup);
                    switch (state->status) {
                       case TSS_INITIAL:
                           state->memtuples[state->memtupcount++] = *tuple; // 将元祖存放在内存中
                           if (...tate->memtupcount > state->bound * 2...) {  // 如果内存元组个数超过2倍的需要返回个数,转成堆方式排序(top n)
                               make_bounded_heap(state);
                                   state->status = TSS_BOUNDED;  // 切换到堆排序
                               return
                           } 
                           
                           if ((state->memtupcount < state->memtupsize))   // 内存充足但是又不能按照堆方式进行排序场景
                               return
                           // 如下将是内存无法放下所有元素场景
                           inittapes(state, true);  // 如果也不符合堆排序要求,就切换到磁盘落盘排序
                               state->status = TSS_BUILDRUNS;   // 磁盘落盘排序
                           dumptuples(state, false);   // 将元祖排序并且写到磁盘
                               dumpbatch(state, alltuples);
                                   tuplesort_sort_memtuples(state);   // 先对当前子串进行排序
                                   for (i = 0; i < memtupwrite; i++) {
                                       WRITETUP(....);     // 将当前有序的子串写入到磁盘
                                       state->memtupcount--;
                                    }
                       case TSS_BOUNDED:
                             // 如果是基于落盘的方式存储,先判断当前元组和堆顶元组
                             if (COMPARETUP(state, tuple, &state->memtuples[0]) <= 0)
                                  free_sort_tuple(state, tuple); // 如果当前元组小于堆顶元组,可以直接丢弃   
                             else
                                  free_sort_tuple(state, &state->memtuples[0]);  // 丢弃堆顶元组
                                  tuplesort_heap_replace_top(state, tuple);  // 将当前的元组插入到当前堆中
                       case TSS_BUILDRUNS:
                           dumptuples(state, false);  // 此处为处理为第二、三、四...子串落盘场景
                               dumpbatch(state, alltuples);  // 调用栈同上边
                    }
        }
    }
    tuplesort_performsort(tuple_sortstate);   // 排序
        switch (state->status) {
            case TSS_INITIAL:     // 内存排序
                tuplesort_sort_memtuples(state);
                   qsort_tuple    // 使用快速排序对元组进行排序
            case TSS_BOUNDED:     // 堆排序
                sort_bounded_heap(state);
            case TSS_BUILDRUNS:   // 磁盘排序
                dumptuples(state, true);  // 将最后一个字串进行落盘
                mergeruns(state);   // 将已经落盘的各个有序子串进行合并
        }
    tuplesort_gettupleslot   // 依次返回有序元祖
        tuplesort_gettuple_common
            switch (state->status) {
                case TSS_SORTEDINMEM:   // 直接内存中排序
                    *stup = state->memtuples[state->current++];
                    return
                case TSS_SORTEDONTAPE:  // 磁盘排序
                    READTUP(state, stup, state->result_tape, tuplen);
                    return
                case TSS_FINALMERGE:   // 返回前需要先合并
                    mergereadnext(state, srcTape, &newtup)  // 合并
                    tuplesort_heap_delete_top(state);
                    return
            }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值