func (c *csTrieMatcher) bLookup(i *iNode, b *branch, words []string) ([]subscriber, bool) {
	if len(words) > 1 {
		if b.iNode == nil {
			return make([]subscriber, 0), true
		}
		return c.ilookup(b.iNode, i, words[1:])
	}
	return b.subscribers(), true
}
bLookup attempts to retrieve the Subscribers from the word path along the
given branch. True is returned if the Subscribers were retrieved, false if
the operation needs to be retried.
package hub
import (
	"strings"
	"sync/atomic"
	"unsafe"
)
type iNode struct {
	main *mainNode
}
type mainNode struct {
	cNode *cNode
	tNode *tNode
}
type cNode struct {
	branches map[string]*branch
}
func newCNode(words []string, sub subscriber) *cNode {
	if len(words) == 1 {
		return &cNode{
			branches: map[string]*branch{
				words[0]: {subs: map[subscriber]struct{}{sub: {}}},
			},
		}
	}
	nin := &iNode{main: &mainNode{cNode: newCNode(words[1:], sub)}}
	return &cNode{
		branches: map[string]*branch{
			words[0]: {subs: map[subscriber]struct{}{}, iNode: nin},
		},
	}
}
func (c *cNode) inserted(words []string, sub subscriber) *cNode {
	branches := make(map[string]*branch, len(c.branches)+1)
	for key, branch := range c.branches {
		branches[key] = branch
	}
	var br *branch
	if len(words) == 1 {
		br = &branch{subs: map[subscriber]struct{}{sub: {}}}
	} else {
		br = &branch{
			subs:  make(map[subscriber]struct{}),
			iNode: &iNode{main: &mainNode{cNode: newCNode(words[1:], sub)}},
		}
	}
	branches[words[0]] = br
	return &cNode{branches: branches}
}
func (c *cNode) updated(word string, sub subscriber) *cNode {
	branches := make(map[string]*branch, len(c.branches))
	for word, branch := range c.branches {
		branches[word] = branch
	}
	newBranch := &branch{subs: map[subscriber]struct{}{sub: {}}}
	br, ok := branches[word]
	if ok {
		for id, sub := range br.subs {
			newBranch.subs[id] = sub
		}
		newBranch.iNode = br.iNode
	}
	branches[word] = newBranch
	return &cNode{branches: branches}
}
func (c *cNode) updatedBranch(word string, in *iNode, br *branch) *cNode {
	branches := make(map[string]*branch, len(c.branches))
	for key, branch := range c.branches {
		branches[key] = branch
	}
	branches[word] = br.updated(in)
	return &cNode{branches: branches}
}
func (c *cNode) removed(word string, sub subscriber) *cNode {
	branches := make(map[string]*branch, len(c.branches))
	for word, branch := range c.branches {
		branches[word] = branch
	}
	br, ok := branches[word]
	if ok {
		br = br.removed(sub)
		if len(br.subs) == 0 && br.iNode == nil {
			delete(branches, word)
		} else {
			branches[word] = br
		}
	}
	return &cNode{branches: branches}
}
func (c *cNode) getBranches(word string) (*branch, *branch) {
	return c.branches[word], c.branches[wildcard]
}
type branch struct {
	iNode *iNode
	subs  map[subscriber]struct{}
}
func (b *branch) updated(in *iNode) *branch {
	subs := make(map[subscriber]struct{}, len(b.subs))
	for id, sub := range b.subs {
		subs[id] = sub
	}
	return &branch{subs: subs, iNode: in}
}
func (b *branch) removed(sub subscriber) *branch {
	subs := make(map[subscriber]struct{}, len(b.subs))
	for id, sub := range b.subs {
		subs[id] = sub
	}
	delete(subs, sub)
	return &branch{subs: subs, iNode: b.iNode}
}
func (b *branch) subscribers() []subscriber {
	subs := make([]subscriber, len(b.subs))
	i := 0
	for sub := range b.subs {
		subs[i] = sub
		i++
	}
	return subs
}
type tNode struct{}
type csTrieMatcher struct {
	root *iNode
}
func newCSTrieMatcher() matcher {
	root := &iNode{main: &mainNode{cNode: &cNode{}}}
	return &csTrieMatcher{root: root}
}
func (c *csTrieMatcher) Subscribe(topics []string, sub subscriber) Subscription {
	var (
		rootPtr = (*unsafe.Pointer)(unsafe.Pointer(&c.root))
		root    = (*iNode)(atomic.LoadPointer(rootPtr))
	)
	for _, topic := range topics {
		words := strings.Split(topic, delimiter)
		if !c.iinsert(root, nil, words, sub) {
			return c.Subscribe(topics, sub)
		}
	}
	return Subscription{Topics: topics, Receiver: sub.Ch(), subscriber: sub}
}
func (c *csTrieMatcher) iinsert(i, parent *iNode, words []string, sub subscriber) bool {
	mainPtr := (*unsafe.Pointer)(unsafe.Pointer(&i.main))
	main := (*mainNode)(atomic.LoadPointer(mainPtr))
	switch {
	case main.cNode != nil:
		cn := main.cNode
		br := cn.branches[words[0]]
		if br == nil {
			ncn := &mainNode{cNode: cn.inserted(words, sub)}
			return atomic.CompareAndSwapPointer(
				mainPtr, unsafe.Pointer(main), unsafe.Pointer(ncn))
		}
		if len(words) > 1 {
			if br.iNode != nil {
				return c.iinsert(br.iNode, i, words[1:], sub)
			}
			nin := &iNode{main: &mainNode{cNode: newCNode(words[1:], sub)}}
			ncn := &mainNode{cNode: cn.updatedBranch(words[0], nin, br)}
			return atomic.CompareAndSwapPointer(
				mainPtr, unsafe.Pointer(main), unsafe.Pointer(ncn))
		}
		if _, ok := br.subs[sub]; ok {
			return true
		}
		ncn := &mainNode{cNode: cn.updated(words[0], sub)}
		return atomic.CompareAndSwapPointer(mainPtr, unsafe.Pointer(main), unsafe.Pointer(ncn))
	case main.tNode != nil:
		clean(parent)
		return false
	default:
		panic("csTrie is in an invalid state")
	}
}
func (c *csTrieMatcher) Unsubscribe(sub Subscription) {
	var (
		rootPtr = (*unsafe.Pointer)(unsafe.Pointer(&c.root))
		root    = (*iNode)(atomic.LoadPointer(rootPtr))
	)
	for _, topic := range sub.Topics {
		words := strings.Split(topic, delimiter)
		if !c.iremove(root, nil, nil, words, 0, sub.subscriber) {
			c.Unsubscribe(sub)
		}
	}
}
func (c *csTrieMatcher) iremove(i, parent, parentsParent *iNode, words []string, wordIdx int, sub subscriber) bool {
	mainPtr := (*unsafe.Pointer)(unsafe.Pointer(&i.main))
	main := (*mainNode)(atomic.LoadPointer(mainPtr))
	switch {
	case main.cNode != nil:
		cn := main.cNode
		br := cn.branches[words[wordIdx]]
		if br == nil {
			return true
		}
		if wordIdx+1 < len(words) {
			if br.iNode != nil {
				return c.iremove(br.iNode, i, parent, words, wordIdx+1, sub)
			}
			return true
		}
		if _, ok := br.subs[sub]; !ok {
			return true
		}
		ncn := cn.removed(words[wordIdx], sub)
		cntr := c.toContracted(ncn, i)
		if atomic.CompareAndSwapPointer(
			mainPtr, unsafe.Pointer(main), unsafe.Pointer(cntr)) {
			if parent != nil {
				mainPtr = (*unsafe.Pointer)(unsafe.Pointer(&i.main))
				main = (*mainNode)(atomic.LoadPointer(mainPtr))
				if main.tNode != nil {
					cleanParent(i, parent, parentsParent, c, words[wordIdx-1])
				}
			}
			return true
		}
		return false
	case main.tNode != nil:
		clean(parent)
		return false
	default:
		panic("csTrie is in an invalid state")
	}
}
func (c *csTrieMatcher) Lookup(topic string) []subscriber {
	var (
		words   = strings.Split(topic, delimiter)
		rootPtr = (*unsafe.Pointer)(unsafe.Pointer(&c.root))
		root    = (*iNode)(atomic.LoadPointer(rootPtr))
	)
	result, ok := c.ilookup(root, nil, words)
	if !ok {
		return c.Lookup(topic)
	}
	return result
}
func (c *csTrieMatcher) ilookup(i, parent *iNode, words []string) ([]subscriber, bool) {
	mainPtr := (*unsafe.Pointer)(unsafe.Pointer(&i.main))
	main := (*mainNode)(atomic.LoadPointer(mainPtr))
	switch {
	case main.cNode != nil:
		exact, singleWC := main.cNode.getBranches(words[0])
		subs := make(map[subscriber]struct{})
		if exact != nil {
			s, ok := c.bLookup(i, exact, words)
			if !ok {
				return nil, false
			}
			for _, sub := range s {
				subs[sub] = struct{}{}
			}
		}
		if singleWC != nil {
			s, ok := c.bLookup(i, singleWC, words)
			if !ok {
				return nil, false
			}
			for _, sub := range s {
				subs[sub] = struct{}{}
			}
		}
		s := make([]subscriber, len(subs))
		i := 0
		for sub := range subs {
			s[i] = sub
			i++
		}
		return s, true
	case main.tNode != nil:
		clean(parent)
		return nil, false
	default:
		panic("csTrie is in an invalid state")
	}
}