File tree Expand file tree Collapse file tree 2 files changed +76
-3
lines changed
Expand file tree Collapse file tree 2 files changed +76
-3
lines changed Original file line number Diff line number Diff line change 1+ package main
2+
3+ import (
4+ "container/list"
5+ "sync"
6+ )
7+
8+ type LoadGroup struct {
9+ calls map [string ]* call
10+ mutex sync.Mutex
11+ cache * Cache
12+ }
13+
14+ type call struct {
15+ mu sync.RWMutex
16+ result * string
17+ err * error
18+ }
19+
20+ // Get ensures one loading task is run even if multiple threads are waiting on the same key
21+ // /*
22+ func (l * LoadGroup ) Get (key string , loaderFunc LoaderFunc ) (string , error ) {
23+ l .mutex .Lock ()
24+ cache := * (l .cache )
25+ vc , err := cache .GetWithoutLoad (key )
26+ if err != nil {
27+ //
28+ }
29+
30+ if len (vc ) != 0 {
31+ l .mutex .Unlock ()
32+ return vc , nil
33+ }
34+
35+ if call , ok := l .calls [key ]; ok {
36+ l .mutex .Unlock ()
37+
38+ call .mu .RLock ()
39+ result := call .result
40+ call .mu .RUnlock ()
41+ return * result , nil
42+ }
43+
44+ call := & call {
45+ result : new (string ),
46+ }
47+
48+ l .calls [key ] = call
49+ call .mu .Lock ()
50+ l .mutex .Unlock ()
51+
52+ // TODO: handling panic
53+ v , err := loaderFunc (key )
54+ if err != nil {
55+
56+ }
57+ call .result = & v
58+ call .mu .Unlock ()
59+
60+ // Remove call and update cache
61+ l .mutex .Lock ()
62+ err = cache .Set (key , v )
63+ if err != nil {
64+ // TODO: handling error
65+ l .mutex .Unlock ()
66+ return "" , err
67+ }
68+
69+ delete (l .calls , key )
70+ l .mutex .Unlock ()
71+ }
Original file line number Diff line number Diff line change @@ -10,6 +10,7 @@ var EMPTY_ERROR = errors.New("EMPTY ERROR")
1010
1111type Cache interface {
1212 Get (key string ) (string , error )
13+ GetWithoutLoad (key string ) (string , error )
1314 Set (key , value string ) error
1415}
1516
@@ -41,9 +42,6 @@ type lfuItem struct {
4142 el * list.Element // Reference to lruEntry
4243}
4344
44- type LoadGroup struct {
45- }
46-
4745func NewLFUCache (size int , loaderFunc LoaderFunc ) (* LFUCache , error ) {
4846 if size <= 0 {
4947 return nil , errors .New ("size must be greater than zero" )
@@ -99,6 +97,10 @@ func (cache *LFUCache) Get(key string) (string, error) {
9997 return value , nil
10098}
10199
100+ func load (key string ) (string , error ) {
101+
102+ }
103+
102104func (cache * LFUCache ) GetKeys () []string {
103105 keys := make ([]string , 0 )
104106 for k , _ := range cache .cache {
You can’t perform that action at this time.
0 commit comments