-
Notifications
You must be signed in to change notification settings - Fork 203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ready for Review: Weigher Impl #156
Conversation
@@ -54,6 +54,14 @@ interface Cache<in Key : Any, Value : Any> { | |||
*/ | |||
interface Builder { | |||
|
|||
@ExperimentalTime | |||
var expireAfterWriteDuration: Duration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
had to pull these into interface for extension build function. My question about these (for follow up) - do we need the setter functions or can we have a builder with only vars and set()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setter functions return the instance whereas simple vars do not. So that allows chain of the method calls.
val weigher: Weigher<Key, Value> = OneWeigher(), | ||
val maxWeight: Long = UNSET_LONG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the default parameters? this class is internal
anyway so we can just choose the defaults in builder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the default builder is weigher agnostic it felt cleaner here.
fun weigh(key: K, value: V): Int | ||
} | ||
|
||
class OneWeigher<K : Any, V : Any> : Weigher<K, V> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
internal
?
cache/src/main/kotlin/com/dropbox/android/external/cache4/RealCache.kt
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. If Store3 had tests around this, it would be good to bring those.
Great let me finish up tonight/tomorrow. We did not have tests since it was
a straight fork of Guava. Let me add tests
…On Sun, Apr 26, 2020, 1:38 PM Said Tahsin Dane ***@***.***> wrote:
***@***.**** approved this pull request.
Looks good to me. If Store3 had tests around this, it would be good to
bring those.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#156 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABCRPXH3RTNS4GEKJVVWUOLRORWSPANCNFSM4MMAC7UA>
.
|
We have some tests in Apollo testing our weigher implementation and it's Integration with the cache. Does Store have snapshots? I can quickly check and run those. |
Any plans to finalize this? We need this in order to migrate from old version. Thanks. |
Yes this week. Sorry got pulled off and time flies |
Thanks ❤️ |
Ran into a race condition while trying to land. Will continue tonight (almost there) |
…Cache.kt Co-Authored-By: Yang <ychescale9@gmail.com>
7e65133
to
46e583f
Compare
@tasomaniac should be good to go, mind reviewing? |
Codecov Report
@@ Coverage Diff @@
## master #156 +/- ##
============================================
- Coverage 86.01% 85.62% -0.39%
+ Complexity 230 229 -1
============================================
Files 54 56 +2
Lines 951 981 +30
Branches 149 156 +7
============================================
+ Hits 818 840 +22
- Misses 76 77 +1
- Partials 57 64 +7
Continue to review full report at Codecov.
|
@@ -78,6 +81,8 @@ internal class RealCache<Key : Any, Value : Any>( | |||
*/ | |||
private val loadersSynchronizer = KeyedSynchronizer<Key>() | |||
|
|||
private var totalWeight = 0L |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was this reverted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops good catch. I'll add tests for the new builder as well. BTW your tests were great and caught a logic error of mine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some tests would be great 😃
@ychescale9 ready to review, I added tests. The most interesting one was |
@@ -139,12 +148,22 @@ internal class RealCache<Key : Any, Value : Any>( | |||
val existingEntry = cacheEntries[key] | |||
if (existingEntry != null) { | |||
// cache entry found | |||
recordWrite(existingEntry, nowNanos) | |||
// remove the weight of the current entry | |||
totalWeight -= existingEntry.weight |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cache is multi-threaded and this is not thread safe.
This is actually not easy to fix without adding substantial synchronization to the cache (or adding other optimizations beyond the scope of this cache). The reason is that you need to make sure the state of cachedEntries
and totalWeight
is updated atomically.
existingEntry.value = value | ||
existingEntry.weight = weight |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
value and weight need to be updated atomically (e.g put them in pair or data class)
#200 is the fix for this |
Resolve #153
I was able to implement as extension function. Doing as a subclass of Builder did not work out due to
build
function taking a parameterized type. I could not figure out how to make that one the same as the class parameters on WeighingCacheBuilderI can't get tests to run locally, will run and add new ones tomorrow.
My biggest question is whether
expireEntries
needs to reduce the total weight. Initially I had it reducing total weight but previous impl (copied from guava) did not do it.https://github.com/nytimes/Store/blob/e4c21b23c80ba1c6a2f5c451066ed7adff3592f0/cache/src/main/java/com/nytimes/android/external/cache3/LocalCache.java#L2657
Bug or feature?
TODO Tests tomorrow