mirror of
https://github.com/jech/galene.git
synced 2024-11-22 08:35:57 +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()
|
cache.mu.Lock()
|
||||||
defer cache.mu.Unlock()
|
defer cache.mu.Unlock()
|
||||||
|
|
||||||
|
if int(index) > len(cache.entries) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
if cache.entries[index].seqno != seqno {
|
if cache.entries[index].seqno != seqno {
|
||||||
return 0
|
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
|
// 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
|
// were 0, the index of the first 0 bit, and a bitmap indicating any
|
||||||
// 0 bits after the first one.
|
// 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) {
|
func TestBitmap(t *testing.T) {
|
||||||
value := uint64(0xcdd58f1e035379c0)
|
value := uint64(0xcdd58f1e035379c0)
|
||||||
packet := make([]byte, 1)
|
packet := make([]byte, 1)
|
||||||
|
|
Loading…
Reference in a new issue