Skip to content

Commit

Permalink
Cache managed resource (#71)
Browse files Browse the repository at this point in the history
* Add .bsp to .gitignore

* Extract KeySet and MapKey out of Cache

Because they probably going to be shared with ManagedCache

* define interface for a ManagedCache

* Copy/Paste: cache implementation and cache test for managedCache

* Adapt cache implementation and test for ManagedCache

* make ManagedCache.get return Managed[Error, Value] instead of UIO[Managed[Error, Value]]

* Make ManagedCache work on 2.11 and Scala 3

* Fix doc after Adam's review

* fixup! Fix doc after Adam's review

* fixup! Fix doc after Adam's review
  • Loading branch information
strokyl authored Jun 3, 2022
1 parent 6fb05d1 commit 4ec7a42
Show file tree
Hide file tree
Showing 9 changed files with 1,474 additions and 70 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -408,10 +408,12 @@ project/plugins/project/
.metals/
metals.sbt
.bloop/
.bsp/
project/secret

# mdoc
website/node_modules
website/build
website/i18n/en.json
website/static/api

7 changes: 4 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ lazy val zioCache = crossProject(JSPlatform, JVMPlatform, NativePlatform)
.settings(buildInfoSettings("zio.cache"))
.settings(
libraryDependencies ++= Seq(
"dev.zio" %% "zio" % zioVersion,
"dev.zio" %% "zio-test" % zioVersion % Test,
"dev.zio" %% "zio-test-sbt" % zioVersion % Test
"dev.zio" %% "zio" % zioVersion,
"org.scala-lang.modules" %% "scala-collection-compat" % "2.7.0",
"dev.zio" %% "zio-test" % zioVersion % Test,
"dev.zio" %% "zio-test-sbt" % zioVersion % Test
)
)
.settings(testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework"))
Expand Down
67 changes: 0 additions & 67 deletions zio-cache/shared/src/main/scala/zio/cache/Cache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -281,17 +281,6 @@ object Cache {
}
}

/**
* A `MapKey` represents a key in the cache. It contains mutable references
* to the previous key and next key in the `KeySet` to support an efficient
* implementation of a sorted set of keys.
*/
private final class MapKey[Key](
val value: Key,
var previous: MapKey[Key] = null,
var next: MapKey[Key] = null
)

/**
* A `MapValue` represents a value in the cache. A value may either be
* `Pending` with a `Promise` that will contain the result of computing the
Expand Down Expand Up @@ -346,60 +335,4 @@ object Cache {
new AtomicBoolean(false)
)
}

/**
* A `KeySet` is a sorted set of keys in the cache ordered by last access.
* For efficiency, the set is implemented in terms of a doubly linked list
* and is not safe for concurrent access.
*/
private final class KeySet[Key] {
private[this] var head: MapKey[Key] = null
private[this] var tail: MapKey[Key] = null

/**
* Adds the specified key to the set.
*/
def add(key: MapKey[Key]): Unit =
if (key ne tail) {
if (tail ne null) {
val previous = key.previous
val next = key.next
if (next ne null) {
key.next = null
if (previous ne null) {
previous.next = next
next.previous = previous
} else {
head = next
head.previous = null
}
}
tail.next = key
key.previous = tail
tail = key
} else {
head = key
tail = key
}
}

/**
* Removes the lowest priority key from the set.
*/
def remove(): MapKey[Key] = {
val key = head
if (key ne null) {
val next = key.next
if (next ne null) {
key.next = null
head = next
head.previous = null
} else {
head = null
tail = null
}
}
key
}
}
}
57 changes: 57 additions & 0 deletions zio-cache/shared/src/main/scala/zio/cache/KeySet.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package zio.cache

/**
* A `KeySet` is a sorted set of keys in the cache ordered by last access.
* For efficiency, the set is implemented in terms of a doubly linked list
* and is not safe for concurrent access.
*/
private[cache] final class KeySet[Key] {
private[this] var head: MapKey[Key] = null
private[this] var tail: MapKey[Key] = null

/**
* Adds the specified key to the set.
*/
def add(key: MapKey[Key]): Unit =
if (key ne tail) {
if (tail ne null) {
val previous = key.previous
val next = key.next
if (next ne null) {
key.next = null
if (previous ne null) {
previous.next = next
next.previous = previous
} else {
head = next
head.previous = null
}
}
tail.next = key
key.previous = tail
tail = key
} else {
head = key
tail = key
}
}

/**
* Removes the lowest priority key from the set.
*/
def remove(): MapKey[Key] = {
val key = head
if (key ne null) {
val next = key.next
if (next ne null) {
key.next = null
head = next
head.previous = null
} else {
head = null
tail = null
}
}
key
}
}
Loading

0 comments on commit 4ec7a42

Please sign in to comment.