Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
improve snmp: cache request to a buffer
- Loading branch information
Showing
7 changed files
with
453 additions
and
277 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package snmpclient | ||
|
||
/* Circular buffer object */ | ||
type requestBuffer struct { | ||
start int /* index of oldest element */ | ||
count int /* the count of elements */ | ||
elements []*clientRequest /* vector of elements */ | ||
} | ||
|
||
func newRequestBuffer(elements []*clientRequest) *requestBuffer { | ||
return &requestBuffer{elements: elements} | ||
} | ||
|
||
func (self *requestBuffer) Init(elements []*clientRequest) { | ||
self.elements = elements | ||
self.start = 0 | ||
self.count = 0 | ||
} | ||
|
||
/* clear all elements.*/ | ||
func (self *requestBuffer) Clear() { | ||
self.start = 0 | ||
self.count = 0 | ||
} | ||
|
||
func (self *requestBuffer) IsFull() bool { | ||
return self.count == len(self.elements) | ||
} | ||
|
||
/* return true while size is 0, otherwise return false */ | ||
func (self *requestBuffer) IsEmpty() bool { | ||
return 0 == self.count | ||
} | ||
|
||
/* Write an element, overwriting oldest element if buffer is full. App can | ||
choose to avoid the overwrite by checking isFull(). */ | ||
func (self *requestBuffer) Push(elem *clientRequest) { | ||
end := (self.start + self.count) % len(self.elements) | ||
self.elements[end] = elem | ||
if self.count == len(self.elements) { | ||
self.start = (self.start + 1) % len(self.elements) /* full, overwrite */ | ||
} else { | ||
self.count++ | ||
} | ||
} | ||
|
||
func (self *requestBuffer) Get(idx int) *clientRequest { | ||
if self.IsEmpty() { | ||
return nil | ||
} | ||
|
||
current := (self.start + idx) % len(self.elements) | ||
return self.elements[current] | ||
} | ||
|
||
/* Read oldest element. App must ensure !isEmpty() first. */ | ||
func (self *requestBuffer) Pop() *clientRequest { | ||
if self.IsEmpty() { | ||
return nil | ||
} | ||
|
||
elem := self.elements[self.start] | ||
self.start = (self.start + 1) % len(self.elements) | ||
self.count-- | ||
return elem | ||
} | ||
|
||
func (self *requestBuffer) First() *clientRequest { | ||
if self.IsEmpty() { | ||
return nil | ||
} | ||
|
||
return self.elements[self.start] | ||
} | ||
|
||
func (self *requestBuffer) Last() *clientRequest { | ||
if self.IsEmpty() { | ||
return nil | ||
} | ||
|
||
end := (self.start + self.count - 1) % len(self.elements) | ||
return self.elements[end] | ||
} | ||
|
||
/* Read all elements.*/ | ||
func (self *requestBuffer) Size() int { | ||
return self.count | ||
} | ||
|
||
/* Read all elements.*/ | ||
func (self *requestBuffer) All() []*clientRequest { | ||
if 0 == self.count { | ||
return nil | ||
} | ||
|
||
res := make([]*clientRequest, 0, self.count) | ||
if self.count <= (len(self.elements) - self.start) { | ||
for i := self.start; i < (self.start + self.count); i++ { | ||
res = append(res, self.elements[i]) | ||
} | ||
return res | ||
} | ||
|
||
for i := self.start; i < len(self.elements); i++ { | ||
res = append(res, self.elements[i]) | ||
} | ||
for i := 0; len(res) < self.count; i++ { | ||
res = append(res, self.elements[i]) | ||
} | ||
|
||
return res | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package snmpclient | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestRequestBuffer(t *testing.T) { | ||
cb := newRequestBuffer(make([]*clientRequest, 10)) | ||
|
||
check := func(cb *requestBuffer, c int) { | ||
if c < 10 { | ||
if cb.Size() != (1 + c) { | ||
t.Error("size is error, excepted is", 1+c, ", actual is", cb.Size()) | ||
} | ||
|
||
all := cb.All() | ||
if len(all) != (1 + c) { | ||
t.Error("len(all) is error, excepted is 10, actual is", cb.Size()) | ||
} | ||
|
||
for i := 0; i <= c; i++ { | ||
if all[i].timeout != time.Duration(i) { | ||
t.Error("all[", i, "] is error, excepted is ", all[i].timeout, ", actual is", i) | ||
} | ||
} | ||
|
||
for i := 0; i <= c; i++ { | ||
if all[i].timeout != cb.Get(i).timeout { | ||
t.Error("all[", i, "] != cb.Get(", i, "), excepted is ", all[i].timeout, ", actual is", cb.Get(i).timeout) | ||
} | ||
} | ||
|
||
if time.Duration(c) != cb.Last().timeout { | ||
t.Error("excepted last is", c, ", actual is", cb.Last().timeout) | ||
} | ||
|
||
if all[0].timeout != cb.First().timeout { | ||
t.Error("excepted first is", all[0].timeout, ", actual is", cb.First().timeout) | ||
} | ||
|
||
} else { | ||
if cb.Size() != 10 { | ||
t.Error("size is error, excepted is 10, actual is", cb.Size()) | ||
} | ||
|
||
all := cb.All() | ||
if len(all) != 10 { | ||
t.Error("len(all) is error, excepted is 10, actual is", cb.Size()) | ||
} | ||
|
||
for i := 0; i < 10; i++ { | ||
if all[i].timeout != time.Duration(c-9+i) { | ||
t.Error("all[", i, "] is error, excepted is", all[i].timeout, ", actual is", c-9+i) | ||
} | ||
} | ||
|
||
for i := 0; i < 10; i++ { | ||
if all[i].timeout != cb.Get(i).timeout { | ||
t.Error("all[", i, "] != cb.Get(", i, "), excepted is ", all[i].timeout, ", actual is", cb.Get(i).timeout) | ||
} | ||
} | ||
|
||
if time.Duration(c) != cb.Last().timeout { | ||
t.Error("excepted last is", c, ", actual is", cb.Last().timeout) | ||
} | ||
|
||
if time.Duration(c-9) != cb.First().timeout { | ||
t.Error("excepted first is", c-9, ", actual is", cb.First().timeout) | ||
} | ||
|
||
if all[0].timeout != cb.First().timeout { | ||
t.Error("excepted first is", all[0].timeout, ", actual is", cb.First().timeout) | ||
} | ||
|
||
if all[len(all)-1].timeout != cb.Last().timeout { | ||
t.Error("excepted first is", all[len(all)-1].timeout, ", actual is", cb.Last().timeout) | ||
} | ||
} | ||
} | ||
|
||
for i := 0; i < 100; i++ { | ||
cb.Push(&clientRequest{timeout: time.Duration(i)}) | ||
check(cb, i) | ||
} | ||
} |
Oops, something went wrong.