You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: cache.go
    path of file: ./repos/tank/code/tool/cache
    
    the code of the file until where you have to start completion: package cache

import (
	"errors"
	"fmt"
	"sort"
	"sync"
	"time"
)

//cache2go https://github.com/muesli/cache2go
type Item struct {
	//read write lock
	sync.RWMutex
	key  interface{}
	data interface{}
	// cache duration.
	duration time.Duration
	// create time
	createTime time.Time
	//last access time
	accessTime time.Time
	//visit times
	count int64
	// callback after deleting
	deleteCallback func(key interface{})
}

//create item.
func NewItem(key interface{}, duration time.Duration, data interface{}) *Item {
	t := time.Now()
	return &Item{
		key:            key,
		duration:       duration,
		createTime:     t,
		accessTime:     t,
		count:          0,
		deleteCallback: nil,
		data:           
    
func (table *Table) checkExpire() {
	table.Lock()
	if table.cleanupTimer != nil {
		table.cleanupTimer.Stop()
	}
	if table.cleanupInterval > 0 {
		table.log("Expiration check triggered after %v for table", table.cleanupInterval)
	} else {
		table.log("Expiration check installed for table")
	}

	// in order to not take the lock. use temp items.
	items := table.items
	table.Unlock()

	//in order to make timer more precise, update now every loop.
	now := time.Now()
	smallestDuration := 0 * time.Second
	for key, item := range items {
		//take out our things, in order not to take the lock.
		item.RLock()
		duration := item.duration
		accessTime := item.accessTime
		item.RUnlock()

		// 0 means valid.
		if duration == 0 {
			continue
		}
		if now.Sub(accessTime) >= duration {
			//cache item expired.
			_, e := table.Delete(key)
			if e != nil {
				table.log("occur error while deleting %v", e.Error())
			}
		} else {
			//find the most possible expire item.
			if smallestDuration == 0 || duration-now.Sub(accessTime) < smallestDuration {
				smallestDuration = duration - now.Sub(accessTime)
			}
		}
	}

	//trigger next clean
	table.Lock()
	table.cleanupInterval = smallestDuration
	if smallestDuration > 0 {
		table.cleanupTimer = time.AfterFunc(smallestDuration, func() {
			go table.RunWithRecovery(table.checkExpire)
		})
	}
	table.Unlock()
}