Commit f0adf638 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Use slice for portableHandleMap, which is slighty more efficient.

parent 99c5447e
...@@ -39,41 +39,34 @@ const _ALREADY_MSG = "Object already has a handle" ...@@ -39,41 +39,34 @@ const _ALREADY_MSG = "Object already has a handle"
type portableHandleMap struct { type portableHandleMap struct {
sync.RWMutex sync.RWMutex
nextFree uint32 used int
handles map[uint64]*Handled handles []*Handled
freeIds []uint64
} }
func (m *portableHandleMap) Register(obj *Handled, asInt interface{}) uint64 { func (m *portableHandleMap) Register(obj *Handled, asInt interface{}) (handle uint64) {
if obj.check != 0 { if obj.check != 0 {
panic(_ALREADY_MSG) panic(_ALREADY_MSG)
} }
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()
for {
h := uint64(m.nextFree)
m.nextFree++
// HACK - we make sure we start with 1, so we always
// assign root to 1.
if h < 1 {
continue
}
old := m.handles[h]
if old != nil {
continue
}
m.handles[h] = obj if len(m.freeIds) == 0 {
obj.check = 0xbaabbaab handle = uint64(len(m.handles))
return h m.handles = append(m.handles, obj)
} else {
handle = m.freeIds[len(m.freeIds)-1]
m.freeIds = m.freeIds[:len(m.freeIds)-1]
m.handles[handle] = obj
} }
m.used++
return 0 return handle
} }
func (m *portableHandleMap) Count() int { func (m *portableHandleMap) Count() int {
m.RLock() m.RLock()
defer m.RUnlock() defer m.RUnlock()
return len(m.handles) return m.used
} }
func (m *portableHandleMap) Decode(h uint64) *Handled { func (m *portableHandleMap) Decode(h uint64) *Handled {
...@@ -86,8 +79,9 @@ func (m *portableHandleMap) Forget(h uint64) *Handled { ...@@ -86,8 +79,9 @@ func (m *portableHandleMap) Forget(h uint64) *Handled {
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()
v := m.handles[h] v := m.handles[h]
v.check = 0 m.handles[h] = nil
delete(m.handles, h) m.freeIds = append(m.freeIds, h)
m.used--
return v return v
} }
...@@ -166,7 +160,8 @@ func (m *int64HandleMap) verify() { ...@@ -166,7 +160,8 @@ func (m *int64HandleMap) verify() {
func NewHandleMap(portable bool) (hm HandleMap) { func NewHandleMap(portable bool) (hm HandleMap) {
if portable { if portable {
return &portableHandleMap{ return &portableHandleMap{
handles: make(map[uint64]*Handled), // Avoid handing out ID 0 and 1.
handles: []*Handled{nil, nil},
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment