108 lines
1.9 KiB
Go
108 lines
1.9 KiB
Go
// Copyright 2009 The Go9p Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package go9p
|
|
|
|
import "sync"
|
|
|
|
var m2id = [...]uint8{
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 4,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 5,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 4,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 6,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 4,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 5,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 4,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 7,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 4,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 5,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 4,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 6,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 4,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 5,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 4,
|
|
0, 1, 0, 2, 0, 1, 0, 3,
|
|
0, 1, 0, 2, 0, 1, 0, 0,
|
|
}
|
|
|
|
type pool struct {
|
|
sync.Mutex
|
|
need int
|
|
nchan chan uint32
|
|
maxid uint32
|
|
imap []byte
|
|
}
|
|
|
|
func newPool(maxid uint32) *pool {
|
|
p := new(pool)
|
|
p.maxid = maxid
|
|
p.nchan = make(chan uint32)
|
|
|
|
return p
|
|
}
|
|
|
|
func (p *pool) getId() uint32 {
|
|
var n uint32 = 0
|
|
var ret uint32
|
|
|
|
p.Lock()
|
|
for n = 0; n < uint32(len(p.imap)); n++ {
|
|
if p.imap[n] != 0xFF {
|
|
break
|
|
}
|
|
}
|
|
|
|
if int(n) >= len(p.imap) {
|
|
m := uint32(len(p.imap) + 32)
|
|
if uint32(m*8) > p.maxid {
|
|
m = p.maxid/8 + 1
|
|
}
|
|
|
|
b := make([]byte, m)
|
|
copy(b, p.imap)
|
|
p.imap = b
|
|
}
|
|
|
|
if n >= uint32(len(p.imap)) {
|
|
p.need++
|
|
p.Unlock()
|
|
ret = <-p.nchan
|
|
} else {
|
|
ret = uint32(m2id[p.imap[n]])
|
|
p.imap[n] |= 1 << ret
|
|
ret += n * 8
|
|
p.Unlock()
|
|
}
|
|
|
|
return ret
|
|
}
|
|
|
|
func (p *pool) putId(id uint32) {
|
|
p.Lock()
|
|
if p.need > 0 {
|
|
p.nchan <- id
|
|
p.need--
|
|
p.Unlock()
|
|
return
|
|
}
|
|
|
|
p.imap[id/8] &= ^(1 << (id % 8))
|
|
p.Unlock()
|
|
}
|