func (t *PrimaryTree) Put(k generic.T, upd func(oldV SecondaryLayer, exists bool) (newV SecondaryLayer, write bool)) (oldV SecondaryLayer, written bool) {
	pi := -1
	var p *x1
	q := t.r
	var newV SecondaryLayer
	if q == nil {
		newV, written = upd(newV, false)
		if !written {
			return
		}
		z := t.insert(btDPool1.Get().(*d1), 0, k, newV)
		t.r, t.first, t.last = z, z, z
		return
	}
	for {
		i, ok := t.find(q, k)
		if ok {
			switch x := q.(type) {
			case *x1:
				if x.c > 2*kx1 {
					x, i = t.splitX(p, x, pi, i)
				}
				pi = i + 1
				p = x
				q = x.x[i+1].ch
				continue
			case *d1:
				oldV = x.d[i].v
				newV, written = upd(oldV, true)
				if !written {
					return
				}
				x.d[i].v = newV
			}
			return
		}
		switch x := q.(type) {
		case *x1:
			if x.c > 2*kx1 {
				x, i = t.splitX(p, x, pi, i)
			}
			pi = i
			p = x
			q = x.x[i].ch
		case *d1:  
			newV, written = upd(newV, false)
			if !written {
				return
			}
			switch {
			case x.c < 2*kd1:
				t.insert(x, i, k, newV)
			default:
				t.overflow(p, x, pi, i, k, newV)
			}
			return
		}
	}
}
Put combines Get and Set in a more efficient way where the tree is walked
only once. The upd(ater) receives (old-value, true) if a KV pair for k
exists or (zero-value, false) otherwise. It can then return a (new-value,
true) to create or overwrite the existing value in the KV pair, or
(whatever, false) if it decides not to create or not to update the value of
the KV pair.

tree.Set(k, v) call conceptually equals calling

tree.Put(k, func(generic.T, bool){ return v, true })

modulo the differing return values.
package btree2d
import (
	"fmt"
	"io"
	"sync"
	"sync/atomic"
	"github.com/joeshaw/gengen/generic"
)
const (
	kx1 = 64  
	kd1 = 64  
)
func init() {
	if kd1 < 1 {
		panic(fmt.Errorf("kd1 %d: out of range", kd1))
	}
	if kx1 < 2 {
		panic(fmt.Errorf("kx1 %d: out of range", kx1))
	}
}
var (
	btDPool1 = sync.Pool{New: func() interface{} { return &d1{} }}
	btEPool1 = btEpool1{sync.Pool{New: func() interface{} { return &PrimaryEnumerator{} }}}
	btTPool1 = btTpool1{sync.Pool{New: func() interface{} { return &PrimaryTree{} }}}
	btXPool1 = sync.Pool{New: func() interface{} { return &x1{} }}
)
type btTpool1 struct{ sync.Pool }
func (p *btTpool1) get(cmp PrimaryCmpFunc) *PrimaryTree {
	x := p.Get().(*PrimaryTree)
	x.cmp = cmp
	return x
}
type btEpool1 struct{ sync.Pool }
func (p *btEpool1) get(err error, hit bool, i int, k generic.T, q *d1, t *PrimaryTree, ver uint64) *PrimaryEnumerator {
	x := p.Get().(*PrimaryEnumerator)
	x.err, x.hit, x.i, x.k, x.q, x.t, x.ver = err, hit, i, k, q, t, ver
	return x
}
type (
	d1 struct {  
		c int
		d [2*kd1 + 1]de1
		n *d1
		p *d1
	}
	de1 struct {  
		k generic.T
		v SecondaryLayer
	}
	PrimaryEnumerator struct {
		err error
		hit bool
		i   int
		k   generic.T
		q   *d1
		t   *PrimaryTree
		ver uint64
	}
	PrimaryTree struct {
		c     int
		cmp   PrimaryCmpFunc
		first *d1
		last  *d1
		r     interface{}
		ver   uint64
	}
	xe1 struct {  
		ch interface{}
		k  generic.T
	}
	x1 struct {  
		c int
		x [2*kx1 + 2]xe1
	}
)
var (  
	zd1  d1
	zde1 de1
	ze1  PrimaryEnumerator
	zk1  generic.T
	zt1  PrimaryTree
	zx1  x1
	zxe1 xe1
)
func clr1(q interface{}) {
	switch x := q.(type) {
	case *x1:
		for i := 0; i <= x.c; i++ {  
			clr1(x.x[i].ch)
		}
		*x = zx1
		btXPool1.Put(x)
	case *d1:
		*x = zd1
		btDPool1.Put(x)
	}
}
func newX1(ch0 interface{}) *x1 {
	r := btXPool1.Get().(*x1)
	r.x[0].ch = ch0
	return r
}
func (q *x1) extract(i int) {
	q.c--
	if i < q.c {
		copy(q.x[i:], q.x[i+1:q.c+1])
		q.x[q.c].ch = q.x[q.c+1].ch
		q.x[q.c].k = zk1   
		q.x[q.c+1] = zxe1  
	}
}
func (q *x1) insert(i int, k generic.T, ch interface{}) *x1 {
	c := q.c
	if i < c {
		q.x[c+1].ch = q.x[c].ch
		copy(q.x[i+2:], q.x[i+1:c])
		q.x[i+1].k = q.x[i].k
	}
	c++
	q.c = c
	q.x[i].k = k
	q.x[i+1].ch = ch
	return q
}
func (q *x1) siblings(i int) (l, r *d1) {
	if i >= 0 {
		if i > 0 {
			l = q.x[i-1].ch.(*d1)
		}
		if i < q.c {
			r = q.x[i+1].ch.(*d1)
		}
	}
	return
}
func (l *d1) mvL(r *d1, c int) {
	copy(l.d[l.c:], r.d[:c])
	copy(r.d[:], r.d[c:r.c])
	l.c += c
	r.c -= c
}
func (l *d1) mvR(r *d1, c int) {
	copy(r.d[c:], r.d[:r.c])
	copy(r.d[:c], l.d[l.c-c:])
	r.c += c
	l.c -= c
}
func NewPrimaryTree(cmp PrimaryCmpFunc) *PrimaryTree {
	return btTPool1.get(cmp)
}
func (t *PrimaryTree) Clear() {
	if t.r == nil {
		return
	}
	clr1(t.r)
	t.c, t.first, t.last, t.r = 0, nil, nil, nil
	atomic.AddUint64(&t.ver, 1)
}
func (t *PrimaryTree) Close() {
	t.Clear()
	*t = zt1
	btTPool1.Put(t)
}
func (t *PrimaryTree) cat(p *x1, q, r *d1, pi int) {
	atomic.AddUint64(&t.ver, 1)
	q.mvL(r, r.c)
	if r.n != nil {
		r.n.p = q
	} else {
		t.last = q
	}
	q.n = r.n
	*r = zd1
	btDPool1.Put(r)
	if p.c > 1 {
		p.extract(pi)
		p.x[pi].ch = q
		return
	}
	switch x := t.r.(type) {
	case *x1:
		*x = zx1
		btXPool1.Put(x)
	case *d1:
		*x = zd1
		btDPool1.Put(x)
	}
	t.r = q
}
func (t *PrimaryTree) catX(p, q, r *x1, pi int) {
	atomic.AddUint64(&t.ver, 1)
	q.x[q.c].k = p.x[pi].k
	copy(q.x[q.c+1:], r.x[:r.c])
	q.c += r.c + 1
	q.x[q.c].ch = r.x[r.c].ch
	*r = zx1
	btXPool1.Put(r)
	if p.c > 1 {
		p.c--
		pc := p.c
		if pi < pc {
			p.x[pi].k = p.x[pi+1].k
			copy(p.x[pi+1:], p.x[pi+2:pc+1])
			p.x[pc].ch = p.x[pc+1].ch
			p.x[pc].k = zk1     
			p.x[pc+1].ch = nil  
		}
		return
	}
	switch x := t.r.(type) {
	case *x1:
		*x = zx1
		btXPool1.Put(x)
	case *d1:
		*x = zd1
		btDPool1.Put(x)
	}
	t.r = q
}
func (t *PrimaryTree) Delete(k generic.T) (ok bool) {
	pi := -1
	var p *x1
	q := t.r
	if q == nil {
		return false
	}
	for {
		var i int
		i, ok = t.find(q, k)
		if ok {
			switch x := q.(type) {
			case *x1:
				if x.c < kx1 && q != t.r {
					x, i = t.underflowX(p, x, pi, i)
				}
				pi = i + 1
				p = x
				q = x.x[pi].ch
				ok = false
				continue
			case *d1:
				t.extract(x, i)
				if x.c >= kd1 {
					return true
				}
				if q != t.r {
					t.underflow(p, x, pi)
				} else if t.c == 0 {
					t.Clear()
				}
				return true
			}
		}
		switch x := q.(type) {
		case *x1:
			if x.c < kx1 && q != t.r {
				x, i = t.underflowX(p, x, pi, i)
			}
			pi = i
			p = x
			q = x.x[i].ch
		case *d1:
			return false
		}
	}
}
func (t *PrimaryTree) extract(q *d1, i int) {  
	atomic.AddUint64(&t.ver, 1)
	q.c--
	if i < q.c {
		copy(q.d[i:], q.d[i+1:q.c+1])
	}
	q.d[q.c] = zde1  
	t.c--
	return
}
func (t *PrimaryTree) find(q interface{}, k generic.T) (i int, ok bool) {
	var mk generic.T
	l := 0
	switch x := q.(type) {
	case *x1:
		h := x.c - 1
		for l <= h {
			m := (l + h) >> 1
			mk = x.x[m].k
			switch cmp := t.cmp(k, mk); {
			case cmp > 0:
				l = m + 1
			case cmp == 0:
				return m, true
			default:
				h = m - 1
			}
		}
	case *d1:
		h := x.c - 1
		for l <= h {
			m := (l + h) >> 1
			mk = x.d[m].k
			switch cmp := t.cmp(k, mk); {
			case cmp > 0:
				l = m + 1
			case cmp == 0:
				return m, true
			default:
				h = m - 1
			}
		}
	}
	return l, false
}
func (t *PrimaryTree) First() (k generic.T, v SecondaryLayer) {
	if q := t.first; q != nil {
		q := &q.d[0]
		k, v = q.k, q.v
	}
	return
}
func (t *PrimaryTree) Get(k generic.T) (v SecondaryLayer, ok bool) {
	q := t.r
	if q == nil {
		return
	}
	for {
		var i int
		if i, ok = t.find(q, k); ok {
			switch x := q.(type) {
			case *x1:
				q = x.x[i+1].ch
				continue
			case *d1:
				return x.d[i].v, true
			}
		}
		switch x := q.(type) {
		case *x1:
			q = x.x[i].ch
		default:
			return
		}
	}
}
func (t *PrimaryTree) insert(q *d1, i int, k generic.T, v SecondaryLayer) *d1 {
	atomic.AddUint64(&t.ver, 1)
	c := q.c
	if i < c {
		copy(q.d[i+1:], q.d[i:c])
	}
	c++
	q.c = c
	q.d[i].k, q.d[i].v = k, v
	t.c++
	return q
}
func (t *PrimaryTree) Last() (k generic.T, v SecondaryLayer) {
	if q := t.last; q != nil {
		q := &q.d[q.c-1]
		k, v = q.k, q.v
	}
	return
}
func (t *PrimaryTree) Len() int {
	return t.c
}
func (t *PrimaryTree) overflow(p *x1, q *d1, pi, i int, k generic.T, v SecondaryLayer) {
	atomic.AddUint64(&t.ver, 1)
	l, r := p.siblings(pi)
	if l != nil && l.c < 2*kd1 && i != 0 {
		l.mvL(q, 1)
		t.insert(q, i-1, k, v)
		p.x[pi-1].k = q.d[0].k
		return
	}
	if r != nil && r.c < 2*kd1 {
		if i < 2*kd1 {
			q.mvR(r, 1)
			t.insert(q, i, k, v)
			p.x[pi].k = r.d[0].k
			return
		}
		t.insert(r, 0, k, v)
		p.x[pi].k = k
		return
	}
	t.split(p, q, pi, i, k, v)
}
func (t *PrimaryTree) Seek(k generic.T) (e *PrimaryEnumerator, ok bool) {
	q := t.r
	if q == nil {
		e = btEPool1.get(nil, false, 0, k, nil, t, atomic.LoadUint64(&t.ver))
		return
	}
	for {
		var i int
		if i, ok = t.find(q, k); ok {
			switch x := q.(type) {
			case *x1:
				q = x.x[i+1].ch
				continue
			case *d1:
				return btEPool1.get(nil, ok, i, k, x, t, atomic.LoadUint64(&t.ver)), true
			}
		}
		switch x := q.(type) {
		case *x1:
			q = x.x[i].ch
		case *d1:
			return btEPool1.get(nil, ok, i, k, x, t, atomic.LoadUint64(&t.ver)), false
		}
	}
}
func (t *PrimaryTree) SeekFirst() (e *PrimaryEnumerator, err error) {
	q := t.first
	if q == nil {
		return nil, io.EOF
	}
	return btEPool1.get(nil, true, 0, q.d[0].k, q, t, atomic.LoadUint64(&t.ver)), nil
}
func (t *PrimaryTree) SeekLast() (e *PrimaryEnumerator, err error) {
	q := t.last
	if q == nil {
		return nil, io.EOF
	}
	return btEPool1.get(nil, true, q.c-1, q.d[q.c-1].k, q, t, atomic.LoadUint64(&t.ver)), nil
}
func (t *PrimaryTree) Set(k generic.T, v SecondaryLayer) {
	pi := -1
	var p *x1
	q := t.r
	if q == nil {
		z := t.insert(btDPool1.Get().(*d1), 0, k, v)
		t.r, t.first, t.last = z, z, z
		return
	}
	for {
		i, ok := t.find(q, k)
		if ok {
			switch x := q.(type) {
			case *x1:
				if x.c > 2*kx1 {
					x, i = t.splitX(p, x, pi, i)
				}
				pi = i + 1
				p = x
				q = x.x[i+1].ch
				continue
			case *d1:
				x.d[i].v = v
			}
			return
		}
		switch x := q.(type) {
		case *x1:
			if x.c > 2*kx1 {
				x, i = t.splitX(p, x, pi, i)
			}
			pi = i
			p = x
			q = x.x[i].ch
		case *d1:
			switch {
			case x.c < 2*kd1:
				t.insert(x, i, k, v)
			default:
				t.overflow(p, x, pi, i, k, v)
			}
			return
		}
	}
}