item.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package ccache
  2. import (
  3. "container/list"
  4. "sync/atomic"
  5. "time"
  6. )
  7. type Sized interface {
  8. Size() int64
  9. }
  10. type TrackedItem interface {
  11. Value() interface{}
  12. Release()
  13. Expired() bool
  14. TTL() time.Duration
  15. Expires() time.Time
  16. Extend(duration time.Duration)
  17. }
  18. type nilItem struct{}
  19. func (n *nilItem) Value() interface{} { return nil }
  20. func (n *nilItem) Release() {}
  21. func (i *nilItem) Expired() bool {
  22. return true
  23. }
  24. func (i *nilItem) TTL() time.Duration {
  25. return time.Minute
  26. }
  27. func (i *nilItem) Expires() time.Time {
  28. return time.Time{}
  29. }
  30. func (i *nilItem) Extend(duration time.Duration) {
  31. }
  32. var NilTracked = new(nilItem)
  33. type Item struct {
  34. key string
  35. group string
  36. promotions int32
  37. refCount int32
  38. expires int64
  39. size int64
  40. value interface{}
  41. element *list.Element
  42. }
  43. func newItem(key string, value interface{}, expires int64) *Item {
  44. size := int64(1)
  45. if sized, ok := value.(Sized); ok {
  46. size = sized.Size()
  47. }
  48. return &Item{
  49. key: key,
  50. value: value,
  51. promotions: 0,
  52. size: size,
  53. expires: expires,
  54. }
  55. }
  56. func (i *Item) shouldPromote(getsPerPromote int32) bool {
  57. i.promotions += 1
  58. return i.promotions == getsPerPromote
  59. }
  60. func (i *Item) Value() interface{} {
  61. return i.value
  62. }
  63. func (i *Item) track() {
  64. atomic.AddInt32(&i.refCount, 1)
  65. }
  66. func (i *Item) Release() {
  67. atomic.AddInt32(&i.refCount, -1)
  68. }
  69. func (i *Item) Expired() bool {
  70. expires := atomic.LoadInt64(&i.expires)
  71. return expires < time.Now().UnixNano()
  72. }
  73. func (i *Item) TTL() time.Duration {
  74. expires := atomic.LoadInt64(&i.expires)
  75. return time.Nanosecond * time.Duration(expires-time.Now().UnixNano())
  76. }
  77. func (i *Item) Expires() time.Time {
  78. expires := atomic.LoadInt64(&i.expires)
  79. return time.Unix(0, expires)
  80. }
  81. func (i *Item) Extend(duration time.Duration) {
  82. atomic.StoreInt64(&i.expires, time.Now().Add(duration).UnixNano())
  83. }