func SortedInsert(items []*Trade, add *Trade, maxSize int, comparator func(a, b *Trade) int) (sortedItems []*Trade, pop *Trade, err error) {
	if maxSize <= 0 {
		panic("MAX_SIZE_ZERO")
	}
	itemsLen := len(items)
	if itemsLen > maxSize {
		panic("ITEMS_SIZE")
	}
	if itemsLen == 0 {
		items = append(items, add)
		return items, nil, nil
	}
	isFull := (itemsLen == maxSize)
	if isFull && comparator(items[itemsLen-1], add) <= 0 {
		return items, add, nil
	}
	lo, hi := 0, itemsLen
	for lo < hi {
		mid := (hi-lo)/2 + lo
		if comparator(items[mid], add) <= 0 {
			lo = mid + 1
		} else {
			hi = mid
		}
	}
	items = append(items[:lo], append([]*Trade{add}, items[lo:]...)...)
	if isFull {
		pop = items[itemsLen]
		items = items[:itemsLen]
	}
	return items, pop, nil
}
given an array of items sorted by `comparator`, insert an item into its sort index and constrain the size to
`maxSize` by removing the last item
package entities
import (
	"fmt"
	"github.com/miraclesu/uniswap-sdk-go/constants"
)
var (
	ErrInvalidOption    = fmt.Errorf("invalid maxHops")
	ErrInvalidRecursion = fmt.Errorf("invalid recursion")
)
type BestTradeOptions struct {
	MaxNumResults int
	MaxHops int
}
func NewDefaultBestTradeOptions() *BestTradeOptions {
	return &BestTradeOptions{
		MaxNumResults: 3,
		MaxHops:       3,
	}
}
func (o *BestTradeOptions) ReduceHops() *BestTradeOptions {
	return &BestTradeOptions{
		MaxNumResults: o.MaxNumResults,
		MaxHops:       o.MaxHops - 1,
	}
}
type InputOutput interface {
	InputAmount() *TokenAmount
	OutputAmount() *TokenAmount
}
func InputOutputComparator(a, b InputOutput) int {
	if !a.InputAmount().Currency.Equals(b.InputAmount().Currency) ||
		!a.OutputAmount().Currency.Equals(b.OutputAmount().Currency) {
		panic(ErrInvalidCurrency)
	}
	if a.OutputAmount().EqualTo(b.OutputAmount().Fraction) {
		if a.InputAmount().EqualTo(b.InputAmount().Fraction) {
			return 0
		}
		if a.InputAmount().LessThan(b.InputAmount().Fraction) {
			return -1
		}
		return 1
	}
	if a.OutputAmount().LessThan(b.OutputAmount().Fraction) {
		return 1
	}
	return -1
}
func TradeComparator(a, b *Trade) int {
	ioComp := InputOutputComparator(a, b)
	if ioComp != 0 {
		return ioComp
	}
	if a.PriceImpact.LessThan(b.PriceImpact.Fraction) {
		return -1
	}
	if a.PriceImpact.GreaterThan(b.PriceImpact.Fraction) {
		return 1
	}
	return len(a.Route.Path) - len(b.Route.Path)
}