package main import ( "fmt" "math/bits" "sync/atomic" "unsafe" ) const debug = true type TreeCounterNode struct { Value uint64 Zero *TreeCounterNode One *TreeCounterNode Parent *TreeCounterNode } // MEGA EXPERIMENTAL. Start from the right-most bits in the integer and move leftwards type TreeTopicViewCounter struct { root *TreeCounterNode } func newTreeTopicViewCounter() *TreeTopicViewCounter { return &TreeTopicViewCounter{ &TreeCounterNode{0, nil, nil, nil}, } } func (counter *TreeTopicViewCounter) Bump(signTopicID int64) { var topicID uint64 = uint64(signTopicID) var zeroCount = bits.LeadingZeros64(topicID) if debug { fmt.Printf("topicID int64: %d\n", signTopicID) fmt.Printf("topicID int64: %x\n", signTopicID) fmt.Printf("topicID int64: %b\n", signTopicID) fmt.Printf("topicID uint64: %b\n", topicID) fmt.Printf("leading zeroes: %d\n", zeroCount) var leadingZeroes = "" for i := 0; i < zeroCount; i++ { leadingZeroes += "0" } fmt.Printf("topicID lead uint64: %s%b\n", leadingZeroes, topicID) fmt.Printf("---\n") } var stopAt uint64 = 64 - uint64(zeroCount) var spot uint64 = 1 var node = counter.root for { if debug { fmt.Printf("spot: %d\n", spot) fmt.Printf("topicID&spot: %d\n", topicID&spot) } if topicID&spot == 1 { if node.One == nil { atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(node.One)), nil, unsafe.Pointer(&TreeCounterNode{0, nil, nil, node})) } node = node.One } else { if node.Zero == nil { atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(node.Zero)), nil, unsafe.Pointer(&TreeCounterNode{0, nil, nil, node})) } node = node.Zero } spot++ if spot >= stopAt { break } } atomic.AddUint64(&node.Value, 1) }