Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
dms3
go-datastore
Commits
731e20de
Commit
731e20de
authored
Feb 07, 2015
by
Juan Batiz-Benet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
time cache
parent
2990467a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
160 additions
and
0 deletions
+160
-0
timecache/timecache.go
timecache/timecache.go
+96
-0
timecache/timecache_test.go
timecache/timecache_test.go
+64
-0
No files found.
timecache/timecache.go
0 → 100644
View file @
731e20de
package
timecache
import
(
"sync"
"time"
ds
"github.com/jbenet/go-datastore"
dsq
"github.com/jbenet/go-datastore/query"
)
// op keys
var
(
putKey
=
"put"
getKey
=
"get"
hasKey
=
"has"
deleteKey
=
"delete"
)
type
datastore
struct
{
cache
ds
.
Datastore
ttl
time
.
Duration
ttlmu
sync
.
Mutex
ttls
map
[
ds
.
Key
]
time
.
Time
}
func
WithTTL
(
ttl
time
.
Duration
)
ds
.
Datastore
{
return
WithCache
(
ds
.
NewMapDatastore
(),
ttl
)
}
// WithCache wraps a given datastore as a timecache.
// Get + Has requests are considered expired after a TTL.
func
WithCache
(
d
ds
.
Datastore
,
ttl
time
.
Duration
)
ds
.
Datastore
{
return
&
datastore
{
cache
:
d
,
ttl
:
ttl
,
ttls
:
make
(
map
[
ds
.
Key
]
time
.
Time
)}
}
func
(
d
*
datastore
)
gc
()
{
var
now
=
time
.
Now
()
var
del
[]
ds
.
Key
// remove all expired ttls.
d
.
ttlmu
.
Lock
()
for
k
,
ttl
:=
range
d
.
ttls
{
if
now
.
After
(
ttl
)
{
delete
(
d
.
ttls
,
k
)
del
=
append
(
del
,
k
)
}
}
d
.
ttlmu
.
Unlock
()
for
_
,
k
:=
range
del
{
d
.
cache
.
Delete
(
k
)
}
}
func
(
d
*
datastore
)
ttlPut
(
key
ds
.
Key
)
{
d
.
ttlmu
.
Lock
()
d
.
ttls
[
key
]
=
time
.
Now
()
.
Add
(
d
.
ttl
)
d
.
ttlmu
.
Unlock
()
}
func
(
d
*
datastore
)
ttlDelete
(
key
ds
.
Key
)
{
d
.
ttlmu
.
Lock
()
delete
(
d
.
ttls
,
key
)
d
.
ttlmu
.
Unlock
()
}
// Put stores the object `value` named by `key`.
func
(
d
*
datastore
)
Put
(
key
ds
.
Key
,
value
interface
{})
(
err
error
)
{
err
=
d
.
cache
.
Put
(
key
,
value
)
d
.
ttlPut
(
key
)
return
err
}
// Get retrieves the object `value` named by `key`.
func
(
d
*
datastore
)
Get
(
key
ds
.
Key
)
(
value
interface
{},
err
error
)
{
d
.
gc
()
return
d
.
cache
.
Get
(
key
)
}
// Has returns whether the `key` is mapped to a `value`.
func
(
d
*
datastore
)
Has
(
key
ds
.
Key
)
(
exists
bool
,
err
error
)
{
d
.
gc
()
return
d
.
cache
.
Has
(
key
)
}
// Delete removes the value for given `key`.
func
(
d
*
datastore
)
Delete
(
key
ds
.
Key
)
(
err
error
)
{
d
.
ttlDelete
(
key
)
return
d
.
cache
.
Delete
(
key
)
}
// Query returns a list of keys in the datastore
func
(
d
*
datastore
)
Query
(
q
dsq
.
Query
)
(
dsq
.
Results
,
error
)
{
return
d
.
cache
.
Query
(
q
)
}
timecache/timecache_test.go
0 → 100644
View file @
731e20de
package
timecache
import
(
"testing"
"time"
ds
"github.com/jbenet/go-datastore"
)
func
testHas
(
t
*
testing
.
T
,
d
ds
.
Datastore
,
k
ds
.
Key
,
v
interface
{})
{
if
v2
,
err
:=
d
.
Get
(
k
);
err
!=
nil
{
t
.
Error
(
err
)
}
else
if
v2
!=
v
{
t
.
Error
(
"value incorrect"
,
d
,
k
,
v
,
v2
)
}
if
has
,
err
:=
d
.
Has
(
k
);
err
!=
nil
{
t
.
Error
(
err
)
}
else
if
!
has
{
t
.
Error
(
"should have it"
,
d
,
k
,
v
)
}
}
func
testNotHas
(
t
*
testing
.
T
,
d
ds
.
Datastore
,
k
ds
.
Key
)
{
if
_
,
err
:=
d
.
Get
(
k
);
err
==
nil
{
t
.
Error
(
"should not have it"
,
d
,
k
)
}
if
has
,
err
:=
d
.
Has
(
k
);
err
!=
nil
{
t
.
Error
(
err
)
}
else
if
has
{
t
.
Error
(
"should not have it"
,
d
,
k
)
}
}
func
TestTimeCache
(
t
*
testing
.
T
)
{
ttl
:=
time
.
Millisecond
*
100
cache
:=
WithTTL
(
ttl
)
cache
.
Put
(
ds
.
NewKey
(
"foo1"
),
"bar1"
)
cache
.
Put
(
ds
.
NewKey
(
"foo2"
),
"bar2"
)
<-
time
.
After
(
ttl
/
2
)
cache
.
Put
(
ds
.
NewKey
(
"foo3"
),
"bar3"
)
cache
.
Put
(
ds
.
NewKey
(
"foo4"
),
"bar4"
)
testHas
(
t
,
cache
,
ds
.
NewKey
(
"foo1"
),
"bar1"
)
testHas
(
t
,
cache
,
ds
.
NewKey
(
"foo2"
),
"bar2"
)
testHas
(
t
,
cache
,
ds
.
NewKey
(
"foo3"
),
"bar3"
)
testHas
(
t
,
cache
,
ds
.
NewKey
(
"foo4"
),
"bar4"
)
<-
time
.
After
(
ttl
/
2
)
testNotHas
(
t
,
cache
,
ds
.
NewKey
(
"foo1"
))
testNotHas
(
t
,
cache
,
ds
.
NewKey
(
"foo2"
))
testHas
(
t
,
cache
,
ds
.
NewKey
(
"foo3"
),
"bar3"
)
testHas
(
t
,
cache
,
ds
.
NewKey
(
"foo4"
),
"bar4"
)
cache
.
Delete
(
ds
.
NewKey
(
"foo3"
))
testNotHas
(
t
,
cache
,
ds
.
NewKey
(
"foo3"
))
<-
time
.
After
(
ttl
/
2
)
testNotHas
(
t
,
cache
,
ds
.
NewKey
(
"foo1"
))
testNotHas
(
t
,
cache
,
ds
.
NewKey
(
"foo2"
))
testNotHas
(
t
,
cache
,
ds
.
NewKey
(
"foo3"
))
testNotHas
(
t
,
cache
,
ds
.
NewKey
(
"foo4"
))
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment