Created
April 12, 2025 15:11
-
-
Save tinkerer-red/3dda4095dea382cca89994e1a78a1665 to your computer and use it in GitHub Desktop.
Tries buffer implementation in gml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function convert_to_array_map(_map) { | |
static __buff = buffer_create(0, buffer_grow, 1); | |
var root = array_create(256, undefined); // Root node | |
var _names = struct_get_names(_map); | |
var _length = array_length(_names); | |
for (var _i = 0; _i < _length; _i++) { | |
var _find = _names[_i]; | |
var _replace = _map[$ _find]; | |
buffer_write(__buff, buffer_text, _find); | |
var _byte_len = buffer_tell(__buff); | |
buffer_seek(__buff, buffer_seek_start, 0); | |
var node = root; // Start at root | |
var _j = 0; | |
while (_j < _byte_len) { | |
var _byte = buffer_read(__buff, buffer_u8); | |
_j++; | |
if (node[_byte] == undefined) { | |
node[_byte] = array_create(256, undefined); // Create new array node | |
} | |
node = node[_byte]; // Move to next depth | |
} | |
node[0] = _replace; // Store replacement in index `0`, since `0` in a string is a terminator byte. | |
buffer_resize(__buff, 0); // Reset buffer for next word | |
} | |
return root; // Return just the trie | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function string_replace_all_struct(input_string, _map, _case_sensitive=true) { | |
static temp_buff = buffer_create(0, buffer_grow, 1); // literally only used to write a string into a fast buffer with buffer_copy | |
static input_buff = buffer_create(0, buffer_fast, 1); | |
static output_buff = buffer_create(0, buffer_grow, 1); | |
static holder_buff = buffer_create(0, buffer_fast, 1); // Temporary buffer to store bytes | |
//micro optimization | |
var _temp_buff = temp_buff; | |
var _input_buff = input_buff; | |
var _output_buff = output_buff; | |
var _holder_buff = holder_buff; | |
// Pre-allocate sizes | |
var byte_len = string_byte_length(input_string); | |
buffer_resize(_input_buff, byte_len) | |
buffer_resize(_output_buff, byte_len) | |
buffer_resize(_holder_buff, byte_len) | |
// Write input buffer | |
buffer_write(_temp_buff, buffer_text, input_string); | |
buffer_copy(_temp_buff, 0, byte_len, _input_buff, 0) | |
buffer_resize(_temp_buff, 0) | |
//probably want to cache this if possible | |
var lookup = _map; // Precompute nested hashmap | |
//used for keeping track of the last found replacement | |
var _replacement = undefined; | |
// Buffer Tell positions (optimization) | |
var input_pos = 0; | |
var output_pos = 0; | |
var holder_pos = 0; | |
var node = lookup; | |
var byte = undefined; | |
while (byte || input_pos < byte_len) { | |
if (byte == undefined){ | |
byte = buffer_read(_input_buff, buffer_u8); // Read UTF-16 codepoint | |
input_pos += 1; | |
} | |
var _temp = node[byte] | |
if (!_case_sensitive && _temp == undefined) { | |
// A-Z → a-z | |
if (byte >= 65 && byte <= 90) { | |
var lookup_byte = byte + 32; | |
_temp = node[lookup_byte]; | |
} | |
// a-z → A-Z | |
else if (byte >= 97 && byte <= 122) { | |
var lookup_byte = byte - 32; | |
_temp = node[lookup_byte]; | |
} | |
} | |
if (_temp != undefined) { | |
node = _temp; // Move deeper into the nested hashmap | |
// Check if the static struct exists and has "value" | |
var _value = node[0]; | |
if (_value != undefined) { | |
_replacement = _value; | |
buffer_seek(_holder_buff, buffer_seek_start, 0); // Reset holder buffer | |
holder_pos = 0; | |
} | |
else { | |
// Store byte in holder buffer | |
buffer_write(_holder_buff, buffer_u8, byte); | |
holder_pos++; | |
} | |
byte = undefined; | |
continue; | |
} | |
else { | |
if (_replacement != undefined) { | |
buffer_write(_output_buff, buffer_text, _replacement); | |
_replacement = undefined; | |
node = lookup; | |
continue; | |
} | |
//if we had a replacement char found in the map | |
if (holder_pos) { | |
buffer_copy(_holder_buff, 0, holder_pos, _output_buff, buffer_tell(_output_buff)); | |
buffer_seek(_output_buff, buffer_seek_relative, holder_pos); // Reset holder buffer | |
buffer_seek(_holder_buff, buffer_seek_start, 0); // Reset holder buffer | |
holder_pos = 0; | |
} | |
// No match found, write the original character | |
buffer_write(_output_buff, buffer_u8, byte); | |
byte = undefined; | |
node = lookup; | |
} | |
} | |
// Final replacement in case we end on a valid match | |
if (_replacement != undefined) { | |
buffer_write(_output_buff, buffer_text, _replacement); | |
} | |
// Convert buffer back to string | |
buffer_seek(_output_buff, buffer_seek_start, 0); | |
var result = buffer_read(_output_buff, buffer_text); | |
buffer_resize(_input_buff, 0); | |
buffer_resize(_output_buff, 0); | |
buffer_resize(_holder_buff, 0); | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment