func NewMemoryManager(r Reporter) *MemoryManager {
	if r == nil {
		r = ProcessMemory
	}
	return &MemoryManager{
		reporter: r,
		caches:   make(map[uint64]Disposable),
	}
}
NewMemoryManager creates a new manager with the given memory reporter. If nil is given,
then the Process reporter will be used by default.
package sql
import (
	"os"
	"runtime"
	"strconv"
	"sync"
	errors "gopkg.in/src-d/go-errors.v1"
)
type Disposable interface {
	Dispose()
}
type Freeable interface {
	Free()
}
type KeyValueCache interface {
	Put(uint64, interface{}) error
	Get(uint64) (interface{}, error)
}
type RowsCache interface {
	Add(Row) error
	Get() []Row
}
var ErrNoMemoryAvailable = errors.NewKind("no memory available")
const maxMemoryKey = "MAX_MEMORY"
const (
	b   = 1
	kib = 1024 * b
	mib = 1024 * kib
)
var maxMemory = func() uint64 {
	val := os.Getenv(maxMemoryKey)
	var v uint64
	if val != "" {
		var err error
		v, err = strconv.ParseUint(val, 10, 64)
		if err != nil {
			panic("MAX_MEMORY environment variable must be a number, but got: " + val)
		}
	}
	return v * uint64(mib)
}()
type Reporter interface {
	MaxMemory() uint64
	UsedMemory() uint64
}
var ProcessMemory Reporter = new(processReporter)
type processReporter struct{}
func (processReporter) UsedMemory() uint64 {
	var s runtime.MemStats
	runtime.ReadMemStats(&s)
	return s.HeapInuse + s.StackInuse
}
func (processReporter) MaxMemory() uint64 { return maxMemory }
func HasAvailableMemory(r Reporter) bool {
	maxMemory := r.MaxMemory()
	if maxMemory == 0 {
		return true
	}
	return r.UsedMemory() < maxMemory
}
type MemoryManager struct {
	mu       sync.RWMutex
	reporter Reporter
	caches   map[uint64]Disposable
	token    uint64
}