🌞

cache2go源码阅读(二)

缓存表的排序

为了实现获取缓存表内最多访问的元素,引入这两个数据结构用于排序:

1
2
3
4
5
6
type CacheItemPair struct {
	Key         interface{}
	AccessCount int64
}

type CacheItemPairList []CacheItemPair

CacheItemPairList是存储CacheItemPair的切片,有以下三个方法

1
2
3
func (p CacheItemPairList) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
func (p CacheItemPairList) Len() int           { return len(p) }
func (p CacheItemPairList) Less(i, j int) bool { return p[i].AccessCount > p[j].AccessCount }

为什么是这三个方法,进入sort包,包实现的排序都是对Interface这个接口做的,因此被排序的数据结构需要实现这三个方法

1
2
3
4
5
6
7
8
9
type Interface interface {
	// Len is the number of elements in the collection.
	Len() int
	// Less reports whether the element with
	// index i should sort before the element with index j.
	Less(i, j int) bool
	// Swap swaps the elements with indexes i and j.
	Swap(i, j int)
}

借助CacheItemPair,存储key和访问次数accessCount,通过CacheItemPairList实现排序,排序完的列表,再遍历得到元素,构造新顺序的元素表

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
func (table *CacheTable) MostAccessed(count int64) []*CacheItem {
	table.RLock()
	defer table.RUnlock()

	p := make(CacheItemPairList, len(table.items))
	i := 0
	for k, v := range table.items {
		p[i] = CacheItemPair{k, v.accessCount}
		i++
	}
	sort.Sort(p)

	var r []*CacheItem
	c := int64(0)
	// p经过排序后,通过遍历构造新的items list
	for _, v := range p {
		if c >= count {
			break
		}

		item, ok := table.items[v.Key]
		if ok {
			r = append(r, item)
		}
		c++
	}

	return r
}
updatedupdated2020-01-072020-01-07