使用Golang下chan实现一个缓冲池(Pool)

使用Golang实现byte的缓冲池


  在本文中,使用golang语言中特殊的chan结构来实现一个[]byte类型的缓存池。

BytesPool中主要有两个方法:
1. Put([]byte):将byte切片放入到缓存池中
2. Get(sz int) []byte:从缓存池中去一个长度为sz的切片;如果缓存池中切片的容量(cap)不大于sz,则返回容量大小为sz的空的byte切片
注: 缓存池中的切片都遵循先进先出的原则。
// BytesPool  is a pool of byte slice that can ben used
type BytesPool struct {
	pool chan []byte
}

func NewBytesPool(max int) *BytesPool {
	return &BytesPool{
		pool: make(chan []byte, max),
	}
}

// Get returns a byte slice with at least sz capacity.
func (p *BytesPool) Get(sz int) []byte {
	var c []byte
	select {
	case c = <-p.pool:
	default:
		return make([]byte, sz)
	}

	if cap(c) < sz {
		return make([]byte, sz)
	}

	return c[:sz]
}

// Put returns a slice back to the pool
func (p *BytesPool) Put(c []byte) {
	select {
	case p.pool <- c:
	default:
	}
}

缓存池的使用如下面代码所示:

func main() {
	pool := NewBytesPool(3) // set the pool length is 3
	buf := []struct {
		b []byte
	}{
		{b: []byte("abcdef")},
		{b: []byte("123455")},
		{b: []byte("aaaabbbcccddd")},
	}

	for _, b := range buf {
		pool.Put(b.b)
	}

	for i := 0; i < len(buf); i++ {
		fmt.Println(string(pool.Get(len(buf[i].b))))
	}
}

下面使用chan实现一个包含(key, values)的缓冲池

type Entry struct {
	key    int64
	values []byte
}

func NewEntry(key int64, values []byte) Entry {
	return Entry{
		key:    key,
		values: values,
	}
}

type LimitedEntry struct {
	pool chan Entry
}

func NewLimitedEntry(capacity int) *LimitedEntry {
	return &LimitedEntry{
		pool: make(chan Entry, capacity),
	}
}

func (p *LimitedEntry) Get() (Entry, bool) {
	var e Entry

	select {
	case e = <-p.pool:
		return e, true
	default:
	}
	return e, false
}

func (p *LimitedEntry) Put(e Entry) {
	select {
	case p.pool <- e:
	default:
	}
}
该缓存池的测试如下:
func main() {

	entries := []Entry{
		NewEntry(123, []byte("abc")),
		NewEntry(456, []byte("jidd")),
		NewEntry(678, []byte("anhdu")),
	}

	for _, e := range entries {
		pools.Put(e)
	}

	for i := 0; i < 5; i++ {
		if e, ok := pools.Get(); ok {
			fmt.Printf("key: %v, value: %v\n", e.key, string(e.values))
		} else {
			fmt.Println("the pools is empty")
		}
	}
}
运行结果如下所示,当缓存池为空时,打印“ the pools is empty”:
key: 123, value: abc
key: 456, value: jidd
key: 678, value: anhdu
the pools is empty
the pools is empty





你可能感兴趣的:(golang)