code: void sortBy(int[] vs, int lo, int len, long[] curr, long[] prev) {
  
          if (len < INSERTION_SORT_THRESHOLD) {
              insertionSortBy(vs, lo, len, curr, prev);
              return;
          }
  
          int split = len / 2;
  
          sortBy(vs, lo, split, curr, prev);
          sortBy(vs, lo + split, len - split, curr, prev);
  
          // sub arrays already sorted, no need to merge
          if (!less(vs[lo + split], vs[lo + split - 1], curr, prev)) return;
  
          merge(vs, lo, split, len, curr, prev);
      }
docs: Sort the values (using merge sort) in {@code vs} from {@code lo} (until
  {@code len}) by the {@code prev[]} and then {@code curr[]} invariants to
  determine rank. The values in {@code vs} are indices into the invariant
  arrays.
  
  @param vs   values (indices)
  @param lo   the first value to start sorting from
  @param len  the len of values to consider
  @param curr the current invariants
  @param prev the previous invariants