Merge pull request #990 from micro/buffer
Add debug/buffer package as a simple ring buffer
This commit is contained in:
		
							
								
								
									
										58
									
								
								debug/buffer/buffer.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								debug/buffer/buffer.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | |||||||
|  | // Package buffer provides a simple ring buffer for storing local data | ||||||
|  | package buffer | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"sync" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type Buffer struct { | ||||||
|  | 	size int | ||||||
|  | 	sync.RWMutex | ||||||
|  | 	vals []interface{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (b *Buffer) Put(v interface{}) { | ||||||
|  | 	b.Lock() | ||||||
|  | 	defer b.Unlock() | ||||||
|  |  | ||||||
|  | 	// append to values | ||||||
|  | 	b.vals = append(b.vals, v) | ||||||
|  |  | ||||||
|  | 	// trim if bigger than size required | ||||||
|  | 	if len(b.vals) > b.size { | ||||||
|  | 		b.vals = b.vals[1:] | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the last n entries | ||||||
|  | func (b *Buffer) Get(n int) []interface{} { | ||||||
|  | 	// reset any invalid values | ||||||
|  | 	if n > b.size || n < 0 { | ||||||
|  | 		n = b.size | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	b.RLock() | ||||||
|  | 	defer b.RUnlock() | ||||||
|  |  | ||||||
|  | 	// create a delta | ||||||
|  | 	delta := b.size - n | ||||||
|  |  | ||||||
|  | 	// if all the values are less than delta | ||||||
|  | 	if len(b.vals) < delta { | ||||||
|  | 		return b.vals | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// return the delta set | ||||||
|  | 	return b.vals[delta:] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (b *Buffer) Size() int { | ||||||
|  | 	return b.size | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // New returns a new buffer of the given size | ||||||
|  | func New(i int) *Buffer { | ||||||
|  | 	return &Buffer{ | ||||||
|  | 		size: i, | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										52
									
								
								debug/buffer/buffer_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								debug/buffer/buffer_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | package buffer | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestBuffer(t *testing.T) { | ||||||
|  | 	b := New(10) | ||||||
|  |  | ||||||
|  | 	// test one value | ||||||
|  | 	b.Put("foo") | ||||||
|  | 	v := b.Get(1) | ||||||
|  |  | ||||||
|  | 	if val := v[0].(string); val != "foo" { | ||||||
|  | 		t.Fatalf("expected foo got %v", val) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	b = New(10) | ||||||
|  |  | ||||||
|  | 	// test 10 values | ||||||
|  | 	for i := 0; i < 10; i++ { | ||||||
|  | 		b.Put(i) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	v = b.Get(10) | ||||||
|  |  | ||||||
|  | 	for i := 0; i < 10; i++ { | ||||||
|  | 		val := v[i].(int) | ||||||
|  |  | ||||||
|  | 		if val != i { | ||||||
|  | 			t.Fatalf("expected %d got %d", i, val) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// test more values | ||||||
|  |  | ||||||
|  | 	for i := 0; i < 10; i++ { | ||||||
|  | 		v := i * 2 | ||||||
|  | 		b.Put(v) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	v = b.Get(10) | ||||||
|  |  | ||||||
|  | 	for i := 0; i < 10; i++ { | ||||||
|  | 		val := v[i].(int) | ||||||
|  | 		expect := i * 2 | ||||||
|  | 		if val != expect { | ||||||
|  | 			t.Fatalf("expected %d got %d", expect, val) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user