private void mergeLo(int base1, int len1, int base2, int len2) {
            assert len1 > 0 && len2 > 0 && base1 + len1 == base2;

            // Copy first run into temp array
            Buffer a = this.a; // For performance
            Buffer tmp = ensureCapacity(len1);
            s.copyRange(a, base1, tmp, 0, len1);

            int cursor1 = 0;       // Indexes into tmp array
            int cursor2 = base2;   // Indexes int a
            int dest = base1;      // Indexes int a

            // Move first element of second run and deal with degenerate cases
            s.copyElement(a, cursor2++, a, dest++);
            if (--len2 == 0) {
                s.copyRange(tmp, cursor1, a, dest, len1);
                return;
            }
            if (len1 == 1) {
                s.copyRange(a, cursor2, a, dest, len2);
                s.copyElement(tmp, cursor1, a, dest + len2); // Last elt of run 1 to end of merge
                return;
            }

            K key0 = s.newKey();
            K key1 = s.newKey();

            Comparator<? super K> c = this.c;  // Use local variable for performance
            int minGallop = this.minGallop;    //  "    "       "     "      "
            outer:
            while (true) {
                int count1 = 0; // Number of times in a row that first run won
                int count2 = 0; // Number of times in a row that second run won

        /*
         * Do the straightforward thing until (if ever) one run starts
         * winning consistently.
         */
                do {
                    assert len1 > 1 && len2 > 0;
                    if (c.compare(s.getKey(a, cursor2, key0), s.getKey(tmp, cursor1, key1)) < 0) {
                        s.copyElement(a, cursor2++, a, dest++);
                        count2++;
                        count1 = 0;
                        if (--len2 == 0)
                            break outer;
                    } else {
                        s.copyElement(tmp, cursor1++, a, dest++);
                        count1++;
                        count2 = 0;
                        if (--len1 == 1)
                            break outer;
                    }
                } while ((count1 | count2) < minGallop);

        /*
         * One run is winning so consistently that galloping may be a
         * huge win. So try that, and continue galloping until (if ever)
         * neither run appears to be winning consistently anymore.
         */
                do {
                    assert len1 > 1 && len2 > 0;
                    count1 = gallopRight(s.getKey(a, cursor2, key0), tmp, cursor1, len1, 0, c);
                    if (count1 != 0) {
                        s.copyRange(tmp, cursor1, a, dest, count1);
                        dest += count1;
                        cursor1 += count1;
                        len1 -= count1;
                        if (len1 <= 1) // len1 == 1 || len1 == 0
                            break outer;
                    }
                    s.copyElement(a, cursor2++, a, dest++);
                    if (--len2 == 0)
                        break outer;

                    count2 = gallopLeft(s.getKey(tmp, cursor1, key0), a, cursor2, len2, 0, c);
                    if (count2 != 0) {
                        s.copyRange(a, cursor2, a, dest, count2);
                        dest += count2;
                        cursor2 += count2;
                        len2 -= count2;
                        if (len2 == 0)
                            break outer;
                    }
                    s.copyElement(tmp, cursor1++, a, dest++);
                    if (--len1 == 1)
                        break outer;
                    minGallop--;
                } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);
                if (minGallop < 0)
                    minGallop = 0;
                minGallop += 2;  // Penalize for leaving gallop mode
            }  // End of "outer" loop
            this.minGallop = minGallop < 1 ? 1 : minGallop;  // Write back to field

            if (len1 == 1) {
                assert len2 > 0;
                s.copyRange(a, cursor2, a, dest, len2);
                s.copyElement(tmp, cursor1, a, dest + len2); //  Last elt of run 1 to end of merge
            } else if (len1 == 0) {
                throw new IllegalArgumentException(
                        "Comparison method violates its general contract!");
            } else {
                assert len2 == 0;
                assert len1 > 1;
                s.copyRange(tmp, cursor1, a, dest, len1);
            }
        }
Merges two adjacent runs in place, in a stable fashion.  The first
element of the first run must be greater than the first element of the
second run (a[base1] > a[base2]), and the last element of the first run
(a[base1 + len1-1]) must be greater than all elements of the second run.

For performance, this method should be called only when len1 <= len2;
its twin, mergeHi should be called if len1 >= len2.  (Either method
may be called if len1 == len2.)

@param base1 index of first element in first run to be merged
@param len1  length of first run to be merged (must be > 0)
@param base2 index of first element in second run to be merged
             (must be aBase + aLen)
@param len2  length of second run to be merged (must be > 0)
indexr-query-opt/src/main/java/org/apache/spark/util/collection/TimSort.java