Skip to content

Commit

Permalink
Merge pull request #1 from TBCBank/change/add_more_response_values_to…
Browse files Browse the repository at this point in the history
…_cache

Add more response values to cache model
  • Loading branch information
nikachapo authored Mar 29, 2024
2 parents b6aa9ee + 371b982 commit a8499d0
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 88 deletions.
2 changes: 1 addition & 1 deletion app/src/main/java/ge/tbcbank/retrocache/TestApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import retrofit2.http.Path

interface TestApi {

@Cache(tag = "mtag", cacheTimeMillis = 60_000)
@Cache(tag = "mtag")
@GET("search" + "/{query}/{page}")
suspend fun getBookWithPage(
@Path("page") page: String,
Expand Down
4 changes: 2 additions & 2 deletions retrocache/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
}

group = "ge.tbcbank.retrocache"
version "1.0"
version "1.0.1"

dependencies {
val okhttp = "4.11.0"
Expand All @@ -34,7 +34,7 @@ afterEvaluate {
from(components["java"])
groupId = "com.github.TBCBank"
artifactId = "RetroCache"
version = "1.0"
version = "1.0.1"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package ge.tbcbank.retrocache

import okhttp3.Headers
import okhttp3.Interceptor
import okhttp3.Protocol
import okhttp3.RequestBody
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
Expand Down Expand Up @@ -29,11 +29,12 @@ class RetroCacheInterceptor(
val cachedData = retroCacheManager[key].takeIf { fromCache }
if (cachedData != null) {
Response.Builder()
.code(200)
.request(request)
.message("From RetroCache")
.request(request)
.code(cachedData.responseCode)
.body(cachedData.responseJson?.toResponseBody())
.protocol(Protocol.HTTP_1_1)
.protocol(cachedData.responseProtocol)
.headers(Headers.headersOf(*cachedData.responseHeaders))
.build()
} else {
val response = chain.proceed(request)
Expand All @@ -42,6 +43,9 @@ class RetroCacheInterceptor(
responseJson = response
.peekBody(retroCacheManager.maxObjectSizeBytes.toLong())
.string(),
responseCode = response.code,
responseProtocol = response.protocol,
responseHeaders = response.headers.toArray(),
tag = cacheAnnotation.tag.ifEmpty { null },
expirationTime = getCacheTime(cacheAnnotation, cachePolicy),
)
Expand All @@ -56,6 +60,15 @@ class RetroCacheInterceptor(
}
}

private fun Headers.toArray(): Array<String> {
val headerList = mutableListOf<String>()
forEach {
headerList.add(it.first)
headerList.add(it.second)
}
return headerList.toTypedArray()
}

private fun getCacheTime(cacheAnnotation: Cache, cachePolicy: CachePolicy?): Long? {
if (cachePolicy is CachePolicy.CachedWithTime) {
return System.currentTimeMillis() + cachePolicy.timeInMillis
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,40 @@
package ge.tbcbank.retrocache

import okhttp3.Protocol
import java.io.Serializable

data class RetroCacheValue(
val responseJson: String?,
val responseCode: Int,
val responseProtocol: Protocol,
val responseHeaders: Array<String>,
val tag: String? = null,
val expirationTime: Long? = null,
) : Serializable
) : Serializable {

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as RetroCacheValue

if (responseJson != other.responseJson) return false
if (responseCode != other.responseCode) return false
if (responseProtocol != other.responseProtocol) return false
if (!responseHeaders.contentEquals(other.responseHeaders)) return false
if (tag != other.tag) return false
return expirationTime == other.expirationTime
}

override fun hashCode(): Int {
var result = responseJson?.hashCode() ?: 0
result = 31 * result + responseCode
result = 31 * result + responseProtocol.hashCode()
result = 31 * result + responseHeaders.contentHashCode()
result = 31 * result + (tag?.hashCode() ?: 0)
result = 31 * result + (expirationTime?.hashCode() ?: 0)
return result
}


}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ge.tbcbank.retrocache

import okhttp3.Protocol
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
Expand All @@ -12,7 +13,7 @@ class RetroCacheManagerTest {
@Test
fun `get returns cached object when present`() {
val cacheManager = RetroCacheManager.Builder().build()
val model = RetroCacheValue("test", "123")
val model = getRetroCacheModel()
cacheManager["key"] = model

val cachedModel = cacheManager["key"]
Expand All @@ -23,12 +24,14 @@ class RetroCacheManagerTest {
@Test
fun `get returns null when object expired`() {
val cacheManager = RetroCacheManager.Builder().build()
val model =
RetroCacheValue(
"test",
"123",
expirationTime = System.currentTimeMillis() - 1000
)
val model = RetroCacheValue(
responseJson = "test",
responseCode = 200,
responseProtocol = Protocol.HTTP_1_1,
responseHeaders = arrayOf(),
tag = "123",
expirationTime = System.currentTimeMillis() - 1000
)
cacheManager["key"] = model

val cachedModel = cacheManager["key"]
Expand All @@ -39,8 +42,8 @@ class RetroCacheManagerTest {
@Test
fun `set adds object to cache`() {
val cacheManager = RetroCacheManager.Builder().build()
val model = RetroCacheValue("test", "123")

val model = getRetroCacheModel()
cacheManager["key"] = model

val cachedModel = cacheManager["key"]
Expand All @@ -50,7 +53,7 @@ class RetroCacheManagerTest {
@Test
fun `remove removes object from cache`() {
val cacheManager = RetroCacheManager.Builder().build()
val model = RetroCacheValue("test", "123")
val model = getRetroCacheModel()
cacheManager["key"] = model

cacheManager.remove("key")
Expand All @@ -59,11 +62,19 @@ class RetroCacheManagerTest {
assertNull(cachedModel)
}

private fun getRetroCacheModel(responseJson: String = "test", tag: String = "123") = RetroCacheValue(
responseJson = responseJson,
responseCode = 200,
responseProtocol = Protocol.HTTP_1_1,
responseHeaders = arrayOf(),
tag = tag
)

@Test
fun `clearAll removes all objects from cache`() {
val cacheManager = RetroCacheManager.Builder().build()
cacheManager["key1"] = RetroCacheValue("test1", "123")
cacheManager["key2"] = RetroCacheValue("test2", "456")
cacheManager["key1"] = getRetroCacheModel("test1", "123")
cacheManager["key2"] = getRetroCacheModel("test2", "456")

cacheManager.clearAll()

Expand All @@ -74,9 +85,9 @@ class RetroCacheManagerTest {
@Test
fun `clearAllByTag removes objects with specified tag`() {
val cacheManager = RetroCacheManager.Builder().build()
cacheManager["key1"] = RetroCacheValue("test1", tag = "tag1")
cacheManager["key2"] = RetroCacheValue("test2", tag = "tag1")
cacheManager["key3"] = RetroCacheValue("test3", tag = "tag2")
cacheManager["key1"] = getRetroCacheModel("test1", tag = "tag1")
cacheManager["key2"] = getRetroCacheModel("test2", tag = "tag1")
cacheManager["key3"] = getRetroCacheModel("test3", tag = "tag2")

cacheManager.clearAllByTag("tag1")

Expand Down Expand Up @@ -108,9 +119,9 @@ class RetroCacheManagerTest {
@Test
fun `last accessed object is moved to top of cache`() {
val cacheManager = RetroCacheManager.Builder().build()
cacheManager["key1"] = RetroCacheValue("test1")
cacheManager["key2"] = RetroCacheValue("test2")
cacheManager["key3"] = RetroCacheValue("test3")
cacheManager["key1"] = getRetroCacheModel("test1")
cacheManager["key2"] = getRetroCacheModel("test2")
cacheManager["key3"] = getRetroCacheModel("test3")

var first: RetroCacheValue? = null
var last: RetroCacheValue? = null
Expand Down Expand Up @@ -139,12 +150,12 @@ class RetroCacheManagerTest {
@Test
fun `old cached responses are removed if maxMemory limit has reached`() {
val cacheManager = RetroCacheManager.Builder()
.maxMemorySize(100 * 1024) // 100 kb max memory size
.maxObjectSize(1 * 1024) // 1 kb max memory size
.maxMemorySize(100 * sizeOfObject(getRetroCacheModel(get1KbString()))) // fits 100 object
.maxObjectSize(1 * sizeOfObject(getRetroCacheModel(get1KbString())))
.build()

(0..110).forEach {// add 10 items more than limit
cacheManager[it.toString()] = RetroCacheValue(oneKbString)
cacheManager[it.toString()] = getRetroCacheModel(get1KbString())
}

(0..110).forEach {
Expand All @@ -163,9 +174,8 @@ class RetroCacheManagerTest {
.maxObjectSize(1 * 1024) // 1 kb max memory size
.build()

val invalidSizedString = oneKbString + "12345"
cacheManager["key"] = RetroCacheValue(invalidSizedString)
println(sizeOfObject(RetroCacheValue(invalidSizedString)))
val invalidSizedString = get1KbString() + "12345"
cacheManager["key"] = getRetroCacheModel(invalidSizedString)
assertNull(cacheManager["key"])
}

Expand All @@ -180,62 +190,11 @@ class RetroCacheManagerTest {
}


companion object {
private val oneKbString = """
{
"id": 123,
"name": "John Doe",
"email": "johndoe@example.com",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Anytown",
"country": "USA"
}
}
{
"id": 123,
"name": "John Doe",
"email": "johndoe@example.com",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Anytown",
"country": "USA"
}
}
{
"id": 123,
"name": "John Doe",
"email": "johndoe@example.com",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Anytown",
"country": "USA"
}
}
{
"id": 123,
"name": "John Doe",
"email": "johndoe@example.com",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Anytown",
"country": "USA"
}
}
{
"id": 123,
"name": "John Doe",
"email": "johndoe@example.com",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Anytown",
}1111111
}
""".trimIndent()
private fun get1KbString(): String {
val stringBuilder = StringBuilder()
repeat(1024) {
stringBuilder.append('a')
}
return stringBuilder.toString()
}
}

0 comments on commit a8499d0

Please sign in to comment.