func (p VersionPtrs) multikeyRadixSort(tmp []*Version, keyIndex uint8) {
	// Some fields can be negative and need to get a bump. (Mind order in memory!)
	// As "alpha" is the lowest one, use its absolute value.
	var fieldAdjustment uint64 = 0
	switch keyIndex {
	case 3, 8:
		fieldAdjustment = (-alpha) << 32
	case 4, 9:
		fieldAdjustment = (-alpha)
	}

	// Collate the histogram.
	var offset [256]int
	for _, v := range p {
		if v == nil {
			continue
		}
		k := uint8(twoFieldKey(&v.version, fieldAdjustment, uint8(keyIndex)))
		offset[k]++
	}
	watermark := offset[0] - offset[0] // 'watermark' will finally be the total tally.
	for i, count := range offset {
		offset[i] = watermark
		watermark += count
	}

	// Setup an unordered copy.
	// The allocated space will subsequently be recycled as scratch space.
	if len(tmp) >= len(p) {
		tmp = tmp[:len(p)]
		copy(tmp, p)
	} else {
		tmp = append(tmp[:0], p...)
	}
	for i := watermark; i < len(p); i++ {
		p[i] = nil // Fill the tail end with the 'nil' we'll be skipping.
	}

	// Order from 'tmp' into 'p'.
	for _, v := range tmp {
		if v == nil {
			continue
		}
		k := uint8(twoFieldKey(&v.version, fieldAdjustment, uint8(keyIndex)))
		p[offset[k]] = v
		offset[k]++
	}

	p.multikeyRadixSortDescent(tmp, keyIndex, offset)
}
// multikeyRadixSort exploits the typical distribution of Version values
// to use  two keys at once  in a radix-sort run.
multikeyRadixSort exploits the typical distribution of Version values
to use  two keys at once  in a radix-sort run.
// multikeyRadixSort exploits the typical distribution of Version values // to use two keys at once in a radix - sort run .
func (p VersionPtrs) multikeyRadixSort(tmp []*Version, keyIndex uint8) {
	var fieldAdjustment uint64 = 0
	switch keyIndex {
	case 3, 8:
		fieldAdjustment = (-alpha) << 32
	case 4, 9:
		fieldAdjustment = (-alpha)
	}
	var offset [256]int
	for _, v := range p {
		if v == nil {
			continue
		}
		k := uint8(twoFieldKey(&v.version, fieldAdjustment, uint8(keyIndex)))
		offset[k]++
	}
	watermark := offset[0] - offset[0] 
	for i, count := range offset {
		offset[i] = watermark
		watermark += count
	}
	if len(tmp) >= len(p) {
		tmp = tmp[:len(p)]
		copy(tmp, p)
	} else {
		tmp = append(tmp[:0], p...)
	}
	for i := watermark; i < len(p); i++ {
		p[i] = nil 
	}
	for _, v := range tmp {
		if v == nil {
			continue
		}
		k := uint8(twoFieldKey(&v.version, fieldAdjustment, uint8(keyIndex)))
		p[offset[k]] = v
		offset[k]++
	}
	p.multikeyRadixSortDescent(tmp, keyIndex, offset)
}
func ( p VersionPtrs ) multikeyRadixSort ( tmp [ ] * Version , keyIndex uint8 ) { var fieldAdjustment uint64 = 0 switch keyIndex { case 3 , 8 : fieldAdjustment = ( - alpha ) << 32 case 4 , 9 : fieldAdjustment = ( - alpha ) } var offset [ 256 ] int for _ , v := range p { if v == nil { continue } k := uint8 ( twoFieldKey ( & v . version , fieldAdjustment , uint8 ( keyIndex ) ) ) offset [ k ] ++ } watermark := offset [ 0 ] - offset [ 0 ] for i , count := range offset { offset [ i ] = watermark watermark += count } if len ( tmp ) >= len ( p ) { tmp = tmp [ : len ( p ) ] copy ( tmp , p ) } else { tmp = append ( tmp [ : 0 ] , p ... ) } for i := watermark ; i < len ( p ) ; i ++ { p [ i ] = nil } for _ , v := range tmp { if v == nil { continue } k := uint8 ( twoFieldKey ( & v . version , fieldAdjustment , uint8 ( keyIndex ) ) ) p [ offset [ k ] ] = v offset [ k ] ++ } p . multikeyRadixSortDescent ( tmp , keyIndex , offset ) }
multikeyRadixSort exploits the typical distribution of Version values
to use  two keys at once  in a radix-sort run.
multikeyRadixSort exploits the typical distribution of Version values to use two keys at once in a radix - sort run .
// Some fields can be negative and need to get a bump. (Mind order in memory!) // As "alpha" is the lowest one, use its absolute value. // Collate the histogram. // 'watermark' will finally be the total tally. // Setup an unordered copy. // The allocated space will subsequently be recycled as scratch space. // Fill the tail end with the 'nil' we'll be skipping. // Order from 'tmp' into 'p'.