timsort.js
/**
 * 
 * Like gallopLeft, except that if the range contains an element equal to
 * key, gallopRight returns the index after the rightmost equal element.
 * @param {Object} key 
 * @param {Array} a 
 * @param {Number} base 
 * @param {Number} len 
 * @param {Number} hint 
 * @param {Function} c 
 * @returns {Number}
 */
Like gallopLeft, except that if the range contains an element equal to
key, gallopRight returns the index after the rightmost equal element.
Like gallopLeft except that if the range contains an element equal to key gallopRight returns the index after the rightmost equal element .
function gallopRight(key, a, base, len, hint, c){
    let ofs = 1,
        lastOfs = 0;
    if (c(key, a[base + hint]) < 0) {
        let maxOfs = hint + 1;
        while (ofs < maxOfs && c(key, a[base + hint - ofs]) < 0) {
            lastOfs = ofs;
            ofs = (ofs << 1) + 1;
            if (ofs <= 0){
                ofs = maxOfs; 
            }  
        }
        if (ofs > maxOfs){
            ofs = maxOfs;
        } 
        let tmp = lastOfs;
        lastOfs = hint - ofs;
        ofs = hint - tmp;
    } else {
        let maxOfs = len - hint;
        while (ofs < maxOfs && c(key, a[base + hint + ofs]) >= 0) {
            lastOfs = ofs;
            ofs = (ofs << 1) + 1;
            if (ofs <= 0){
                ofs = maxOfs; 
            } 
        }
        if (ofs > maxOfs){
            ofs = maxOfs;
        } 
        lastOfs += hint;
        ofs += hint;
    }
    lastOfs++;
    while (lastOfs < ofs) {
        let m = lastOfs + ((ofs - lastOfs) >>> 1);
        if (c(key, a[base + m]) < 0){
            ofs = m;          
        }
        else{
            lastOfs = m + 1;  
        }
    }
    return ofs;
}
function gallopRight ( key , a , base , len , hint , c ) { let ofs = 1 , lastOfs = 0 ; if ( c ( key , a [ base + hint ] ) < 0 ) { let maxOfs = hint + 1 ; while ( ofs < maxOfs && c ( key , a [ base + hint - ofs ] ) < 0 ) { lastOfs = ofs ; ofs = ( ofs << 1 ) + 1 ; if ( ofs <= 0 ) { ofs = maxOfs ; } } if ( ofs > maxOfs ) { ofs = maxOfs ; } let tmp = lastOfs ; lastOfs = hint - ofs ; ofs = hint - tmp ; } else { let maxOfs = len - hint ; while ( ofs < maxOfs && c ( key , a [ base + hint + ofs ] ) >= 0 ) { lastOfs = ofs ; ofs = ( ofs << 1 ) + 1 ; if ( ofs <= 0 ) { ofs = maxOfs ; } } if ( ofs > maxOfs ) { ofs = maxOfs ; } lastOfs += hint ; ofs += hint ; } lastOfs ++ ; while ( lastOfs < ofs ) { let m = lastOfs + ( ( ofs - lastOfs ) >>> 1 ) ; if ( c ( key , a [ base + m ] ) < 0 ) { ofs = m ; } else { lastOfs = m + 1 ; } } return ofs ; }
Like gallopLeft, except that if the range contains an element equal to
 key, gallopRight returns the index after the rightmost equal element.
Like gallopLeft except that if the range contains an element equal to key gallopRight returns the index after the rightmost equal element .
//assert len > 0 && hint >= 0 && hint < len;
 // Gallop left until a[b+hint - ofs] <= key < a[b+hint - lastOfs]
 // int overflow
 // Make offsets relative to b
 // a[b + hint] <= key
 // Gallop right until a[b+hint + lastOfs] <= key < a[b+hint + ofs]
 // int overflow
 // Make offsets relative to b
 // assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;
 /*
    * Now a[b + lastOfs] <= key < a[b + ofs], so key belongs somewhere to
    * the right of lastOfs but no farther right than ofs.  Do a binary
    * search, with invariant a[b + lastOfs - 1] <= key < a[b + ofs].
    */ // key < a[b + m]
 // a[b + m] <= key
 //assert lastOfs == ofs;    // so a[b + ofs - 1] <= key < a[b + ofs]
