File tree 15 files changed +170
-9
lines changed
15 files changed +170
-9
lines changed Original file line number Diff line number Diff line change @@ -32,6 +32,20 @@ type arc struct {
32
32
b2 * internal.Cache
33
33
}
34
34
35
+ func (a * arc ) Front () interface {} {
36
+ if k := a .t1 .Front (); k != nil {
37
+ return k
38
+ }
39
+ return a .t2 .Front ()
40
+ }
41
+
42
+ func (a * arc ) Back () interface {} {
43
+ if k := a .t1 .Back (); k != nil {
44
+ return k
45
+ }
46
+ return a .t2 .Back ()
47
+ }
48
+
35
49
func (a * arc ) Load (key interface {}) (value interface {}, ok bool ) {
36
50
if val , ok := a .t1 .Peek (key ); ok {
37
51
exp , _ := a .t1 .Expiry (key )
Original file line number Diff line number Diff line change @@ -53,8 +53,11 @@ func TestARCc(t *testing.T) {
53
53
54
54
a .Store (1 , 1 )
55
55
a .Load (1 )
56
+
56
57
assert .Equal (t , 0 , a .t1 .Len ())
57
58
assert .Equal (t , 1 , a .t2 .Len ())
59
+ assert .Equal (t , 1 , a .Front ())
60
+ assert .Equal (t , 1 , a .Back ())
58
61
59
62
a .Delete (1 )
60
63
}
Original file line number Diff line number Diff line change @@ -24,6 +24,20 @@ type Event = internal.Event
24
24
25
25
// Cache stores data so that future requests for that data can be served faster.
26
26
type Cache interface {
27
+ // Front returns the first key of cache or nil if the cache is empty.
28
+ //
29
+ // # Experimental
30
+ //
31
+ // Notice: This func is EXPERIMENTAL and may be changed or removed in a
32
+ // later release.
33
+ Front () interface {}
34
+ // Back returns the last key of cache or nil if the cache is empty.
35
+ //
36
+ // # Experimental
37
+ //
38
+ // Notice: This func is EXPERIMENTAL and may be changed or removed in a
39
+ // later release.
40
+ Back () interface {}
27
41
// Load returns key value.
28
42
Load (key interface {}) (interface {}, bool )
29
43
// Peek returns key value without updating the underlying "recent-ness".
@@ -91,7 +105,7 @@ type Cache interface {
91
105
// GC is a long running function, it returns when ctx done, therefore the
92
106
// caller must start it in its own goroutine.
93
107
//
94
- // Experimental
108
+ // # Experimental
95
109
//
96
110
// Notice: This func is EXPERIMENTAL and may be changed or removed in a
97
111
// later release.
@@ -142,6 +156,20 @@ type cache struct {
142
156
unsafe Cache
143
157
}
144
158
159
+ func (c * cache ) Front () interface {} {
160
+ c .mu .Lock ()
161
+ k := c .unsafe .Front ()
162
+ c .mu .Unlock ()
163
+ return k
164
+ }
165
+
166
+ func (c * cache ) Back () interface {} {
167
+ c .mu .Lock ()
168
+ k := c .unsafe .Back ()
169
+ c .mu .Unlock ()
170
+ return k
171
+ }
172
+
145
173
func (c * cache ) Load (key interface {}) (interface {}, bool ) {
146
174
c .mu .Lock ()
147
175
v , ok := c .unsafe .Load (key )
Original file line number Diff line number Diff line change @@ -42,6 +42,20 @@ func (c *collection) Discard() (e *internal.Entry) {
42
42
return
43
43
}
44
44
45
+ func (c * collection ) Front () (e * internal.Entry ) {
46
+ if le := c .ll .Front (); le != nil {
47
+ e = le .Value .(* internal.Entry )
48
+ }
49
+ return
50
+ }
51
+
52
+ func (c * collection ) Back () (e * internal.Entry ) {
53
+ if le := c .ll .Back (); le != nil {
54
+ e = le .Value .(* internal.Entry )
55
+ }
56
+ return
57
+ }
58
+
45
59
func (c * collection ) Len () int {
46
60
return c .ll .Len ()
47
61
}
Original file line number Diff line number Diff line change @@ -28,11 +28,14 @@ func TestCollection(t *testing.T) {
28
28
}
29
29
}
30
30
31
+ front := c .Front ()
32
+ back := c .Back ()
31
33
oldest := c .Discard ()
32
34
c .Remove (entries [2 ])
33
- back := c .ll .Back ().Value .(* internal.Entry )
34
35
36
+ assert .Equal (t , 1 , front .Key )
37
+ assert .Equal (t , 3 , back .Key )
35
38
assert .Equal (t , 1 , oldest .Key )
36
39
assert .Equal (t , 1 , c .Len ())
37
- assert .Equal (t , 2 , back .Key )
40
+ assert .Equal (t , 2 , c . Back () .Key )
38
41
}
Original file line number Diff line number Diff line change @@ -18,6 +18,8 @@ func New(cap int) libcache.Cache {
18
18
19
19
type idle struct {}
20
20
21
+ func (idle ) Front () (v interface {}) { return }
22
+ func (idle ) Back () (v interface {}) { return }
21
23
func (idle ) Load (interface {}) (v interface {}, ok bool ) { return }
22
24
func (idle ) Peek (interface {}) (v interface {}, ok bool ) { return }
23
25
func (idle ) Keys () (keys []interface {}) { return }
Original file line number Diff line number Diff line change @@ -53,6 +53,8 @@ type Collection interface {
53
53
Add (* Entry )
54
54
Remove (* Entry )
55
55
Discard () * Entry
56
+ Front () * Entry
57
+ Back () * Entry
56
58
Len () int
57
59
Init ()
58
60
}
@@ -97,6 +99,30 @@ type Cache struct {
97
99
capacity int
98
100
}
99
101
102
+ // Front returns the first key of cache or nil if the cache is empty.
103
+ func (c * Cache ) Front () interface {} {
104
+ // Run GC inline before get the front entry.
105
+ c .GC ()
106
+
107
+ if e := c .coll .Front (); e != nil {
108
+ return e .Key
109
+ }
110
+
111
+ return nil
112
+ }
113
+
114
+ // Back returns the last key of cache or nil if the cache is empty.
115
+ func (c * Cache ) Back () interface {} {
116
+ // Run GC inline before get the back entry.
117
+ c .GC ()
118
+
119
+ if e := c .coll .Back (); e != nil {
120
+ return e .Key
121
+ }
122
+
123
+ return nil
124
+ }
125
+
100
126
// Load returns key value.
101
127
func (c * Cache ) Load (key interface {}) (interface {}, bool ) {
102
128
return c .get (key , false )
Original file line number Diff line number Diff line change @@ -57,6 +57,20 @@ func (f *collection) Discard() (e *internal.Entry) {
57
57
return heap .Pop (f ).(* element ).value
58
58
}
59
59
60
+ func (f * collection ) Front () (e * internal.Entry ) {
61
+ if f .Len () > 0 {
62
+ e = (* f )[f .Len ()- 1 ].value
63
+ }
64
+ return
65
+ }
66
+
67
+ func (f * collection ) Back () (e * internal.Entry ) {
68
+ if f .Len () > 0 {
69
+ e = (* f )[0 ].value
70
+ }
71
+ return
72
+ }
73
+
60
74
func (f * collection ) Move (e * internal.Entry ) {
61
75
ele := e .Element .(* element )
62
76
ele .count ++
Original file line number Diff line number Diff line change @@ -27,9 +27,13 @@ func TestCollection(t *testing.T) {
27
27
}
28
28
}
29
29
30
+ front := f .Front ()
31
+ back := f .Back ()
30
32
oldest := f .Discard ()
31
33
f .Remove (entries [2 ])
32
34
35
+ assert .Equal (t , front .Key , 2 )
36
+ assert .Equal (t , back .Key , 1 )
33
37
assert .Equal (t , oldest .Key , 1 )
34
38
assert .Equal (t , f .Len (), 1 )
35
39
assert .Equal (t , (* f )[0 ].value .Key , 2 )
Original file line number Diff line number Diff line change @@ -42,6 +42,20 @@ func (c *collection) Discard() (e *internal.Entry) {
42
42
return
43
43
}
44
44
45
+ func (c * collection ) Front () (e * internal.Entry ) {
46
+ if le := c .ll .Front (); le != nil {
47
+ e = le .Value .(* internal.Entry )
48
+ }
49
+ return
50
+ }
51
+
52
+ func (c * collection ) Back () (e * internal.Entry ) {
53
+ if le := c .ll .Back (); le != nil {
54
+ e = le .Value .(* internal.Entry )
55
+ }
56
+ return
57
+ }
58
+
45
59
func (c * collection ) Len () int {
46
60
return c .ll .Len ()
47
61
}
Original file line number Diff line number Diff line change @@ -28,11 +28,15 @@ func TestCollection(t *testing.T) {
28
28
}
29
29
}
30
30
31
+ front := c .Front ()
32
+ back := c .Back ()
33
+
31
34
oldest := c .Discard ()
32
35
c .Remove (entries [0 ])
33
- back := c .ll .Back ().Value .(* internal.Entry )
34
36
37
+ assert .Equal (t , 1 , front .Key )
38
+ assert .Equal (t , 3 , back .Key )
35
39
assert .Equal (t , 3 , oldest .Key )
36
40
assert .Equal (t , 1 , c .Len ())
37
- assert .Equal (t , 2 , back .Key )
41
+ assert .Equal (t , 2 , c . Back () .Key )
38
42
}
Original file line number Diff line number Diff line change @@ -45,6 +45,20 @@ func (c *collection) Discard() (e *internal.Entry) {
45
45
return
46
46
}
47
47
48
+ func (c * collection ) Front () (e * internal.Entry ) {
49
+ if le := c .ll .Front (); le != nil {
50
+ e = le .Value .(* internal.Entry )
51
+ }
52
+ return
53
+ }
54
+
55
+ func (c * collection ) Back () (e * internal.Entry ) {
56
+ if le := c .ll .Back (); le != nil {
57
+ e = le .Value .(* internal.Entry )
58
+ }
59
+ return
60
+ }
61
+
48
62
func (c * collection ) Len () int {
49
63
return c .ll .Len ()
50
64
}
Original file line number Diff line number Diff line change @@ -28,11 +28,15 @@ func TestCollection(t *testing.T) {
28
28
}
29
29
}
30
30
31
+ front := c .Front ()
32
+ back := c .Back ()
33
+
31
34
oldest := c .Discard ()
32
35
c .Remove (entries [2 ])
33
- back := c .ll .Back ().Value .(* internal.Entry )
34
36
37
+ assert .Equal (t , 3 , front .Key )
38
+ assert .Equal (t , 1 , back .Key )
35
39
assert .Equal (t , 1 , oldest .Key )
36
40
assert .Equal (t , 1 , c .Len ())
37
- assert .Equal (t , 2 , back .Key )
41
+ assert .Equal (t , 2 , c . Back () .Key )
38
42
}
Original file line number Diff line number Diff line change @@ -45,6 +45,20 @@ func (c *collection) Discard() (e *internal.Entry) {
45
45
return
46
46
}
47
47
48
+ func (c * collection ) Front () (e * internal.Entry ) {
49
+ if le := c .ll .Front (); le != nil {
50
+ e = le .Value .(* internal.Entry )
51
+ }
52
+ return
53
+ }
54
+
55
+ func (c * collection ) Back () (e * internal.Entry ) {
56
+ if le := c .ll .Back (); le != nil {
57
+ e = le .Value .(* internal.Entry )
58
+ }
59
+ return
60
+ }
61
+
48
62
func (c * collection ) Len () int {
49
63
return c .ll .Len ()
50
64
}
Original file line number Diff line number Diff line change @@ -28,11 +28,14 @@ func TestCollection(t *testing.T) {
28
28
}
29
29
}
30
30
31
+ front := c .Front ()
32
+ back := c .Back ()
31
33
oldest := c .Discard ()
32
34
c .Remove (entries [1 ])
33
- back := c .ll .Back ().Value .(* internal.Entry )
34
35
36
+ assert .Equal (t , 3 , front .Key )
37
+ assert .Equal (t , 1 , back .Key )
35
38
assert .Equal (t , 3 , oldest .Key )
36
39
assert .Equal (t , 1 , c .Len ())
37
- assert .Equal (t , 1 , back .Key )
40
+ assert .Equal (t , 1 , c . Back () .Key )
38
41
}
You can’t perform that action at this time.
0 commit comments