зеркало из https://github.com/Azure/go-amqp.git
move bitmap to internal package (#65)
This commit is contained in:
Родитель
7fe27c31cd
Коммит
20e2c91b8c
9
conn.go
9
conn.go
|
@ -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))
|
11
session.go
11
session.go
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче