I. Overview
Today we begin the first part of "Golang Skills enhancement". This piece I plan to analyze 3 projects, one is a very popular Golang source reading starter Project Cache2go, followed by the very popular Memcache go language version groupcache, and finally is one of the core components of the Docker project Containerd, Through the 3 projects of the source of the full analysis to achieve the purpose of the Golang capacity of a step.
In this tutorial series, I want you to be able to do the following: If you are a novice in the go language, look at the following code analysis process you will certainly encounter some of your own unfamiliar coding, unfamiliar knowledge points, in the process I hope you encounter a point to master a point, such as see the following code to use the lock, To find a variety of information on the lock-related knowledge points learned. When you see the callback function, think about why people use callback functions in these places. So after reading this project source code analysis, you can learn a part of the knowledge module
Second, what is Cache2go
This is an open source project on GitHub, as the original author describes:
Concurrency-safe Golang caching library with expiration capabilities.
Do you understand me? In short, there is a concurrency-safe Go language cache library with a heartbeat mechanism. OK, here's the project we're going to analyze is a cache library, and there are 2 features, concurrency Security and heartbeat mechanism!
III. Structure of the project
Project directory structure as shown, you can see the function implementation of the relevant source files only 3:
Cache.go
Cacheitem.go
Cachetable.go
Iv. Key Data Structures
Only 2 complex data types are involved in the project, namely:
The meaning is consistent with the literal meaning, one is the cache table, and the other is the entry in the cache table. Let's look at how the 2 structures are defined below.
1, CacheItem
The CacheItem type is used to represent a separate cache entry, the source code is shown below, each field is clearly understandable, and a slightly longer note has been annotated in Chinese.
1// cacheitem is an individual cache item 2// parameter data Contains the user-set value in the cache. 3type cacheitem struct {4 sync. Rwmutex 5 6 // the item ' S key. 7 key interface{} 8 // the item ' S data. 9 data interface{}10 //"Time to live after not being accessed" 11 // How long will the item live in the cache when Not being accessed/kept alive.12 lifespan time. duration1314 // creation timestamp.15 createdon Time. Time16 // last access timestamp.17 accessedon time. Time18 // how often the item was accessed.19 accesscount int6420 //"callback method triggered when deleted" 21 // callback method triggered right before removing the item from the cache22 abouttoexpire func (key interface{}) 23}
2, Cachetable
Cachetable describes a table entry in the cache, with the Items property being the CacheItem type instance mentioned above. In addition to the general properties, there are several functions of the type of properties, the source code is as follows (the last few lines appear to cramp the style ~):
1// cachetable is a table within the cache 2type CacheTable struct {3 sync. Rwmutex 4 5 // the table ' S name. 6 name string 7 // all cached items. 8 //"All entries in a table exist in this map, the map key is any type and the value is CacheItem pointer type" 9 items map[interface{}]*CacheItem1011 // Timer responsible for triggering cleanup.12 //"timer responsible for triggering the purge operation" 13 cleanuptimer *time. timer14 // current timer duration.15 //" Clears the time interval that the operation triggered "16 cleanupinterval time. duration1718 // the logger used for this table.19 logger *log. Logger2021 //&nbsP callback method triggered when trying to load a non-existing key.22 //"callback function triggered when a nonexistent key needs to be extracted" 23 loaddata func (key interface{}, args ...interface{}) *CacheItem24 // Callback method triggered when adding a new item to the cache.25 //"callback function triggered when adding a cache entry" 26 addeditem func (Item *cacheitem) 27 // Callback method triggered before deleting an item from the cache.28 //"callback function triggered before deletion" 29 Abouttodeleteitem func (Item *cacheitem) 30}
As shown above, Cache2go's core data structure is concise and should be easier to understand. Of course, not fully understand the reason for the definition of each field is not urgent, after reading the following code logic in turn to look at the data structure, it is certain to understand the role of each field.
Five, Code logic
Our idea is to analyze the code from the bottom up, what does it mean? This means looking at the action associated with the item, then the table-related code that contains the item, and finally the logic to manipulate the cache level of the table. So the following we have to look at Cacheitem.go code, and then analyze Cachetable.go, and then see Cache.go, finally see 3 files in the source of the correlation between what, finally see example, that is, how to play the cache ~
1, Cacheitem.go
For example, this source file contains only a definition of type CacheItem and a function Newcacheitem (). CacheItem What properties have been seen before, the following first look at the Newcacheitem () function:
1// newcacheitem returns a newly created cacheitem. 2// parameter key is the item ' S cache-key. 3// parameter lifespan determines after which time period without an access the item 4// will get removed from the cache. 5// parameter data is the item ' S value. 6func newcacheitem (Key interface{}, lifespan time. duration, data interface{}) *cacheitem {7 t := time. Now () 8 return &cacheitem{9 key: key,10 lifeSpan: lifeSpan,11 createdOn: t,12 accessedOn: t,13 accessCount: 0,14 abouttoexpire: nil,15 data:      DATA,16    }17}
As shown above, the Newcacheitem () function receives 3 parameters, namely, the key, the value, the time to live (key, data, lifespan), and returns a pointer to an instance of the CacheItem type.
Where Createon and Accessedon are set to the current time, Abouttoexpire is the callback method triggered when the deletion is temporarily set to nil, it is not difficult to think that this function will need to call other methods to set this property.
Cacheitem.go In addition to the definition of the CacheItem type, the definition of the Newcacheitem () function, there is a part of the CacheItem method definition, a total of 8
The source code looks a lot of lines, the content is actually very simple, the main element is to get the operation, here need to pay attention to read and write operations are added the corresponding read and write lock, remember the beginning of the cache2go is a concurrency security program? Concurrency security is reflected in these places. The most complex of the following is the setting of the last callback function, the formal parameter of this method is F func (interface{}), that is, the formal parameter name is F, the formal parameter type is func (interface{}), which is a function type, the parameter of the function type is a interface{ }, which is an empty interface, because any type can be considered to implement an empty interface, so you can receive any type of argument here. That is, the type of f is a function type that can receive any type of argument. A bit around, need to calm down to understand oh ~
The source code is as follows:
1// keepalive marks an item to be kept for another Expireduration period. 2//"Update Accessedon to Current Time" 3func (Item *cacheitem) keepalive () {4 item. Lock () 5 defer item. Unlock () 6 item.accessedon = time. Now () 7 item.accesscount++ 8} 910// lifespan returns this item ' s expiration duration.11func (Item *cacheitem) lifespan () time. duration {12 // immutable13 return item.lifespan14}1516// accessedon returns when this item was last accessed.17func (Item *cacheitem) accessedon () time. Time {18 item. Rlock () 19 defer item. Runlock () 20    RETURN ITEM.ACCESSEDON21}2223// CREatedon returns when this item was added to the cache.24func (Item *cacheitem) createdon () time. TIME {25    // IMMUTABLE26    RETURN ITEM.CREATEDON27} 2829// accesscount returns how often this item has been accessed.30func (Item *cacheitem) accesscount () int64 {31 item . Rlock () 32 defer item. Runlock () 33 return item.accesscount34}3536// key returns the key of this cached item.37func (Item *cacheitem) Key () interface{} {38 // immutable39 return item.key40}4142// Data returns the value of this cached item.43func (item * CacheItem) data ()  INTERFACE{}&NBsp {44 // immutable45 return item.data46}4748// setabouttoexpirecallback configures a callback, which will be called Right49// before the item is about to be removed from the cache.50//"Sets the callback function that will be called when an item is removed" 51func (Item *cacheitem) setabouttoexpirecallback (F func (interface{})) {52 item. Lock () 53 defer item. Unlock () 54 item.abouttoexpire = f55}
Here to read this source file, is not very easy ~
The above a bunch of method functions are still very intuitive, today we see here, the next to continue to analyze the cachetable related code.
191 reads