キャッシュシステムのCRUDインターフェイスの実装
ここで、キャッシュシステムのCRUDインターフェイスを実装することができます。以下のインターフェイスを使用して、キャッシュシステムにデータを追加することができます。
// キャッシュデータ項目を設定し、既に存在する場合は上書きする
func (c *Cache) Set(k string, v interface{}, d time.Duration) {
var e int64
if d == DefaultExpiration {
d = c.defaultExpiration
}
if d > 0 {
e = time.Now().Add(d).UnixNano()
}
c.mu.Lock()
defer c.mu.Unlock()
c.items[k] = Item{
Object: v,
Expiration: e,
}
}
// ロック操作なしでデータ項目を設定する
func (c *Cache) set(k string, v interface{}, d time.Duration) {
var e int64
if d == DefaultExpiration {
d = c.defaultExpiration
}
if d > 0 {
e = time.Now().Add(d).UnixNano()
}
c.items[k] = Item{
Object: v,
Expiration: e,
}
}
// データ項目を取得する。また、項目が期限切れになったかどうかもチェックする
func (c *Cache) get(k string) (interface{}, bool) {
item, found := c.items[k]
if!found {
return nil, false
}
if item.Expired() {
return nil, false
}
return item.Object, true
}
// データ項目を追加する。既に存在する場合はエラーを返す
func (c *Cache) Add(k string, v interface{}, d time.Duration) error {
c.mu.Lock()
_, found := c.get(k)
if found {
c.mu.Unlock()
return fmt.Errorf("Item %s already exists", k)
}
c.set(k, v, d)
c.mu.Unlock()
return nil
}
// データ項目を取得する
func (c *Cache) Get(k string) (interface{}, bool) {
c.mu.RLock()
defer c.mu.RUnlock()
item, found := c.items[k]
if!found {
return nil, false
}
if item.Expired() {
return nil, false
}
return item.Object, true
}
上記のコードでは、Set()
と Add()
インターフェイスを実装しています。両者の主な違いは、前者は既に存在する場合にキャッシュシステム内のデータ項目を上書きする一方、後者は既にデータ項目が存在する場合にエラーを投げ、キャッシュが誤って上書きされるのを防ぐことです。また、Get()
メソッドも実装しており、これはキャッシュシステムからデータ項目を取得します。重要なことは、キャッシュデータ項目が存在するという真の意味は、項目が存在しており、期限切れになっていないことです。
次に、削除と更新インターフェイスを実装することができます。
// 既存のデータ項目を置き換える
func (c *Cache) Replace(k string, v interface{}, d time.Duration) error {
c.mu.Lock()
_, found := c.get(k)
if!found {
c.mu.Unlock()
return fmt.Errorf("Item %s doesn't exist", k)
}
c.set(k, v, d)
c.mu.Unlock()
return nil
}
// データ項目を削除する
func (c *Cache) Delete(k string) {
c.mu.Lock()
c.delete(k)
c.mu.Unlock()
}
上記のコードは自明であるため、詳細には触れません。