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

            // Copy second run into temp array
            Buffer a = this.a; // For performance
            Buffer tmp = ensureCapacity(len2);
            s.copyRange(a, base2, tmp, 0, len2);

            int cursor1 = base1 + len1 - 1;  // Indexes into a
            int cursor2 = len2 - 1;          // Indexes into tmp array
            int dest = base2 + len2 - 1;     // Indexes into a

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

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

            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
         * appears to win consistently.
         */
                do {
                    assert len1 > 0 && len2 > 1;
                    if (c.compare(s.getKey(tmp, cursor2, key0), s.getKey(a, cursor1, key1)) < 0) {
                        s.copyElement(a, cursor1--, a, dest--);
                        count1++;
                        count2 = 0;
                        if (--len1 == 0)
                            break outer;
                    } else {
                        s.copyElement(tmp, cursor2--, a, dest--);
                        count2++;
                        count1 = 0;
                        if (--len2 == 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 > 0 && len2 > 1;
                    count1 = len1 - gallopRight(s.getKey(tmp, cursor2, key0), a, base1, len1, len1 - 1, c);
                    if (count1 != 0) {
                        dest -= count1;
                        cursor1 -= count1;
                        len1 -= count1;
                        s.copyRange(a, cursor1 + 1, a, dest + 1, count1);
                        if (len1 == 0)
                            break outer;
                    }
                    s.copyElement(tmp, cursor2--, a, dest--);
                    if (--len2 == 1)
                        break outer;

                    count2 = len2 - gallopLeft(s.getKey(a, cursor1, key0), tmp, 0, len2, len2 - 1, c);
                    if (count2 != 0) {
                        dest -= count2;
                        cursor2 -= count2;
                        len2 -= count2;
                        s.copyRange(tmp, cursor2 + 1, a, dest + 1, count2);
                        if (len2 <= 1)  // len2 == 1 || len2 == 0
                            break outer;
                    }
                    s.copyElement(a, cursor1--, a, dest--);
                    if (--len1 == 0)
                        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 (len2 == 1) {
                assert len1 > 0;
                dest -= len1;
                cursor1 -= len1;
                s.copyRange(a, cursor1 + 1, a, dest + 1, len1);
                s.copyElement(tmp, cursor2, a, dest); // Move first elt of run2 to front of merge
            } else if (len2 == 0) {
                throw new IllegalArgumentException(
                        "Comparison method violates its general contract!");
            } else {
                assert len1 == 0;
                assert len2 > 0;
                s.copyRange(tmp, 0, a, dest - (len2 - 1), len2);
            }
        }
Like mergeLo, except that this method should be called only if
len1 >= len2; mergeLo 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