github.com/saintwish/kv@v1.0.4/kv1/shard.go (about)

     1  package kv1
     2  
     3  import (
     4  	"time"
     5  	"sync"
     6  
     7  	"github.com/saintwish/kv/swiss"
     8  )
     9  
    10  type item[V any] struct {
    11  	Object V
    12  	Expire time.Time
    13  }
    14  
    15  //used internally
    16  type shard[K comparable, V any] struct {
    17  	Map *swiss.Map[K, item[V]]
    18  	Expiration time.Duration
    19  	*sync.RWMutex //mutex
    20  }
    21  
    22  func newShard[K comparable, V any](ex time.Duration, size uint64, count uint64) shard[K, V] {
    23  	return shard[K, V] {
    24  		Map: swiss.NewMap[K, item[V]]( uint32(size/count) ),
    25  		Expiration: ex,
    26  		RWMutex: &sync.RWMutex{},
    27  	}
    28  }
    29  
    30  /*--------
    31  	Raw get functions.
    32  ----------*/
    33  func (m shard[K, V]) get(key K) (val V) {
    34  	m.RLock()
    35  
    36  	val = m.Map.Get(key).Object
    37  
    38  	m.RUnlock()
    39  
    40  	return
    41  }
    42  
    43  func (m shard[K, V]) getRenew(key K) (val V) {
    44  	m.Lock()
    45  
    46  	if ok,v := m.Map.GetHas(key); ok {
    47  		v.Expire = time.Now().Add(m.Expiration)
    48  		m.Map.Set(key, v)
    49  		val = v.Object
    50  	}
    51  
    52  	m.Unlock()
    53  
    54  	return
    55  }
    56  
    57  func (m shard[K, V]) has(key K) (ok bool) {
    58  	m.RLock()
    59  
    60  	ok = m.Map.Has(key)
    61  
    62  	m.RUnlock()
    63  
    64  	return
    65  }
    66  
    67  func (m shard[K, V]) getHas(key K) (val V, ok bool) {
    68  	m.RLock()
    69  
    70  	ok,v := m.Map.GetHas(key);
    71  	val = v.Object
    72  
    73  	m.RUnlock()
    74  
    75  	return
    76  }
    77  
    78  func (m shard[K, V]) getHasRenew(key K) (val V, ok bool) {
    79  	m.Lock()
    80  
    81  	if ok,v := m.Map.GetHas(key); ok {
    82  		v.Expire = time.Now().Add(m.Expiration)
    83  		m.Map.Set(key, v)
    84  		val = v.Object
    85  	}
    86  
    87  	m.Unlock()
    88  
    89  	return
    90  }
    91  
    92  
    93  /*--------
    94  	Other functions
    95  ----------*/
    96  func (m shard[K, V]) set(key K, val V) {
    97  	itm := item[V]{
    98  		Object: val,
    99  		Expire: time.Now().Add(m.Expiration),
   100  	}
   101  
   102  	m.Lock()
   103  
   104  	m.Map.Set(key, itm)
   105  
   106  	m.Unlock()
   107  }
   108  
   109  func (m shard[K, V]) update(key K, val V) {
   110  	itm := item[V]{
   111  		Object: val,
   112  		Expire: time.Now().Add(m.Expiration),
   113  	}
   114  
   115  	m.Lock()
   116  
   117  	if ok := m.Map.Has(key); ok {
   118  		m.Map.Set(key, itm)
   119  	}
   120  
   121  	m.Unlock()
   122  }
   123  
   124  func (m shard[K, V]) delete(key K) (ok bool) {
   125  	m.Lock()
   126  
   127  	ok, _ = m.Map.Delete(key)
   128  
   129  	m.Unlock()
   130  
   131  	return
   132  }
   133  
   134  func (m shard[K, V]) isExpired(key K) (ex bool) {
   135  	m.RLock()
   136  
   137  	if ok,v:= m.Map.GetHas(key); ok {
   138  		ex = time.Now().After(v.Expire)
   139  	}
   140  
   141  	m.RUnlock()
   142  	return
   143  }
   144  
   145  //Returns true if item is expired and thus evicted.
   146  func (m shard[K, V]) evictItem(key K, callback func(K,V)) (ex bool) {
   147  	m.Lock()
   148  
   149  	ex = false
   150  	if ok,v := m.Map.GetHas(key); ok {
   151  		if time.Now().After(v.Expire) {
   152  			ex = true
   153  			callback(key, v.Object)
   154  			m.Map.Delete(key)
   155  		}
   156  	}
   157  
   158  	m.Unlock()
   159  
   160  	return
   161  }
   162  
   163  func (m shard[K, V]) evictExpired(callback func(K,V)) {
   164  	m.Lock()
   165  
   166  	m.Map.Iter(func (key K, v item[V]) (stop bool) {
   167  		if time.Now().After(v.Expire) {
   168  			callback(key, v.Object)
   169  			m.Map.Delete(key)
   170  		}
   171  		
   172  		if stop {
   173  			m.Unlock()
   174  			return
   175  		}
   176  
   177  		return
   178  	})
   179  
   180  	m.Unlock()
   181  }
   182  
   183  func (m shard[K, V]) renew(key K) {
   184  	expire := time.Now().Add(m.Expiration)
   185  
   186  	m.Lock()
   187  	
   188  	if ok,v := m.Map.GetHas(key); ok {
   189  		v.Expire = expire
   190  	}
   191  
   192  	m.Unlock()
   193  }
   194  
   195  func (m shard[K, V]) clear() {
   196  	m.Map.Clear()
   197  }
   198  
   199  func (m shard[K, V]) flush(callback func(K, V)) {
   200  	m.Lock()
   201  
   202  	m.Map.Iter(func(key K, val item[V]) (stop bool) {
   203  		callback(key, val.Object)
   204  		m.Map.Delete(key)
   205  		
   206  		if stop {
   207  			m.Unlock()
   208  			return
   209  		}
   210  
   211  		return
   212  	})
   213  
   214  	m.Unlock()
   215  }