Skip to content

Instantly share code, notes, and snippets.

@tinkerer-red
Created March 17, 2025 23:52
Show Gist options
  • Save tinkerer-red/5675df130e81840dd48abb5fef7df96c to your computer and use it in GitHub Desktop.
Save tinkerer-red/5675df130e81840dd48abb5fef7df96c to your computer and use it in GitHub Desktop.
A Simply Cache System for internal use in functions
function CacheSystem() constructor {
data = {};
static __string_hash = {} //explicetly used to improve the speed at which we hash strings
static save = function(_value) {
var _data = data;
var _cache_ref_key_count = argument_count;
var _last_index = _cache_ref_key_count-1;
for(var _i=1; _i<_cache_ref_key_count; _i++) {
var _arg = argument[_i];
//hash the argument
var _hash = hash_input(_arg);
//parse the cache for matches
var _temp = struct_get_from_hash(_data, _hash)
if (_temp != undefined) {
_data = _temp;
if (_i == _last_index) {
//keep the data from being overritten by arbitrary chance
var _value_holder_static = static_get(_data)
_value_holder_static.value = _value;
}
}
else { //if no match is found make a new one
if (_i == _last_index) {
var _value_holder = {};
//keep the data from being overritten by arbitrary chance
var _value_holder_static = {value: _value};
static_set(_value_holder, _value_holder_static)
struct_set_from_hash(_data, _hash, _value_holder);
}
else {
var _new_data = {};
struct_set_from_hash(_data, _hash, _new_data);
_data = _new_data;
}
}
}
}
static load = function() {
var _data = data;
var _cache_ref_key_count = argument_count;
var _last_index = _cache_ref_key_count-1;
for(var _i=0; _i<_cache_ref_key_count; _i++) {
var _arg = argument[_i];
//hash the argument
var _hash = hash_input(_arg);
//parse the cache for matches
var _temp = struct_get_from_hash(_data, _hash)
if (_temp != undefined) {
_data = _temp
}
else { //if no match is found make a new one
return undefined;
}
}
var _static = static_get(_data)
if (_static) return _static[$ "value"]; // will be undefined if it's not there
return undefined;
}
static remove = function() {
var _prev_data = undefined;
var _data = data;
var _cache_ref_key_count = argument_count;
var _last_index = _cache_ref_key_count-1;
for(var _i=0; _i<_cache_ref_key_count; _i++) {
var _arg = argument[_i];
//hash the argument
var _hash = hash_input(_arg);
var _temp = struct_get_from_hash(_data, _hash)
//parse the cache for matches
var _temp = struct_get_from_hash(_data, _hash)
if (_temp != undefined) {
_prev_data = _data;
_data = _temp;
}
else { //if no match is found make a new one
return;
}
}
if (_prev_data) {
struct_remove_from_hash(_prev_data, _hash)
}
return;
}
static flush = function() {
data = {};
__string_hash = {};
}
// Hashing
static hash_input = function(_arg) {
var _hash = 2166136261; // FNV-1a 32-bit offset basis
switch (typeof(_arg)) {
case "number": case "int32": case "int64": case "bool": {
return hash_combine(_hash, _arg);
}
case "string": {
var _sting_hash = __string_hash[$ _arg]
if (_sting_hash == undefined) {
var _len = string_length(_arg);
for (var i = 1; i <= _len; i++) {
_hash = hash_combine(_hash, ord(string_char_at(_arg, i)));
}
__string_hash[$ _arg] = _hash;
}
else {
_hash = _sting_hash;
}
return _hash;
}
case "array": {
var _len = array_length(_arg);
for (var i = 0; i < _len; i++) {
_hash = hash_combine(_hash, hash_input(_arg[i]));
}
return _hash;
}
case "struct": {
var _keys = variable_struct_get_names(_arg);
array_sort(_keys, true); // Ensure deterministic order
var _len = array_length(_keys);
for (var i = 0; i < _len; i++) {
var _key = _keys[i];
var _val = variable_struct_get(_arg, _key);
_hash = hash_combine(_hash, hash_input(_key));
_hash = hash_combine(_hash, hash_input(_val));
}
return _hash;
}
case "method": case "ptr": case "ref": {
return hash_combine(_hash, hash_input(string(_arg)));
}
case "undefined": {
return hash_combine(_hash, 0xBADF00D); // Arbitrary constant
}
case "null": {
return hash_combine(_hash, 0xDEADBEEF); // Arbitrary constant
}
default: {
return hash_combine(_hash, hash_input(string(_arg))); // Fallback to string representation
}
}
}
static hash_combine = function(_h, _value) {
_value = _value & 0xFFFFFFFF; // Ensure 32-bit range
_h = ((_h ^ _value) * 31) & 0xFFFFFFFF; // Prime multiplication
return ((_h << 5) | (_h >> 27)) & 0xFFFFFFFF; // Rotate bits for better mixing
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment