/*
* @Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
*/
package memorycache
import std.sync.Mutex
import std.collection.HashMap
import std.collection.LinkedList
public class MemoryCache <: Cache {
private var cache: HashMap<String, String>
private var capacity: Int64
private var mtx: Mutex
private var trackingQueue: LinkedList<String>
public init(capacity: Int64) {
if (capacity < 1) {
throw MemoryCacheException("capacity must be greater than 0")
}
this.capacity = capacity
this.cache = HashMap<String, String>()
this.mtx = Mutex()
this.trackingQueue = LinkedList<String>()
}
private func trackingRemove(key: String) {
var node = trackingQueue.firstNode
while (true) {
match (node) {
case Some(v) => if (v.value == key) {
trackingQueue.remove(v)
break
} else {
node = v.next
}
case None => break
}
}
}
public func contains(key: String): Bool {
synchronized(mtx) {
return cache.contains(key)
}
}
public func get(key: String): Option<String> {
synchronized(mtx) {
var val = cache.get(key)
match (val) {
case Some(v) =>
trackingRemove(key)
trackingQueue.addLast(key)
case None => ()
}
return val
}
}
public func put(key: String, value: String): Unit {
synchronized(mtx) {
match (cache.get(key)) {
case Some(V) =>
cache.add(key, value)
trackingRemove(key)
trackingQueue.addLast(key)
case None =>
if (cache.size == capacity) {
cache.remove(trackingQueue.removeFirst().getOrThrow())
}
cache.add(key, value)
trackingQueue.addLast(key)
}
}
}
public func remove(key: String): Option<String> {
synchronized(mtx) {
trackingRemove(key)
return cache.remove(key)
}
}
public func clear(): Unit {
synchronized(mtx) {
cache.clear()
trackingQueue.clear()
}
}
public func getCapacity(): Int64 {
synchronized(mtx) {
return capacity
}
}
public func setCapacity(capacity: Int64) {
if (capacity < 1) {
throw MemoryCacheException("capacity must be greater than 0")
}
synchronized(mtx) {
this.capacity = capacity
while (cache.size > capacity) {
var key = trackingQueue.removeLast().getOrThrow()
cache.remove(key)
}
}
}
}