forked from joey/godottest
98 lines
2.8 KiB
GDScript
98 lines
2.8 KiB
GDScript
extends RefCounted
|
|
class_name GedisExpiry
|
|
|
|
var _gedis: Gedis
|
|
|
|
# Provides an ordered view of expirations for efficient purging.
|
|
# The list is sorted by timestamp and stores [timestamp, key] pairs.
|
|
var _expiry_list: Array
|
|
|
|
func _init(p_gedis: Gedis):
|
|
_gedis = p_gedis
|
|
_expiry_list = []
|
|
|
|
func _now() -> int:
|
|
return _gedis._time_source.get_time()
|
|
|
|
func _is_expired(key: String) -> bool:
|
|
if _gedis._core._expiry.has(key) and _gedis._core._expiry[key] <= _now():
|
|
var timestamp = _gedis._core._expiry[key]
|
|
_gedis._core._delete_all_types_for_key(key)
|
|
var entry = [timestamp, key]
|
|
var index = _expiry_list.bsearch(entry)
|
|
if index < _expiry_list.size() and _expiry_list[index] == entry:
|
|
_expiry_list.remove_at(index)
|
|
return true
|
|
return false
|
|
|
|
func _purge_expired() -> void:
|
|
var now := _now()
|
|
var expired_count := 0
|
|
var ex := _gedis._core._expiry
|
|
for item in _expiry_list:
|
|
var timestamp: int = item[0]
|
|
var key: String = item[1]
|
|
|
|
if timestamp <= now:
|
|
if ex.has(key) and ex[key] == timestamp:
|
|
_gedis._core._delete_all_types_for_key(key)
|
|
_gedis.publish("gedis:keyspace:" + key, "expire")
|
|
expired_count += 1
|
|
else:
|
|
break
|
|
|
|
if expired_count > 0:
|
|
_expiry_list = _expiry_list.slice(expired_count)
|
|
|
|
# ----------------
|
|
# Expiry commands
|
|
# ----------------
|
|
func expire(key: String, seconds: int) -> bool:
|
|
if not _gedis.exists(key):
|
|
return false
|
|
|
|
# If the key already has an expiry, remove the old entry from the sorted list.
|
|
if _gedis._core._expiry.has(key):
|
|
var old_timestamp = _gedis._core._expiry[key]
|
|
var old_entry = [old_timestamp, key]
|
|
var index = _expiry_list.bsearch(old_entry)
|
|
if index < _expiry_list.size() and _expiry_list[index] == old_entry:
|
|
_expiry_list.remove_at(index)
|
|
|
|
var new_timestamp = _now() + (float(seconds) * 1000.0)
|
|
_gedis._core._expiry[key] = new_timestamp
|
|
|
|
# Add the new expiry to the sorted list.
|
|
var new_entry = [new_timestamp, key]
|
|
var insertion_index = _expiry_list.bsearch(new_entry)
|
|
_expiry_list.insert(insertion_index, new_entry)
|
|
|
|
return true
|
|
|
|
# TTL returns:
|
|
# -2 if the key does not exist
|
|
# -1 if the key exists but has no associated expire
|
|
# >= 0 number of seconds to expire
|
|
func ttl(key: String) -> int:
|
|
if not _gedis.exists(key):
|
|
return -2
|
|
if not _gedis._core._expiry.has(key):
|
|
return -1
|
|
return max(0, int(ceil((_gedis._core._expiry[key] - _now()) / 1000.0)))
|
|
|
|
func persist(key: String) -> bool:
|
|
if not _gedis.exists(key):
|
|
return false
|
|
if _gedis._core._expiry.has(key):
|
|
var timestamp = _gedis._core._expiry[key]
|
|
_gedis._core._expiry.erase(key)
|
|
var entry = [timestamp, key]
|
|
var index = _expiry_list.bsearch(entry)
|
|
if index < _expiry_list.size() and _expiry_list[index] == entry:
|
|
_expiry_list.remove_at(index)
|
|
return true
|
|
return false
|
|
|
|
func setex(key: String, seconds: int, value: Variant) -> void:
|
|
_gedis.set_value(key, value)
|
|
expire(key, seconds) |