/*
* @Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
*/
package memorycache
import stdx.encoding.json.JsonObject
import std.sync.AtomicInt64
import std.collection.concurrent.ConcurrentHashMap
import std.collection.concurrent.LinkedBlockingQueue
public class FifoCache <: Cache {
private var cache: ConcurrentHashMap<String, String>
private var capacity: Int64
private var fn: AtomicInt64
private var trackingQueue: LinkedBlockingQueue<String>
public init(capacity: Int64) {
if (capacity < 1) {
throw MemoryCacheException("capacity must be greater than 0")
}
this.capacity = capacity
this.cache = ConcurrentHashMap<String, String>()
this.fn = AtomicInt64(0)
this.trackingQueue = LinkedBlockingQueue<String>()
}
public func contains(key: String): Bool {
return cache.contains(key)
}
public func getCapacity(): Int64 {
return capacity
}
public func setCapacity(capacity: Int64) {
if (capacity < 1) {
throw MemoryCacheException("capacity must be greater than 0")
}
this.capacity = capacity
while (fn.load() > capacity) {
var key = trackingQueue.remove()
cache.remove(key)
fn.fetchSub(1)
}
}
public func clear(): Unit {
cache = ConcurrentHashMap<String, String>()
trackingQueue = LinkedBlockingQueue<String>()
}
public func get(key: String): Option<String> {
return cache.get(key)
}
public func put(key: String, value: String) {
match (cache.add(key, value)) {
case None => if (fn.fetchAdd(1) >= capacity) {
cache.remove(trackingQueue.remove())
trackingQueue.add(key)
} else {
trackingQueue.add(key)
}
case Some(_) => ()
}
}
public func remove(): Option<String> {
if (fn.load() == 0) {
return None
}
var res = cache.remove(trackingQueue.remove())
if (res.isSome()) {
fn.fetchSub(1)
}
return res
}
}