irgaly / kottage

Kotlin Multiplatform Key-Value Store Local Cache Storage for Single Source of Truth.
Other
70 stars 0 forks source link

[Feature] Auto Populate List #250

Open chrisjenx opened 2 months ago

chrisjenx commented 2 months ago

I was of the understanding that cache.list() would be backed completely by the cache object. But it's very confusing api when cache and list are independent of each other, for example:

I would expect this to work:

val cache = kottage.cache( //...
val list = cache.list( // ...

// I thought cache was backing the list 
cache.put("id", TestClass())
val results = list.getPageFrom(null, null)
results.items shouldHaveSize 1 // fails 

This creates some confusing API interactions, now I want to update a value based on key, if I don't handle that gracefully:

cache.put("id", TestClass())
list.addKey("id")
// Then update later
cache.put("id", TestClass())
list.addKey("id")

// I now get:
val results = list.getPageFrom(null, null)
results.items shouldHaveSize 1 // fails because the equals 2

// I have to wrap in something like:
    open suspend fun put(key: String, value: T) {
        val exists = cache.exists(key)
        cache.put(key, value, type)
        if (!exists) list.addKey(key)
    }

Either:

Or:

val results = list.getPageFrom(null, null) results.items shouldHaveSize 1 // should succeed because the list is backed by the cache



Thoughts?
irgaly commented 2 months ago

I agree with you that the Kottage List feature has complex API and confusable...

The items of Kottage List may have same reference to items in Kottage Cache.

val cache = kottage.cache("cache A")
val list = cache.list("list A")
cache.put("other", ...) // add new "other" item to Cache
list.add("item1", ...) // add new "item1" item to Cache and List
list.add("item2", ...) // add new "item2" item to Cache and List
list.add("item3", ...) // add new "item3" item to Cache and List
list.add("item1") // add "item1" item from Cache to List
list.add("item2") // add "item2" item from Cache to List

// cache has 4 items
// list has 5 items

This will be:

flowchart LR
  subgraph cacheA["cache A (like Map<String, Any>)"]
    item1["key = 'item1'<br/>value = '...'"]
    item2["key = 'item2'<br/>value = '...'"]
    item3["key = 'item3'<br/>value = '...'"]
    other["key = 'other'<br/>value = '...'"]
  end
  subgraph listA["list A (like LinkedList)"]
    listItem1["list item 1 (reference to 'item1')"]
    listItem2["list item 2 (reference to 'item2')"]
    listItem3["list item 3 (reference to 'item3')"]
    listItem4["list item 4 (reference to 'item1')"]
    listItem5["list item 5 (reference to 'item2')"]
  end
  listItem1 ==> listItem2
  listItem2 ==> listItem3
  listItem3 ==> listItem4
  listItem4 ==> listItem5
  listItem1 -. ref .-> item1
  listItem2 -. ref .-> item2
  listItem3 -. ref .-> item3
  listItem4 -. ref .-> item1
  listItem5 -. ref .-> item2

For more description, in your case:

cache.put("id", TestClass())
val results = list.getPageFrom(null, null)

// cache has 1 item
// list has 0 items

will be:

flowchart LR
  subgraph cache
    item1["key = 'id'<br/>value = TestClass"]
  end
  subgraph list["list (empty)"]
    empty["(no item in list)"]
  end

cache.put("id", TestClass())
list.addKey("id")
cache.put("id", TestClass())
list.addKey("id")

// cache has 1 item
// list has 2 item

will be:

flowchart LR
  subgraph cache
    item1["key = 'id'<br/>value = TestClass"]
  end
  subgraph list
    listItem1["list item 1 (reference to 'item1')"]
    listItem2["list item 2 (reference to 'item1')"]
  end
  listItem1 ==> listItem2
  listItem1 -. ref .-> item1
  listItem2 -. ref .-> item1

List should be created directly from kottage.list() that way theres no way to get into weird states and you only interact with the list api. (Would need to add, get(key)/replace(key)/remove(key) to make that useable.

Kottage Cache is KVS, but Kottage List is Linked List, so Kottage List's items cannot be accessed by key. That can be accessed only by page.

  • list should be automatically backed by the cache:

Kottage List is not have all items in Cache. The items in cache can be added to list and remove from list in any time.

valeriyo commented 1 month ago

@chrisjenx I think you are asking for the same thing as I -- https://github.com/irgaly/kottage/discussions/254 -- a simple way to get all keys in storage (which is glaringly missing) and attempts to use KottageList for that doesn't quite fit, because: