move bitmap to internal package (#65)

This commit is contained in:
Joel Hendrix 2021-09-16 10:32:22 -07:00 коммит произвёл GitHub
Родитель 7fe27c31cd
Коммит 20e2c91b8c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 29 добавлений и 23 удалений

Просмотреть файл

@ -12,6 +12,7 @@ import (
"sync"
"time"
"github.com/Azure/go-amqp/internal/bitmap"
"github.com/Azure/go-amqp/internal/buffer"
"github.com/Azure/go-amqp/internal/encoding"
"github.com/Azure/go-amqp/internal/frames"
@ -333,10 +334,10 @@ func (c *conn) getErr() error {
func (c *conn) mux() {
var (
// allocated channels
channels = &bitmap{max: uint32(c.channelMax)}
channels = bitmap.New(uint32(c.channelMax))
// create the next session to allocate
nextChannel, _ = channels.next()
nextChannel, _ = channels.Next()
nextSession = newSessionResp{session: newSession(c, uint16(nextChannel))}
// map channels to sessions
@ -421,7 +422,7 @@ func (c *conn) mux() {
sessionsByChannel[ch] = nextSession.session
// get next available channel
next, ok := channels.next()
next, ok := channels.Next()
if !ok {
nextSession = newSessionResp{err: fmt.Errorf("reached connection channel max (%d)", c.channelMax)}
continue
@ -434,7 +435,7 @@ func (c *conn) mux() {
case s := <-c.delSession:
delete(sessionsByChannel, s.channel)
delete(sessionsByRemoteChannel, s.remoteChannel)
channels.remove(uint32(s.channel))
channels.Remove(uint32(s.channel))
// connection is complete
case <-c.closeMux:

Просмотреть файл

@ -1,21 +1,25 @@
package amqp
package bitmap
import (
"math/bits"
)
// bitmap is a lazily initialized bitmap
type bitmap struct {
type Bitmap struct {
max uint32
bits []uint64
}
func New(max uint32) *Bitmap {
return &Bitmap{max: max}
}
// add sets n in the bitmap.
//
// bits will be expanded as needed.
//
// If n is greater than max, the call has no effect.
func (b *bitmap) add(n uint32) {
func (b *Bitmap) Add(n uint32) {
if n > b.max {
return
}
@ -35,7 +39,7 @@ func (b *bitmap) add(n uint32) {
// remove clears n from the bitmap.
//
// If n is not set or greater than max the call has not effect.
func (b *bitmap) remove(n uint32) {
func (b *Bitmap) Remove(n uint32) {
var (
idx = n / 64
offset = n % 64
@ -54,7 +58,7 @@ func (b *bitmap) remove(n uint32) {
//
// If there are no unset bits below max, the second return
// value will be false.
func (b *bitmap) next() (uint32, bool) {
func (b *Bitmap) Next() (uint32, bool) {
// find the first unset bit
for i, v := range b.bits {
// skip if all bits are set

Просмотреть файл

@ -1,4 +1,4 @@
package amqp
package bitmap
import (
"math"
@ -118,24 +118,24 @@ func TestBitmap(t *testing.T) {
for i, tt := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
bm := &bitmap{max: tt.max}
bm := New(tt.max)
for _, op := range tt.ops {
switch op := op.(type) {
case add:
bm.add(uint32(op))
bm.Add(uint32(op))
case rem:
bm.remove(uint32(op))
bm.Remove(uint32(op))
case next:
for i := int64(0); i < int64(op); i++ {
bm.next()
bm.Next()
}
default:
panic("unhandled op " + reflect.TypeOf(op).String())
}
}
next, ok := bm.next()
next, ok := bm.Next()
if ok == tt.nextFail {
t.Errorf("next() failed with %d", next)
}
@ -154,10 +154,10 @@ func TestBitmap(t *testing.T) {
func TestBitmap_Sequence(t *testing.T) {
const max = 1024
bm := &bitmap{max: max}
bm := New(max)
for i := uint32(0); i <= max; i++ {
next, ok := bm.next()
next, ok := bm.Next()
if !ok {
t.Errorf("next() failed with %d", next)
}
@ -173,7 +173,7 @@ func TestBitmap_Sequence(t *testing.T) {
}
}
func countBitmap(bm *bitmap) uint32 {
func countBitmap(bm *Bitmap) uint32 {
var count uint32
for _, v := range bm.bits {
count += uint32(bits.OnesCount64(v))

Просмотреть файл

@ -6,6 +6,7 @@ import (
"fmt"
"sync"
"github.com/Azure/go-amqp/internal/bitmap"
"github.com/Azure/go-amqp/internal/encoding"
"github.com/Azure/go-amqp/internal/frames"
)
@ -139,9 +140,9 @@ func (s *Session) mux(remoteBegin *frames.PerformBegin) {
}()
var (
links = make(map[uint32]*link) // mapping of remote handles to links
linksByKey = make(map[linkKey]*link) // mapping of name+role link
handles = &bitmap{max: s.handleMax} // allocated handles
links = make(map[uint32]*link) // mapping of remote handles to links
linksByKey = make(map[linkKey]*link) // mapping of name+role link
handles = bitmap.New(s.handleMax) // allocated handles
handlesByDeliveryID = make(map[uint32]uint32) // mapping of deliveryIDs to handles
deliveryIDByHandle = make(map[uint32]uint32) // mapping of handles to latest deliveryID
@ -201,7 +202,7 @@ func (s *Session) mux(remoteBegin *frames.PerformBegin) {
continue
}
next, ok := handles.next()
next, ok := handles.Next()
if !ok {
l.err = fmt.Errorf("reached session handle max (%d)", s.handleMax)
l.rx <- nil
@ -217,7 +218,7 @@ func (s *Session) mux(remoteBegin *frames.PerformBegin) {
delete(links, l.remoteHandle)
delete(deliveryIDByHandle, l.handle)
delete(linksByKey, l.key)
handles.remove(l.handle)
handles.Remove(l.handle)
close(l.rx) // close channel to indicate deallocation
// incoming frame for link