mirror of
https://github.com/jech/galene.git
synced 2024-11-22 00:25:58 +01:00
Implement packetcache resizing.
This commit is contained in:
parent
b1542af47c
commit
b00d2abacf
2 changed files with 97 additions and 0 deletions
|
@ -139,6 +139,9 @@ func (cache *Cache) GetAt(seqno uint16, index uint16, result []byte) uint16 {
|
|||
cache.mu.Lock()
|
||||
defer cache.mu.Unlock()
|
||||
|
||||
if int(index) > len(cache.entries) {
|
||||
return 0
|
||||
}
|
||||
if cache.entries[index].seqno != seqno {
|
||||
return 0
|
||||
}
|
||||
|
@ -148,6 +151,57 @@ func (cache *Cache) GetAt(seqno uint16, index uint16, result []byte) uint16 {
|
|||
)
|
||||
}
|
||||
|
||||
func (cache *Cache) resize(capacity int) {
|
||||
if len(cache.entries) == capacity {
|
||||
return
|
||||
}
|
||||
|
||||
entries := make([]entry, capacity)
|
||||
|
||||
if capacity > len(cache.entries) {
|
||||
copy(entries, cache.entries[:cache.tail])
|
||||
copy(entries[int(cache.tail)+capacity-len(cache.entries):],
|
||||
cache.entries[cache.tail:])
|
||||
} else if capacity > int(cache.tail) {
|
||||
copy(entries, cache.entries[:cache.tail])
|
||||
copy(entries[cache.tail:],
|
||||
cache.entries[int(cache.tail)+
|
||||
len(cache.entries)-capacity:])
|
||||
} else {
|
||||
// too bad, invalidate all indices
|
||||
copy(entries,
|
||||
cache.entries[int(cache.tail)-capacity:cache.tail])
|
||||
cache.tail = 0
|
||||
}
|
||||
cache.entries = entries
|
||||
}
|
||||
|
||||
func (cache *Cache) Resize(capacity int) {
|
||||
cache.mu.Lock()
|
||||
defer cache.mu.Unlock()
|
||||
|
||||
cache.resize(capacity)
|
||||
}
|
||||
|
||||
func (cache *Cache) ResizeCond(capacity int) bool {
|
||||
cache.mu.Lock()
|
||||
defer cache.mu.Unlock()
|
||||
|
||||
current := len(cache.entries)
|
||||
|
||||
if current >= capacity/2 && current < capacity*2 {
|
||||
return false
|
||||
}
|
||||
|
||||
if int(cache.tail) > current/2 && int(cache.tail) > capacity/2 {
|
||||
// bad time to resize, this would invalidate too many indices
|
||||
return false
|
||||
}
|
||||
|
||||
cache.resize(capacity)
|
||||
return true
|
||||
}
|
||||
|
||||
// Shift 17 bits out of the bitmap. Return a boolean indicating if any
|
||||
// were 0, the index of the first 0 bit, and a bitmap indicating any
|
||||
// 0 bits after the first one.
|
||||
|
|
|
@ -81,6 +81,49 @@ func TestCacheOverflow(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCacheGrow(t *testing.T) {
|
||||
cache := New(16)
|
||||
|
||||
for i := 0; i < 24; i++ {
|
||||
cache.Store(uint16(i), []byte{uint8(i)})
|
||||
}
|
||||
|
||||
cache.Resize(32)
|
||||
for i := 0; i < 32; i++ {
|
||||
expected := uint16(0)
|
||||
if i < 8 {
|
||||
expected = uint16(i + 16)
|
||||
}
|
||||
if i >= 24 {
|
||||
expected = uint16(i - 16)
|
||||
}
|
||||
if cache.entries[i].seqno != expected {
|
||||
t.Errorf("At %v, got %v, expected %v",
|
||||
i, cache.entries[i].seqno, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCacheShrink(t *testing.T) {
|
||||
cache := New(16)
|
||||
|
||||
for i := 0; i < 24; i++ {
|
||||
cache.Store(uint16(i), []byte{uint8(i)})
|
||||
}
|
||||
|
||||
cache.Resize(12)
|
||||
for i := 0; i < 12; i++ {
|
||||
expected := uint16(i + 16)
|
||||
if i >= 8 {
|
||||
expected = uint16(i + 4)
|
||||
}
|
||||
if cache.entries[i].seqno != expected {
|
||||
t.Errorf("At %v, got %v, expected %v",
|
||||
i, cache.entries[i].seqno, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBitmap(t *testing.T) {
|
||||
value := uint64(0xcdd58f1e035379c0)
|
||||
packet := make([]byte, 1)
|
||||
|
|
Loading…
Reference in a new issue