From 490a68b7968de07ed19b272e4ccfe1fd5b051adb Mon Sep 17 00:00:00 2001 From: howsohazard <143410553+howsohazard@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:05:11 -0400 Subject: [PATCH] 20465: Improves performance of string interning (#216) --- src/Amalgam/AmalgamMain.cpp | 2 +- src/Amalgam/AssetManager.cpp | 6 +- src/Amalgam/AssetManager.h | 4 +- src/Amalgam/Opcodes.cpp | 457 +++++++++-------- src/Amalgam/Opcodes.h | 40 +- src/Amalgam/SeparableBoxFilterDataStore.h | 2 +- src/Amalgam/amlg_code/test.amlg | 39 +- src/Amalgam/entity/Entity.h | 8 +- src/Amalgam/entity/EntityManipulation.cpp | 33 +- src/Amalgam/entity/EntityManipulation.h | 27 +- src/Amalgam/entity/EntityQueryBuilder.h | 30 +- src/Amalgam/evaluablenode/EvaluableNode.cpp | 5 +- src/Amalgam/evaluablenode/EvaluableNode.h | 11 +- .../evaluablenode/EvaluableNodeManagement.h | 6 +- .../EvaluableNodeTreeDifference.cpp | 4 +- .../EvaluableNodeTreeFunctions.h | 14 +- .../EvaluableNodeTreeManipulation.cpp | 8 +- .../EvaluableNodeTreeManipulation.h | 11 +- src/Amalgam/interpreter/Interpreter.cpp | 6 +- src/Amalgam/interpreter/Interpreter.h | 4 +- .../interpreter/InterpreterOpcodesBase.cpp | 9 +- .../InterpreterOpcodesCodeMixing.cpp | 28 +- .../InterpreterOpcodesDataTypes.cpp | 124 ++--- .../InterpreterOpcodesEntityAccess.cpp | 5 +- .../InterpreterOpcodesEntityControl.cpp | 16 +- .../InterpreterOpcodesListManipulation.cpp | 8 +- .../InterpreterOpcodesTransformations.cpp | 2 +- src/Amalgam/out.txt | 403 +++++++++++---- src/Amalgam/string/StringInternPool.h | 481 +++++++----------- 29 files changed, 948 insertions(+), 845 deletions(-) diff --git a/src/Amalgam/AmalgamMain.cpp b/src/Amalgam/AmalgamMain.cpp index 11975b71..d2b484dc 100644 --- a/src/Amalgam/AmalgamMain.cpp +++ b/src/Amalgam/AmalgamMain.cpp @@ -328,7 +328,7 @@ PLATFORM_MAIN_CONSOLE if(num_strings_used > 0) { std::cerr << "ERROR: Num strings still in use: " << num_strings_used << std::endl; - std::vector> in_use = string_intern_pool.GetNonStaticStringsInUse(); + std::vector> in_use = string_intern_pool.GetDynamicStringsInUse(); for(auto &[s, count] : in_use) std::cerr << '"' << s << "\":" << count << std::endl; diff --git a/src/Amalgam/AssetManager.cpp b/src/Amalgam/AssetManager.cpp index 552d4a01..35ab1669 100644 --- a/src/Amalgam/AssetManager.cpp +++ b/src/Amalgam/AssetManager.cpp @@ -166,7 +166,7 @@ Entity *AssetManager::LoadEntityFromResourcePath(std::string &resource_path, std new_entity->SetRoot(code, true); EvaluableNodeReference args = EvaluableNodeReference(new_entity->evaluableNodeManager.AllocNode(ENT_ASSOC), true); - args->SetMappedChildNode(ENBISI_create_new_entity, new_entity->evaluableNodeManager.AllocNode(ENT_FALSE)); + args->SetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI_create_new_entity), new_entity->evaluableNodeManager.AllocNode(ENT_FALSE)); auto call_stack = Interpreter::ConvertArgsToCallStack(args, new_entity->evaluableNodeManager); new_entity->Execute(StringInternPool::NOT_A_STRING_ID, call_stack, false, calling_interpreter); @@ -185,14 +185,14 @@ Entity *AssetManager::LoadEntityFromResourcePath(std::string &resource_path, std { if(EvaluableNode::IsAssociativeArray(metadata)) { - EvaluableNode **seed = metadata->GetMappedChildNode(ENBISI_rand_seed); + EvaluableNode **seed = metadata->GetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI_rand_seed)); if(seed != nullptr) { default_random_seed = EvaluableNode::ToStringPreservingOpcodeType(*seed); new_entity->SetRandomState(default_random_seed, true); } - EvaluableNode **version = metadata->GetMappedChildNode(ENBISI_version); + EvaluableNode **version = metadata->GetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI_version)); if(version != nullptr) { auto [tostr_success, version_str] = EvaluableNode::ToString(*version); diff --git a/src/Amalgam/AssetManager.h b/src/Amalgam/AssetManager.h index 23a43ab4..63a387ff 100644 --- a/src/Amalgam/AssetManager.h +++ b/src/Amalgam/AssetManager.h @@ -110,8 +110,8 @@ class AssetManager EvaluableNode en_assoc(ENT_ASSOC); EvaluableNode en_rand_seed(ENT_STRING, entity->GetRandomState()); EvaluableNode en_version(ENT_STRING, AMALGAM_VERSION_STRING); - en_assoc.SetMappedChildNode(ENBISI_rand_seed, &en_rand_seed); - en_assoc.SetMappedChildNode(ENBISI_version, &en_version); + en_assoc.SetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI_rand_seed), &en_rand_seed); + en_assoc.SetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI_version), &en_version); std::string metadata_extension = FILE_EXTENSION_AMLG_METADATA; //don't reescape the path here, since it has already been done diff --git a/src/Amalgam/Opcodes.cpp b/src/Amalgam/Opcodes.cpp index c8462f4d..2ade350c 100644 --- a/src/Amalgam/Opcodes.cpp +++ b/src/Amalgam/Opcodes.cpp @@ -4,291 +4,302 @@ StringInternPool string_intern_pool; -void StringInternPool::InitializeStaticStrings() +static inline void EmplaceStaticString(EvaluableNodeBuiltInStringId bisid, const char *str) { - numStaticStrings = ENBISI_FIRST_DYNAMIC_STRING; - stringToID.reserve(numStaticStrings); - idToStringAndRefCount.resize(numStaticStrings); + auto sid = string_intern_pool.CreateStringReference(str); + string_intern_pool.staticStringsIndexToStringID[bisid] = sid; + string_intern_pool.staticStringIDToIndex.emplace(sid, bisid); +} - EmplaceStaticString(ENBISI_NOT_A_STRING, "(null)"); - EmplaceStaticString(ENBISI_EMPTY_STRING, ""); +inline void EmplaceNodeTypeString(EvaluableNodeType t, const char *str) +{ + EmplaceStaticString(static_cast(t + NUM_ENBISI_SPECIAL_STRING_IDS), str); +} + +void StringInternPool::InitializeStaticStrings() +{ + stringToID.reserve(ENBISI_FIRST_DYNAMIC_STRING); + staticStringsIndexToStringID.resize(ENBISI_FIRST_DYNAMIC_STRING); + staticStringIDToIndex.reserve(ENBISI_FIRST_DYNAMIC_STRING); + string_intern_pool.staticStringsIndexToStringID[ENBISI_EMPTY_STRING] = string_intern_pool.emptyStringId; + string_intern_pool.staticStringIDToIndex.emplace(string_intern_pool.emptyStringId, ENBISI_EMPTY_STRING); //opcodes //built-in / system specific - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SYSTEM), "system"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_DEFAULTS), "get_defaults"); + EmplaceNodeTypeString(ENT_SYSTEM, "system"); + EmplaceNodeTypeString(ENT_GET_DEFAULTS, "get_defaults"); //parsing - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_PARSE), "parse"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_UNPARSE), "unparse"); + EmplaceNodeTypeString(ENT_PARSE, "parse"); + EmplaceNodeTypeString(ENT_UNPARSE, "unparse"); //core control - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_IF), "if"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SEQUENCE), "seq"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_PARALLEL), "parallel"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_LAMBDA), "lambda"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CONCLUDE), "conclude"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_RETURN), "return"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CALL), "call"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CALL_SANDBOXED), "call_sandboxed"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_WHILE), "while"); + EmplaceNodeTypeString(ENT_IF, "if"); + EmplaceNodeTypeString(ENT_SEQUENCE, "seq"); + EmplaceNodeTypeString(ENT_PARALLEL, "parallel"); + EmplaceNodeTypeString(ENT_LAMBDA, "lambda"); + EmplaceNodeTypeString(ENT_CONCLUDE, "conclude"); + EmplaceNodeTypeString(ENT_RETURN, "return"); + EmplaceNodeTypeString(ENT_CALL, "call"); + EmplaceNodeTypeString(ENT_CALL_SANDBOXED, "call_sandboxed"); + EmplaceNodeTypeString(ENT_WHILE, "while"); //definitions - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_LET), "let"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_DECLARE), "declare"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ASSIGN), "assign"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ACCUM), "accum"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_RETRIEVE), "retrieve"); + EmplaceNodeTypeString(ENT_LET, "let"); + EmplaceNodeTypeString(ENT_DECLARE, "declare"); + EmplaceNodeTypeString(ENT_ASSIGN, "assign"); + EmplaceNodeTypeString(ENT_ACCUM, "accum"); + EmplaceNodeTypeString(ENT_RETRIEVE, "retrieve"); //retrieval - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET), "get"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SET), "set"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_REPLACE), "replace"); + EmplaceNodeTypeString(ENT_GET, "get"); + EmplaceNodeTypeString(ENT_SET, "set"); + EmplaceNodeTypeString(ENT_REPLACE, "replace"); //stack and node manipulation - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_TARGET), "target"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CURRENT_INDEX), "current_index"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CURRENT_VALUE), "current_value"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_PREVIOUS_RESULT), "previous_result"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_OPCODE_STACK), "opcode_stack"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_STACK), "stack"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ARGS), "args"); + EmplaceNodeTypeString(ENT_TARGET, "target"); + EmplaceNodeTypeString(ENT_CURRENT_INDEX, "current_index"); + EmplaceNodeTypeString(ENT_CURRENT_VALUE, "current_value"); + EmplaceNodeTypeString(ENT_PREVIOUS_RESULT, "previous_result"); + EmplaceNodeTypeString(ENT_OPCODE_STACK, "opcode_stack"); + EmplaceNodeTypeString(ENT_STACK, "stack"); + EmplaceNodeTypeString(ENT_ARGS, "args"); //simulation and operations - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_RAND), "rand"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_WEIGHTED_RAND), "weighted_rand"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_RAND_SEED), "get_rand_seed"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SET_RAND_SEED), "set_rand_seed"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SYSTEM_TIME), "system_time"); + EmplaceNodeTypeString(ENT_RAND, "rand"); + EmplaceNodeTypeString(ENT_WEIGHTED_RAND, "weighted_rand"); + EmplaceNodeTypeString(ENT_GET_RAND_SEED, "get_rand_seed"); + EmplaceNodeTypeString(ENT_SET_RAND_SEED, "set_rand_seed"); + EmplaceNodeTypeString(ENT_SYSTEM_TIME, "system_time"); //base math - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ADD), "+"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SUBTRACT), "-"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_MULTIPLY), "*"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_DIVIDE), "/"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_MODULUS), "mod"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_DIGITS), "get_digits"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SET_DIGITS), "set_digits"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_FLOOR), "floor"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CEILING), "ceil"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ROUND), "round"); + EmplaceNodeTypeString(ENT_ADD, "+"); + EmplaceNodeTypeString(ENT_SUBTRACT, "-"); + EmplaceNodeTypeString(ENT_MULTIPLY, "*"); + EmplaceNodeTypeString(ENT_DIVIDE, "/"); + EmplaceNodeTypeString(ENT_MODULUS, "mod"); + EmplaceNodeTypeString(ENT_GET_DIGITS, "get_digits"); + EmplaceNodeTypeString(ENT_SET_DIGITS, "set_digits"); + EmplaceNodeTypeString(ENT_FLOOR, "floor"); + EmplaceNodeTypeString(ENT_CEILING, "ceil"); + EmplaceNodeTypeString(ENT_ROUND, "round"); //extended math - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_EXPONENT), "exp"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_LOG), "log"); - - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SIN), "sin"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ASIN), "asin"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_COS), "cos"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ACOS), "acos"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_TAN), "tan"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ATAN), "atan"); - - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SINH), "sinh"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ASINH), "asinh"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_COSH), "cosh"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ACOSH), "acosh"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_TANH), "tanh"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ATANH), "atanh"); - - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ERF), "erf"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_TGAMMA), "tgamma"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_LGAMMA), "lgamma"); - - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SQRT), "sqrt"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_POW), "pow"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ABS), "abs"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_MAX), "max"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_MIN), "min"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GENERALIZED_DISTANCE), "generalized_distance"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_DOT_PRODUCT), "dot_product"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ENTROPY), "entropy"); + EmplaceNodeTypeString(ENT_EXPONENT, "exp"); + EmplaceNodeTypeString(ENT_LOG, "log"); + + EmplaceNodeTypeString(ENT_SIN, "sin"); + EmplaceNodeTypeString(ENT_ASIN, "asin"); + EmplaceNodeTypeString(ENT_COS, "cos"); + EmplaceNodeTypeString(ENT_ACOS, "acos"); + EmplaceNodeTypeString(ENT_TAN, "tan"); + EmplaceNodeTypeString(ENT_ATAN, "atan"); + + EmplaceNodeTypeString(ENT_SINH, "sinh"); + EmplaceNodeTypeString(ENT_ASINH, "asinh"); + EmplaceNodeTypeString(ENT_COSH, "cosh"); + EmplaceNodeTypeString(ENT_ACOSH, "acosh"); + EmplaceNodeTypeString(ENT_TANH, "tanh"); + EmplaceNodeTypeString(ENT_ATANH, "atanh"); + + EmplaceNodeTypeString(ENT_ERF, "erf"); + EmplaceNodeTypeString(ENT_TGAMMA, "tgamma"); + EmplaceNodeTypeString(ENT_LGAMMA, "lgamma"); + + EmplaceNodeTypeString(ENT_SQRT, "sqrt"); + EmplaceNodeTypeString(ENT_POW, "pow"); + EmplaceNodeTypeString(ENT_ABS, "abs"); + EmplaceNodeTypeString(ENT_MAX, "max"); + EmplaceNodeTypeString(ENT_MIN, "min"); + EmplaceNodeTypeString(ENT_GENERALIZED_DISTANCE, "generalized_distance"); + EmplaceNodeTypeString(ENT_DOT_PRODUCT, "dot_product"); + EmplaceNodeTypeString(ENT_ENTROPY, "entropy"); //list manipulation - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_FIRST), "first"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_TAIL), "tail"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_LAST), "last"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_TRUNC), "trunc"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_APPEND), "append"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SIZE), "size"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_RANGE), "range"); + EmplaceNodeTypeString(ENT_FIRST, "first"); + EmplaceNodeTypeString(ENT_TAIL, "tail"); + EmplaceNodeTypeString(ENT_LAST, "last"); + EmplaceNodeTypeString(ENT_TRUNC, "trunc"); + EmplaceNodeTypeString(ENT_APPEND, "append"); + EmplaceNodeTypeString(ENT_SIZE, "size"); + EmplaceNodeTypeString(ENT_RANGE, "range"); //transformation - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_REWRITE), "rewrite"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_MAP), "map"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_FILTER), "filter"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_WEAVE), "weave"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_REDUCE), "reduce"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_APPLY), "apply"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_REVERSE), "reverse"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SORT), "sort"); + EmplaceNodeTypeString(ENT_REWRITE, "rewrite"); + EmplaceNodeTypeString(ENT_MAP, "map"); + EmplaceNodeTypeString(ENT_FILTER, "filter"); + EmplaceNodeTypeString(ENT_WEAVE, "weave"); + EmplaceNodeTypeString(ENT_REDUCE, "reduce"); + EmplaceNodeTypeString(ENT_APPLY, "apply"); + EmplaceNodeTypeString(ENT_REVERSE, "reverse"); + EmplaceNodeTypeString(ENT_SORT, "sort"); //associative list manipulation - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_INDICES), "indices"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_VALUES), "values"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CONTAINS_INDEX), "contains_index"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CONTAINS_VALUE), "contains_value"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_REMOVE), "remove"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_KEEP), "keep"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ASSOCIATE), "associate"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ZIP), "zip"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_UNZIP), "unzip"); + EmplaceNodeTypeString(ENT_INDICES, "indices"); + EmplaceNodeTypeString(ENT_VALUES, "values"); + EmplaceNodeTypeString(ENT_CONTAINS_INDEX, "contains_index"); + EmplaceNodeTypeString(ENT_CONTAINS_VALUE, "contains_value"); + EmplaceNodeTypeString(ENT_REMOVE, "remove"); + EmplaceNodeTypeString(ENT_KEEP, "keep"); + EmplaceNodeTypeString(ENT_ASSOCIATE, "associate"); + EmplaceNodeTypeString(ENT_ZIP, "zip"); + EmplaceNodeTypeString(ENT_UNZIP, "unzip"); //logic - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_AND), "and"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_OR), "or"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_XOR), "xor"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_NOT), "not"); + EmplaceNodeTypeString(ENT_AND, "and"); + EmplaceNodeTypeString(ENT_OR, "or"); + EmplaceNodeTypeString(ENT_XOR, "xor"); + EmplaceNodeTypeString(ENT_NOT, "not"); //equivalence - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_EQUAL), "="); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_NEQUAL), "!="); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_LESS), "<"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_LEQUAL), "<="); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GREATER), ">"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GEQUAL), ">="); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_TYPE_EQUALS), "~"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_TYPE_NEQUALS), "!~"); + EmplaceNodeTypeString(ENT_EQUAL, "="); + EmplaceNodeTypeString(ENT_NEQUAL, "!="); + EmplaceNodeTypeString(ENT_LESS, "<"); + EmplaceNodeTypeString(ENT_LEQUAL, "<="); + EmplaceNodeTypeString(ENT_GREATER, ">"); + EmplaceNodeTypeString(ENT_GEQUAL, ">="); + EmplaceNodeTypeString(ENT_TYPE_EQUALS, "~"); + EmplaceNodeTypeString(ENT_TYPE_NEQUALS, "!~"); //built-in constants and variables - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_TRUE), "true"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_FALSE), "false"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_NULL), "null"); + EmplaceNodeTypeString(ENT_TRUE, "true"); + EmplaceNodeTypeString(ENT_FALSE, "false"); + EmplaceNodeTypeString(ENT_NULL, "null"); //data types - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_LIST), "list"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ASSOC), "assoc"); + EmplaceNodeTypeString(ENT_LIST, "list"); + EmplaceNodeTypeString(ENT_ASSOC, "assoc"); //immediates - no associated keywords - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_NUMBER), "number"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_STRING), "string"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SYMBOL), "symbol"); + EmplaceNodeTypeString(ENT_NUMBER, "number"); + EmplaceNodeTypeString(ENT_STRING, "string"); + EmplaceNodeTypeString(ENT_SYMBOL, "symbol"); //node types - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_TYPE), "get_type"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_TYPE_STRING), "get_type_string"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SET_TYPE), "set_type"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_FORMAT), "format"); + EmplaceNodeTypeString(ENT_GET_TYPE, "get_type"); + EmplaceNodeTypeString(ENT_GET_TYPE_STRING, "get_type_string"); + EmplaceNodeTypeString(ENT_SET_TYPE, "set_type"); + EmplaceNodeTypeString(ENT_FORMAT, "format"); //labels and comments - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_LABELS), "get_labels"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_ALL_LABELS), "get_all_labels"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SET_LABELS), "set_labels"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ZIP_LABELS), "zip_labels"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_COMMENTS), "get_comments"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SET_COMMENTS), "set_comments"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_CONCURRENCY), "get_concurrency"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SET_CONCURRENCY), "set_concurrency"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_VALUE), "get_value"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SET_VALUE), "set_value"); + EmplaceNodeTypeString(ENT_GET_LABELS, "get_labels"); + EmplaceNodeTypeString(ENT_GET_ALL_LABELS, "get_all_labels"); + EmplaceNodeTypeString(ENT_SET_LABELS, "set_labels"); + EmplaceNodeTypeString(ENT_ZIP_LABELS, "zip_labels"); + EmplaceNodeTypeString(ENT_GET_COMMENTS, "get_comments"); + EmplaceNodeTypeString(ENT_SET_COMMENTS, "set_comments"); + EmplaceNodeTypeString(ENT_GET_CONCURRENCY, "get_concurrency"); + EmplaceNodeTypeString(ENT_SET_CONCURRENCY, "set_concurrency"); + EmplaceNodeTypeString(ENT_GET_VALUE, "get_value"); + EmplaceNodeTypeString(ENT_SET_VALUE, "set_value"); //string - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_EXPLODE), "explode"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SPLIT), "split"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SUBSTR), "substr"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CONCAT), "concat"); + EmplaceNodeTypeString(ENT_EXPLODE, "explode"); + EmplaceNodeTypeString(ENT_SPLIT, "split"); + EmplaceNodeTypeString(ENT_SUBSTR, "substr"); + EmplaceNodeTypeString(ENT_CONCAT, "concat"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CRYPTO_SIGN), "crypto_sign"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CRYPTO_SIGN_VERIFY), "crypto_sign_verify"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ENCRYPT), "encrypt"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_DECRYPT), "decrypt"); + EmplaceNodeTypeString(ENT_CRYPTO_SIGN, "crypto_sign"); + EmplaceNodeTypeString(ENT_CRYPTO_SIGN_VERIFY, "crypto_sign_verify"); + EmplaceNodeTypeString(ENT_ENCRYPT, "encrypt"); + EmplaceNodeTypeString(ENT_DECRYPT, "decrypt"); //I/O - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_PRINT), "print"); + EmplaceNodeTypeString(ENT_PRINT, "print"); //tree merging - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_TOTAL_SIZE), "total_size"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_COMMONALITY), "commonality"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_EDIT_DISTANCE), "edit_distance"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_MUTATE), "mutate"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_INTERSECT), "intersect"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_UNION), "union"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_DIFFERENCE), "difference"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_MIX), "mix"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_MIX_LABELS), "mix_labels"); + EmplaceNodeTypeString(ENT_TOTAL_SIZE, "total_size"); + EmplaceNodeTypeString(ENT_COMMONALITY, "commonality"); + EmplaceNodeTypeString(ENT_EDIT_DISTANCE, "edit_distance"); + EmplaceNodeTypeString(ENT_MUTATE, "mutate"); + EmplaceNodeTypeString(ENT_INTERSECT, "intersect"); + EmplaceNodeTypeString(ENT_UNION, "union"); + EmplaceNodeTypeString(ENT_DIFFERENCE, "difference"); + EmplaceNodeTypeString(ENT_MIX, "mix"); + EmplaceNodeTypeString(ENT_MIX_LABELS, "mix_labels"); //entity merging - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_TOTAL_ENTITY_SIZE), "total_entity_size"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_FLATTEN_ENTITY), "flatten_entity"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_COMMONALITY_ENTITIES), "commonality_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_EDIT_DISTANCE_ENTITIES), "edit_distance_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_MUTATE_ENTITY), "mutate_entity"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_INTERSECT_ENTITIES), "intersect_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_UNION_ENTITIES), "union_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_DIFFERENCE_ENTITIES), "difference_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_MIX_ENTITIES), "mix_entities"); + EmplaceNodeTypeString(ENT_TOTAL_ENTITY_SIZE, "total_entity_size"); + EmplaceNodeTypeString(ENT_FLATTEN_ENTITY, "flatten_entity"); + EmplaceNodeTypeString(ENT_COMMONALITY_ENTITIES, "commonality_entities"); + EmplaceNodeTypeString(ENT_EDIT_DISTANCE_ENTITIES, "edit_distance_entities"); + EmplaceNodeTypeString(ENT_MUTATE_ENTITY, "mutate_entity"); + EmplaceNodeTypeString(ENT_INTERSECT_ENTITIES, "intersect_entities"); + EmplaceNodeTypeString(ENT_UNION_ENTITIES, "union_entities"); + EmplaceNodeTypeString(ENT_DIFFERENCE_ENTITIES, "difference_entities"); + EmplaceNodeTypeString(ENT_MIX_ENTITIES, "mix_entities"); //entity details - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_ENTITY_COMMENTS), "get_entity_comments"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_RETRIEVE_ENTITY_ROOT), "retrieve_entity_root"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ASSIGN_ENTITY_ROOTS), "assign_entity_roots"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ACCUM_ENTITY_ROOTS), "accum_entity_roots"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_ENTITY_RAND_SEED), "get_entity_rand_seed"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SET_ENTITY_RAND_SEED), "set_entity_rand_seed"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_GET_ENTITY_ROOT_PERMISSION), "get_entity_root_permission"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_SET_ENTITY_ROOT_PERMISSION), "set_entity_root_permission"); + EmplaceNodeTypeString(ENT_GET_ENTITY_COMMENTS, "get_entity_comments"); + EmplaceNodeTypeString(ENT_RETRIEVE_ENTITY_ROOT, "retrieve_entity_root"); + EmplaceNodeTypeString(ENT_ASSIGN_ENTITY_ROOTS, "assign_entity_roots"); + EmplaceNodeTypeString(ENT_ACCUM_ENTITY_ROOTS, "accum_entity_roots"); + EmplaceNodeTypeString(ENT_GET_ENTITY_RAND_SEED, "get_entity_rand_seed"); + EmplaceNodeTypeString(ENT_SET_ENTITY_RAND_SEED, "set_entity_rand_seed"); + EmplaceNodeTypeString(ENT_GET_ENTITY_ROOT_PERMISSION, "get_entity_root_permission"); + EmplaceNodeTypeString(ENT_SET_ENTITY_ROOT_PERMISSION, "set_entity_root_permission"); //entity base actions - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CREATE_ENTITIES), "create_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CLONE_ENTITIES), "clone_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_MOVE_ENTITIES), "move_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_DESTROY_ENTITIES), "destroy_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_LOAD), "load"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_LOAD_ENTITY), "load_entity"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_LOAD_PERSISTENT_ENTITY), "load_persistent_entity"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_STORE), "store"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_STORE_ENTITY), "store_entity"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CONTAINS_ENTITY), "contains_entity"); + EmplaceNodeTypeString(ENT_CREATE_ENTITIES, "create_entities"); + EmplaceNodeTypeString(ENT_CLONE_ENTITIES, "clone_entities"); + EmplaceNodeTypeString(ENT_MOVE_ENTITIES, "move_entities"); + EmplaceNodeTypeString(ENT_DESTROY_ENTITIES, "destroy_entities"); + EmplaceNodeTypeString(ENT_LOAD, "load"); + EmplaceNodeTypeString(ENT_LOAD_ENTITY, "load_entity"); + EmplaceNodeTypeString(ENT_LOAD_PERSISTENT_ENTITY, "load_persistent_entity"); + EmplaceNodeTypeString(ENT_STORE, "store"); + EmplaceNodeTypeString(ENT_STORE_ENTITY, "store_entity"); + EmplaceNodeTypeString(ENT_CONTAINS_ENTITY, "contains_entity"); //entity query - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CONTAINED_ENTITIES), "contained_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_COMPUTE_ON_CONTAINED_ENTITIES), "compute_on_contained_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_COUNT), "query_count"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_SELECT), "query_select"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_SAMPLE), "query_sample"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_WEIGHTED_SAMPLE), "query_weighted_sample"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_IN_ENTITY_LIST), "query_in_entity_list"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_NOT_IN_ENTITY_LIST), "query_not_in_entity_list"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_EXISTS), "query_exists"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_NOT_EXISTS), "query_not_exists"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_EQUALS), "query_equals"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_NOT_EQUALS), "query_not_equals"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_BETWEEN), "query_between"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_NOT_BETWEEN), "query_not_between"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_AMONG), "query_among"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_NOT_AMONG), "query_not_among"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_MAX), "query_max"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_MIN), "query_min"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_SUM), "query_sum"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_MODE), "query_mode"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_QUANTILE), "query_quantile"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_GENERALIZED_MEAN), "query_generalized_mean"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_MIN_DIFFERENCE), "query_min_difference"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_MAX_DIFFERENCE), "query_max_difference"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_VALUE_MASSES), "query_value_masses"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_LESS_OR_EQUAL_TO), "query_less_or_equal_to"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_GREATER_OR_EQUAL_TO), "query_greater_or_equal_to"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_WITHIN_GENERALIZED_DISTANCE), "query_within_generalized_distance"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_QUERY_NEAREST_GENERALIZED_DISTANCE), "query_nearest_generalized_distance"); + EmplaceNodeTypeString(ENT_CONTAINED_ENTITIES, "contained_entities"); + EmplaceNodeTypeString(ENT_COMPUTE_ON_CONTAINED_ENTITIES, "compute_on_contained_entities"); + EmplaceNodeTypeString(ENT_QUERY_COUNT, "query_count"); + EmplaceNodeTypeString(ENT_QUERY_SELECT, "query_select"); + EmplaceNodeTypeString(ENT_QUERY_SAMPLE, "query_sample"); + EmplaceNodeTypeString(ENT_QUERY_WEIGHTED_SAMPLE, "query_weighted_sample"); + EmplaceNodeTypeString(ENT_QUERY_IN_ENTITY_LIST, "query_in_entity_list"); + EmplaceNodeTypeString(ENT_QUERY_NOT_IN_ENTITY_LIST, "query_not_in_entity_list"); + EmplaceNodeTypeString(ENT_QUERY_EXISTS, "query_exists"); + EmplaceNodeTypeString(ENT_QUERY_NOT_EXISTS, "query_not_exists"); + EmplaceNodeTypeString(ENT_QUERY_EQUALS, "query_equals"); + EmplaceNodeTypeString(ENT_QUERY_NOT_EQUALS, "query_not_equals"); + EmplaceNodeTypeString(ENT_QUERY_BETWEEN, "query_between"); + EmplaceNodeTypeString(ENT_QUERY_NOT_BETWEEN, "query_not_between"); + EmplaceNodeTypeString(ENT_QUERY_AMONG, "query_among"); + EmplaceNodeTypeString(ENT_QUERY_NOT_AMONG, "query_not_among"); + EmplaceNodeTypeString(ENT_QUERY_MAX, "query_max"); + EmplaceNodeTypeString(ENT_QUERY_MIN, "query_min"); + EmplaceNodeTypeString(ENT_QUERY_SUM, "query_sum"); + EmplaceNodeTypeString(ENT_QUERY_MODE, "query_mode"); + EmplaceNodeTypeString(ENT_QUERY_QUANTILE, "query_quantile"); + EmplaceNodeTypeString(ENT_QUERY_GENERALIZED_MEAN, "query_generalized_mean"); + EmplaceNodeTypeString(ENT_QUERY_MIN_DIFFERENCE, "query_min_difference"); + EmplaceNodeTypeString(ENT_QUERY_MAX_DIFFERENCE, "query_max_difference"); + EmplaceNodeTypeString(ENT_QUERY_VALUE_MASSES, "query_value_masses"); + EmplaceNodeTypeString(ENT_QUERY_LESS_OR_EQUAL_TO, "query_less_or_equal_to"); + EmplaceNodeTypeString(ENT_QUERY_GREATER_OR_EQUAL_TO, "query_greater_or_equal_to"); + EmplaceNodeTypeString(ENT_QUERY_WITHIN_GENERALIZED_DISTANCE, "query_within_generalized_distance"); + EmplaceNodeTypeString(ENT_QUERY_NEAREST_GENERALIZED_DISTANCE, "query_nearest_generalized_distance"); //compute queries - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_COMPUTE_ENTITY_CONVICTIONS), "compute_entity_convictions"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_COMPUTE_ENTITY_GROUP_KL_DIVERGENCE), "compute_entity_group_kl_divergence"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_COMPUTE_ENTITY_DISTANCE_CONTRIBUTIONS), "compute_entity_distance_contributions"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_COMPUTE_ENTITY_KL_DIVERGENCES), "compute_entity_kl_divergences"); + EmplaceNodeTypeString(ENT_COMPUTE_ENTITY_CONVICTIONS, "compute_entity_convictions"); + EmplaceNodeTypeString(ENT_COMPUTE_ENTITY_GROUP_KL_DIVERGENCE, "compute_entity_group_kl_divergence"); + EmplaceNodeTypeString(ENT_COMPUTE_ENTITY_DISTANCE_CONTRIBUTIONS, "compute_entity_distance_contributions"); + EmplaceNodeTypeString(ENT_COMPUTE_ENTITY_KL_DIVERGENCES, "compute_entity_kl_divergences"); //entity access - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CONTAINS_LABEL), "contains_label"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ASSIGN_TO_ENTITIES), "assign_to_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_DIRECT_ASSIGN_TO_ENTITIES), "direct_assign_to_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_ACCUM_TO_ENTITIES), "accum_to_entities"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_RETRIEVE_FROM_ENTITY), "retrieve_from_entity"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_DIRECT_RETRIEVE_FROM_ENTITY), "direct_retrieve_from_entity"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CALL_ENTITY), "call_entity"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CALL_ENTITY_GET_CHANGES), "call_entity_get_changes"); - EmplaceStaticString(GetStringIdFromNodeTypeFromString(ENT_CALL_CONTAINER), "call_container"); + EmplaceNodeTypeString(ENT_CONTAINS_LABEL, "contains_label"); + EmplaceNodeTypeString(ENT_ASSIGN_TO_ENTITIES, "assign_to_entities"); + EmplaceNodeTypeString(ENT_DIRECT_ASSIGN_TO_ENTITIES, "direct_assign_to_entities"); + EmplaceNodeTypeString(ENT_ACCUM_TO_ENTITIES, "accum_to_entities"); + EmplaceNodeTypeString(ENT_RETRIEVE_FROM_ENTITY, "retrieve_from_entity"); + EmplaceNodeTypeString(ENT_DIRECT_RETRIEVE_FROM_ENTITY, "direct_retrieve_from_entity"); + EmplaceNodeTypeString(ENT_CALL_ENTITY, "call_entity"); + EmplaceNodeTypeString(ENT_CALL_ENTITY_GET_CHANGES, "call_entity_get_changes"); + EmplaceNodeTypeString(ENT_CALL_CONTAINER, "call_container"); //end opcodes diff --git a/src/Amalgam/Opcodes.h b/src/Amalgam/Opcodes.h index 67b49c03..23de6117 100644 --- a/src/Amalgam/Opcodes.h +++ b/src/Amalgam/Opcodes.h @@ -612,22 +612,44 @@ enum EvaluableNodeBuiltInStringId ENBISI_FIRST_DYNAMIC_STRING }; +//returns the string id representing EvaluableNodeBuiltInStringId t +inline StringInternPool::StringID GetStringIdFromBuiltInStringId(EvaluableNodeBuiltInStringId t) +{ + if(t >= ENBISI_FIRST_DYNAMIC_STRING) + return string_intern_pool.staticStringsIndexToStringID[ENBISI_NOT_A_STRING]; + return string_intern_pool.staticStringsIndexToStringID[t]; +} + +//returns the EvaluableNodeType for a given string, ENT_NOT_A_BUILT_IN_TYPE if it isn't one +inline EvaluableNodeBuiltInStringId GetBuiltInStringIdFromStringId(StringInternPool::StringID sid) +{ + auto found = string_intern_pool.staticStringIDToIndex.find(sid); + if(found == end(string_intern_pool.staticStringIDToIndex)) + return ENBISI_NOT_A_STRING; + + EvaluableNodeBuiltInStringId bisid = static_cast(found->second); + if(bisid >= ENBISI_FIRST_DYNAMIC_STRING) + return ENBISI_NOT_A_STRING; + + return bisid; +} //returns the string id representing EvaluableNodeType t -constexpr StringInternPool::StringID GetStringIdFromNodeTypeFromString(EvaluableNodeType t) +inline StringInternPool::StringID GetStringIdFromNodeType(EvaluableNodeType t) { if(t >= NUM_VALID_ENT_OPCODES) - return ENT_NOT_A_BUILT_IN_TYPE; - return static_cast(t + NUM_ENBISI_SPECIAL_STRING_IDS); + return string_intern_pool.staticStringsIndexToStringID[ENT_NOT_A_BUILT_IN_TYPE]; + return string_intern_pool.staticStringsIndexToStringID[t + NUM_ENBISI_SPECIAL_STRING_IDS]; } -//like GetEvaluableNodeTypeFromString but uses a string id -constexpr EvaluableNodeType GetEvaluableNodeTypeFromStringId(StringInternPool::StringID sid) +//returns the EvaluableNodeType for a given string, ENT_NOT_A_BUILT_IN_TYPE if it isn't one +inline EvaluableNodeType GetEvaluableNodeTypeFromStringId(StringInternPool::StringID sid) { - if(sid <= ENBISI_EMPTY_STRING) + auto found = string_intern_pool.staticStringIDToIndex.find(sid); + if(found == end(string_intern_pool.staticStringIDToIndex)) return ENT_NOT_A_BUILT_IN_TYPE; - size_t type_index = sid - NUM_ENBISI_SPECIAL_STRING_IDS; + size_t type_index = found->second - NUM_ENBISI_SPECIAL_STRING_IDS; if(type_index >= NUM_VALID_ENT_OPCODES) return ENT_NOT_A_BUILT_IN_TYPE; @@ -647,14 +669,14 @@ inline std::string GetStringFromEvaluableNodeType(EvaluableNodeType t, bool get_ return ""; } - return string_intern_pool.GetStringFromID(GetStringIdFromNodeTypeFromString(t)); + return string_intern_pool.GetStringFromID(GetStringIdFromNodeType(t)); } //returns the enumerated type for the string inline EvaluableNodeType GetEvaluableNodeTypeFromString(const std::string &s) { auto sid = string_intern_pool.GetIDFromString(s); - if(sid == string_intern_pool.NOT_A_STRING_ID || sid == string_intern_pool.EMPTY_STRING_ID) + if(sid == string_intern_pool.NOT_A_STRING_ID || sid == string_intern_pool.emptyStringId) return ENT_NOT_A_BUILT_IN_TYPE; return GetEvaluableNodeTypeFromStringId(sid); diff --git a/src/Amalgam/SeparableBoxFilterDataStore.h b/src/Amalgam/SeparableBoxFilterDataStore.h index be2d778e..3d63ab0a 100644 --- a/src/Amalgam/SeparableBoxFilterDataStore.h +++ b/src/Amalgam/SeparableBoxFilterDataStore.h @@ -834,7 +834,7 @@ class SeparableBoxFilterDataStore GetValue(entity_index, feature_attribs.featureIndex).stringID, ENIVT_STRING_ID, query_feature_index, high_accuracy); else - return r_dist_eval.ComputeDistanceTermNominal(string_intern_pool.EMPTY_STRING_ID, ENIVT_STRING_ID, + return r_dist_eval.ComputeDistanceTermNominal(string_intern_pool.emptyStringId, ENIVT_STRING_ID, query_feature_index, high_accuracy); } diff --git a/src/Amalgam/amlg_code/test.amlg b/src/Amalgam/amlg_code/test.amlg index 8ac9e7ac..4446b905 100644 --- a/src/Amalgam/amlg_code/test.amlg +++ b/src/Amalgam/amlg_code/test.amlg @@ -1,39 +1,4 @@ (seq - - (print (get - (list - {"a" 3} - ;@(get (get (target 0) 0) "a")) - @(get (target 2) [0 "a"]) - ;(get (target 0) [0 "a"]) - ) - 1) - "\n") - - - ;(create_entities "test" - ; (lambda - ; ##label_target - ; (list - ; {"a" 1} - ; @(get (get (target 2) 0) "a")) - ; ) - ; ) - ;) - - ;(print (flatten_entity "test")) - - ;(print - ; ;(get - ; (retrieve_from_entity "test" "label_target) - ; ;(list 0 "a") - ; ;) - ;"\n") - - ;(store_entity "testsave.amlg" "test") - - ;(call (flatten_entity "test") {new_entity "test2"}) - - ;(load_entity "testsave.amlg" "test2") - ;(print (flatten_entity "test2")) + (print (tail "abcdef" -10) "\n") +(print (tail "") "\n") ) \ No newline at end of file diff --git a/src/Amalgam/entity/Entity.h b/src/Amalgam/entity/Entity.h index e2733f93..f7c9c2e2 100644 --- a/src/Amalgam/entity/Entity.h +++ b/src/Amalgam/entity/Entity.h @@ -348,18 +348,12 @@ class Entity StringInternPool::StringID AddContainedEntity(Entity *t, std::string id_string, std::vector *write_listeners = nullptr); - inline void AddContainedEntityViaReference(Entity *t, StringInternRef &sir, std::vector *write_listeners = nullptr) + inline void AddContainedEntityViaReference(Entity *t, StringRef &sir, std::vector *write_listeners = nullptr) { StringInternPool::StringID new_sid = AddContainedEntity(t, static_cast(sir), write_listeners); sir.SetIDAndCreateReference(new_sid); } - inline void AddContainedEntityViaReference(Entity *t, StringInternWeakRef &siwr, std::vector *write_listeners = nullptr) - { - StringInternPool::StringID new_sid = AddContainedEntity(t, static_cast(siwr), write_listeners); - siwr.SetID(new_sid); - } - //Removes the specified id from being contained by this Entity /// write_listeners is optional, and if specified, will log the event void RemoveContainedEntity(StringInternPool::StringID id, std::vector *write_listeners = nullptr); diff --git a/src/Amalgam/entity/EntityManipulation.cpp b/src/Amalgam/entity/EntityManipulation.cpp index 250f9ca6..e0770a10 100644 --- a/src/Amalgam/entity/EntityManipulation.cpp +++ b/src/Amalgam/entity/EntityManipulation.cpp @@ -262,8 +262,8 @@ EvaluableNodeReference EntityManipulation::DifferenceEntities(Interpreter *inter EvaluableNode *df_assoc = enm->AllocNode(ENT_ASSOC); difference_function->AppendOrderedChildNode(df_assoc); - df_assoc->SetMappedChildNode(ENBISI__, nullptr); - df_assoc->SetMappedChildNode(ENBISI_new_entity, nullptr); + df_assoc->SetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI__), nullptr); + df_assoc->SetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI_new_entity), nullptr); //find entities that match up, and if no difference, then can shortcut the function std::vector top_entities_identical; @@ -272,8 +272,8 @@ EvaluableNodeReference EntityManipulation::DifferenceEntities(Interpreter *inter { EvaluableNode *clone_entity = enm->AllocNode(ENT_CLONE_ENTITIES); difference_function->AppendOrderedChildNode(clone_entity); - clone_entity->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI__)); - clone_entity->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI_new_entity)); + clone_entity->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI__))); + clone_entity->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI_new_entity))); delete root_merged; return EvaluableNodeReference(difference_function, true); } @@ -282,9 +282,11 @@ EvaluableNodeReference EntityManipulation::DifferenceEntities(Interpreter *inter // (assign "new_entity" (first (create_entities new_entity EvaluableNode *assign_new_entity = enm->AllocNode(ENT_ASSIGN); difference_function->AppendOrderedChildNode(assign_new_entity); - assign_new_entity->AppendOrderedChildNode(enm->AllocNode(ENT_STRING, ENBISI_new_entity)); + assign_new_entity->AppendOrderedChildNode(enm->AllocNode(ENT_STRING, + GetStringIdFromBuiltInStringId(ENBISI_new_entity))); EvaluableNode *create_root_entity = enm->AllocNode(ENT_CREATE_ENTITIES); - create_root_entity->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI_new_entity)); + create_root_entity->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, + GetStringIdFromBuiltInStringId(ENBISI_new_entity))); EvaluableNode *first_of_create_entity = enm->AllocNode(ENT_FIRST); first_of_create_entity->AppendOrderedChildNode(create_root_entity); assign_new_entity->AppendOrderedChildNode(first_of_create_entity); @@ -301,8 +303,8 @@ EvaluableNodeReference EntityManipulation::DifferenceEntities(Interpreter *inter EvaluableNode *edac_assoc = enm->AllocNode(ENT_ASSOC); entity_difference_apply_call->AppendOrderedChildNode(edac_assoc); EvaluableNode *get_entity_code = enm->AllocNode(ENT_RETRIEVE_ENTITY_ROOT); - edac_assoc->SetMappedChildNode(ENBISI__, get_entity_code); - get_entity_code->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI__)); + edac_assoc->SetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI__), get_entity_code); + get_entity_code->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI__))); //apply difference function for root entities // make sure to make a copy of each root so don't end up with mixed entity nodes @@ -322,12 +324,12 @@ EvaluableNodeReference EntityManipulation::DifferenceEntities(Interpreter *inter // ) EvaluableNode *src_id_list = GetTraversalIDPathFromAToB(enm, entity2, entity_to_create); EvaluableNode *src_append = enm->AllocNode(ENT_APPEND); - src_append->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI__)); + src_append->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI__))); src_append->AppendOrderedChildNode(src_id_list); EvaluableNode *dest_id_list = enm->DeepAllocCopy(src_id_list); EvaluableNode *dest_append = enm->AllocNode(ENT_APPEND); - dest_append->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI_new_entity)); + dest_append->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI_new_entity))); dest_append->AppendOrderedChildNode(dest_id_list); EvaluableNode *create_entity = enm->AllocNode(ENT_CREATE_ENTITIES); @@ -369,7 +371,7 @@ EvaluableNodeReference EntityManipulation::DifferenceEntities(Interpreter *inter call_diff->AppendOrderedChildNode(call_assoc); EvaluableNode *entity_code = enm->AllocNode(ENT_RETRIEVE_ENTITY_ROOT); - call_assoc->SetMappedChildNode(ENBISI__, entity_code); + call_assoc->SetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI__), entity_code); entity_code->AppendOrderedChildNode(src_append); } } @@ -387,12 +389,12 @@ EvaluableNodeReference EntityManipulation::DifferenceEntities(Interpreter *inter EvaluableNode *src_id_list = GetTraversalIDPathFromAToB(enm, entity2, entity_to_clone); EvaluableNode *src_append = enm->AllocNode(ENT_APPEND); - src_append->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI__)); + src_append->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI__))); src_append->AppendOrderedChildNode(src_id_list); EvaluableNode *dest_id_list = enm->DeepAllocCopy(src_id_list); EvaluableNode *dest_append = enm->AllocNode(ENT_APPEND); - dest_append->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI_new_entity)); + dest_append->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI_new_entity))); dest_append->AppendOrderedChildNode(dest_id_list); clone_entity->AppendOrderedChildNode(src_append); @@ -400,7 +402,7 @@ EvaluableNodeReference EntityManipulation::DifferenceEntities(Interpreter *inter } //add new_entity to return value of let statement to return the newly created id - difference_function->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI_new_entity)); + difference_function->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI_new_entity))); delete root_merged; @@ -630,7 +632,8 @@ void EntityManipulation::MergeContainedEntities(EntitiesMergeMethod *mm, Entity RecursivelyRenameAllEntityReferences(merged_entity, entities_renamed); } -Entity *EntityManipulation::MutateEntity(Interpreter *interpreter, Entity *entity, double mutation_rate, CompactHashMap *mutation_weights, CompactHashMap *operation_type) +Entity *EntityManipulation::MutateEntity(Interpreter *interpreter, Entity *entity, double mutation_rate, + CompactHashMap *mutation_weights, CompactHashMap *operation_type) { if(entity == nullptr) return nullptr; diff --git a/src/Amalgam/entity/EntityManipulation.h b/src/Amalgam/entity/EntityManipulation.h index 94191280..217e6c76 100644 --- a/src/Amalgam/entity/EntityManipulation.h +++ b/src/Amalgam/entity/EntityManipulation.h @@ -124,7 +124,8 @@ class EntityManipulation //computes the edit distance between the two entities static double EditDistance(Entity *entity1, Entity *entity2); - static Entity *MutateEntity(Interpreter *interpreter, Entity *entity, double mutation_rate, CompactHashMap *mutation_weights, CompactHashMap *operation_type); + static Entity *MutateEntity(Interpreter *interpreter, Entity *entity, double mutation_rate, + CompactHashMap *mutation_weights, CompactHashMap *operation_type); //flattens entity using enm to allocate code that can recreate it // all_contained_entities must be populated via Entity::GetAllDeeplyContainedEntityReadReferencesGroupedByDepth @@ -179,8 +180,8 @@ class EntityManipulation EvaluableNode *flatten_params = enm->AllocNode(ENT_ASSOC); declare_flatten->AppendOrderedChildNode(flatten_params); - flatten_params->SetMappedChildNode(ENBISI_new_entity, nullptr); - flatten_params->SetMappedChildNode(ENBISI_create_new_entity, enm->AllocNode(ENT_TRUE)); + flatten_params->SetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI_new_entity), nullptr); + flatten_params->SetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI_create_new_entity), enm->AllocNode(ENT_TRUE)); // (let (assoc _ (lambda *entity code*)) EvaluableNode *let_entity_code = enm->AllocNode(ENT_LET); @@ -189,7 +190,7 @@ class EntityManipulation let_entity_code->AppendOrderedChildNode(let_assoc); EvaluableNode *lambda_for_create_root = enm->AllocNode(ENT_LAMBDA); - let_assoc->SetMappedChildNode(ENBISI__, lambda_for_create_root); + let_assoc->SetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI__), lambda_for_create_root); EvaluableNodeReference root_copy = entity->GetRoot(enm, EvaluableNodeManager::ENMM_LABEL_ESCAPE_INCREMENT); lambda_for_create_root->AppendOrderedChildNode(root_copy); @@ -199,17 +200,17 @@ class EntityManipulation // (if create_new_entity EvaluableNode *if_create_new = enm->AllocNode(ENT_IF); let_entity_code->AppendOrderedChildNode(if_create_new); - if_create_new->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI_create_new_entity)); + if_create_new->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI_create_new_entity))); // (assign "new_entity" (first // (create_entities new_entity _) // )) EvaluableNode *assign_new_entity_from_create = enm->AllocNode(ENT_ASSIGN); if_create_new->AppendOrderedChildNode(assign_new_entity_from_create); - assign_new_entity_from_create->AppendOrderedChildNode(enm->AllocNode(ENT_STRING, ENBISI_new_entity)); + assign_new_entity_from_create->AppendOrderedChildNode(enm->AllocNode(ENT_STRING, GetStringIdFromBuiltInStringId(ENBISI_new_entity))); EvaluableNode *create_root_entity = enm->AllocNode(ENT_CREATE_ENTITIES); - create_root_entity->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI_new_entity)); - create_root_entity->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI__)); + create_root_entity->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI_new_entity))); + create_root_entity->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI__))); EvaluableNode *first_of_create_entity = enm->AllocNode(ENT_FIRST); first_of_create_entity->AppendOrderedChildNode(create_root_entity); assign_new_entity_from_create->AppendOrderedChildNode(first_of_create_entity); @@ -217,8 +218,8 @@ class EntityManipulation // (assign_entity_roots new_entity _) EvaluableNode *assign_new_entity_into_current = enm->AllocNode(ENT_ASSIGN_ENTITY_ROOTS); if_create_new->AppendOrderedChildNode(assign_new_entity_into_current); - assign_new_entity_into_current->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI_new_entity)); - assign_new_entity_into_current->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI__)); + assign_new_entity_into_current->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI_new_entity))); + assign_new_entity_into_current->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI__))); if(include_rand_seeds) { @@ -226,7 +227,7 @@ class EntityManipulation // new_entity // *rand seed string* ) EvaluableNode *set_rand_seed_root = enm->AllocNode(ENT_SET_ENTITY_RAND_SEED); - set_rand_seed_root->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI_new_entity)); + set_rand_seed_root->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI_new_entity))); set_rand_seed_root->AppendOrderedChildNode(enm->AllocNode(ENT_STRING, entity->GetRandomState())); declare_flatten->AppendOrderedChildNode(set_rand_seed_root); @@ -260,7 +261,7 @@ class EntityManipulation EvaluableNode *src_id_list = GetTraversalIDPathFromAToB(enm, entity, cur_entity); EvaluableNode *src_append = enm->AllocNode(ENT_APPEND); - src_append->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI_new_entity)); + src_append->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI_new_entity))); src_append->AppendOrderedChildNode(src_id_list); create_entity->AppendOrderedChildNode(src_append); @@ -291,7 +292,7 @@ class EntityManipulation } //add new_entity to return value of let statement to return the newly created id - declare_flatten->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI_new_entity)); + declare_flatten->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI_new_entity))); //if anything isn't cycle free, then need to recompute everything if(!cycle_free) diff --git a/src/Amalgam/entity/EntityQueryBuilder.h b/src/Amalgam/entity/EntityQueryBuilder.h index 09e02e60..745eda40 100644 --- a/src/Amalgam/entity/EntityQueryBuilder.h +++ b/src/Amalgam/entity/EntityQueryBuilder.h @@ -56,7 +56,7 @@ namespace EntityQueryBuilder if constexpr(std::is_same::value) { double value = std::numeric_limits::quiet_NaN(); - if(cn.first != string_intern_pool.EMPTY_STRING_ID) + if(cn.first != string_intern_pool.emptyStringId) { auto [number_value, success] = Platform_StringToNumber(string_intern_pool.GetStringFromID(cn.first)); if(success) @@ -123,7 +123,7 @@ namespace EntityQueryBuilder for(auto &cn : mcn) { double value = std::numeric_limits::quiet_NaN(); - if(cn.first != string_intern_pool.EMPTY_STRING_ID) + if(cn.first != string_intern_pool.emptyStringId) { auto [number_value, success] = Platform_StringToNumber(string_intern_pool.GetStringFromID(cn.first)); if(success) @@ -205,18 +205,14 @@ namespace EntityQueryBuilder if(found) { StringInternPool::StringID feature_type_id = EvaluableNode::ToStringIDIfExists(en); - switch(feature_type_id) - { - case ENBISI_nominal_numeric: feature_type = GeneralizedDistanceEvaluator::FDT_NOMINAL_NUMERIC; break; - case ENBISI_nominal_string: feature_type = GeneralizedDistanceEvaluator::FDT_NOMINAL_STRING; break; - case ENBISI_nominal_code: feature_type = GeneralizedDistanceEvaluator::FDT_NOMINAL_CODE; break; - case ENBISI_continuous_numeric: feature_type = GeneralizedDistanceEvaluator::FDT_CONTINUOUS_NUMERIC; break; - case ENBISI_continuous_numeric_cyclic: feature_type = GeneralizedDistanceEvaluator::FDT_CONTINUOUS_NUMERIC_CYCLIC; break; - case ENBISI_continuous_string: feature_type = GeneralizedDistanceEvaluator::FDT_CONTINUOUS_STRING; break; - case ENBISI_continuous_code: feature_type = GeneralizedDistanceEvaluator::FDT_CONTINUOUS_CODE; break; - - default: feature_type = GeneralizedDistanceEvaluator::FDT_CONTINUOUS_NUMERIC; break; - } + if(feature_type_id == GetStringIdFromBuiltInStringId(ENBISI_nominal_numeric)) feature_type = GeneralizedDistanceEvaluator::FDT_NOMINAL_NUMERIC; + else if(feature_type_id == GetStringIdFromBuiltInStringId(ENBISI_nominal_string)) feature_type = GeneralizedDistanceEvaluator::FDT_NOMINAL_STRING; + else if(feature_type_id == GetStringIdFromBuiltInStringId(ENBISI_nominal_code)) feature_type = GeneralizedDistanceEvaluator::FDT_NOMINAL_CODE; + else if(feature_type_id == GetStringIdFromBuiltInStringId(ENBISI_continuous_numeric)) feature_type = GeneralizedDistanceEvaluator::FDT_CONTINUOUS_NUMERIC; + else if(feature_type_id == GetStringIdFromBuiltInStringId(ENBISI_continuous_numeric_cyclic)) feature_type = GeneralizedDistanceEvaluator::FDT_CONTINUOUS_NUMERIC_CYCLIC; + else if(feature_type_id == GetStringIdFromBuiltInStringId(ENBISI_continuous_string)) feature_type = GeneralizedDistanceEvaluator::FDT_CONTINUOUS_STRING; + else if(feature_type_id == GetStringIdFromBuiltInStringId(ENBISI_continuous_code)) feature_type = GeneralizedDistanceEvaluator::FDT_CONTINUOUS_CODE; + else feature_type = GeneralizedDistanceEvaluator::FDT_CONTINUOUS_NUMERIC; } dist_eval.featureAttribs[i].featureType = feature_type; } @@ -460,7 +456,7 @@ namespace EntityQueryBuilder EvaluableNode *dwe_param = ocn[DISTANCE_VALUE_TRANSFORM]; if(!EvaluableNode::IsNull(dwe_param)) { - if(dwe_param->GetType() == ENT_STRING && dwe_param->GetStringIDReference() == ENBISI_surprisal_to_prob) + if(dwe_param->GetType() == ENT_STRING && dwe_param->GetStringIDReference() == GetStringIdFromBuiltInStringId(ENBISI_surprisal_to_prob)) cur_condition->distEvaluator.computeSurprisal = true; else //try to convert to number cur_condition->distanceWeightExponent = EvaluableNode::ToNumber(dwe_param, 1.0); @@ -490,12 +486,12 @@ namespace EntityQueryBuilder if(ocn.size() > NUMERICAL_PRECISION) { StringInternPool::StringID np_sid = EvaluableNode::ToStringIDIfExists(ocn[NUMERICAL_PRECISION]); - if(np_sid == ENBISI_precise) + if(np_sid == GetStringIdFromBuiltInStringId(ENBISI_precise)) { cur_condition->distEvaluator.highAccuracyDistances = true; cur_condition->distEvaluator.recomputeAccurateDistances = false; } - else if(np_sid == ENBISI_fast) + else if(np_sid == GetStringIdFromBuiltInStringId(ENBISI_fast)) { cur_condition->distEvaluator.highAccuracyDistances = false; cur_condition->distEvaluator.recomputeAccurateDistances = false; diff --git a/src/Amalgam/evaluablenode/EvaluableNode.cpp b/src/Amalgam/evaluablenode/EvaluableNode.cpp index 83680c7e..1bcff888 100644 --- a/src/Amalgam/evaluablenode/EvaluableNode.cpp +++ b/src/Amalgam/evaluablenode/EvaluableNode.cpp @@ -114,7 +114,8 @@ bool EvaluableNode::IsTrue(EvaluableNode *n) if(DoesEvaluableNodeTypeUseStringData(node_type)) { - if(n->GetStringIDReference() <= StringInternPool::EMPTY_STRING_ID) + auto sid = n->GetStringIDReference(); + if(sid == string_intern_pool.NOT_A_STRING_ID || sid == string_intern_pool.emptyStringId) return false; return true; } @@ -1017,7 +1018,7 @@ std::vector EvaluableNode::GetCommentsSeparateLines() std::vector comment_lines; StringInternPool::StringID comment_sid = GetCommentsStringId(); - if(comment_sid <= StringInternPool::EMPTY_STRING_ID) + if(comment_sid == string_intern_pool.NOT_A_STRING_ID || comment_sid == string_intern_pool.emptyStringId) return comment_lines; auto full_comments = string_intern_pool.GetStringFromID(comment_sid); diff --git a/src/Amalgam/evaluablenode/EvaluableNode.h b/src/Amalgam/evaluablenode/EvaluableNode.h index 495c2f97..8b5a2c5b 100644 --- a/src/Amalgam/evaluablenode/EvaluableNode.h +++ b/src/Amalgam/evaluablenode/EvaluableNode.h @@ -970,7 +970,7 @@ union EvaluableNodeImmediateValue : number(_number) { } - constexpr EvaluableNodeImmediateValue(StringInternPool::StringID string_id) + __forceinline EvaluableNodeImmediateValue(StringInternPool::StringID string_id) : stringID(string_id) { } @@ -982,6 +982,10 @@ union EvaluableNodeImmediateValue : code(eniv.code) { } + constexpr EvaluableNodeImmediateValue(size_t indirection_index) + : indirectionIndex(indirection_index) + { } + __forceinline EvaluableNodeImmediateValue &operator =(const EvaluableNodeImmediateValue &eniv) { //perform a memcpy because it's a union, to be safe; the compiler should optimize this out @@ -1070,7 +1074,7 @@ class EvaluableNodeImmediateValueWithType : nodeType(ENIVT_NULL) { } - constexpr EvaluableNodeImmediateValueWithType(EvaluableNodeImmediateValue node_value, + __forceinline EvaluableNodeImmediateValueWithType(EvaluableNodeImmediateValue node_value, EvaluableNodeImmediateValueType node_type) : nodeType(node_type), nodeValue(node_value) { } @@ -1168,7 +1172,8 @@ class EvaluableNodeImmediateValueWithType if(nodeType == ENIVT_STRING_ID) { - if(nodeValue.stringID <= StringInternPool::EMPTY_STRING_ID) + if(nodeValue.stringID == string_intern_pool.NOT_A_STRING_ID + || nodeValue.stringID == string_intern_pool.emptyStringId) return false; return true; } diff --git a/src/Amalgam/evaluablenode/EvaluableNodeManagement.h b/src/Amalgam/evaluablenode/EvaluableNodeManagement.h index 316ed1e4..59c6b2b9 100644 --- a/src/Amalgam/evaluablenode/EvaluableNodeManagement.h +++ b/src/Amalgam/evaluablenode/EvaluableNodeManagement.h @@ -372,11 +372,9 @@ class EvaluableNodeManager return n; } - inline EvaluableNode *AllocNode(EvaluableNodeType type, StringInternRef &sir) + inline EvaluableNode *AllocNode(EvaluableNodeType type, StringRef &sir) { return AllocNode(type, static_cast(sir)); } - inline EvaluableNode *AllocNode(EvaluableNodeType type, StringInternWeakRef &siwr) - { return AllocNode(type, static_cast(siwr)); } - + inline EvaluableNode *AllocNode(double float_value) { EvaluableNode *n = AllocUninitializedNode(); diff --git a/src/Amalgam/evaluablenode/EvaluableNodeTreeDifference.cpp b/src/Amalgam/evaluablenode/EvaluableNodeTreeDifference.cpp index 3f69aaf7..3dce9870 100644 --- a/src/Amalgam/evaluablenode/EvaluableNodeTreeDifference.cpp +++ b/src/Amalgam/evaluablenode/EvaluableNodeTreeDifference.cpp @@ -37,13 +37,13 @@ EvaluableNode *EvaluableNodeTreeDifference::DifferenceTrees(EvaluableNodeManager //update difference function to: (declare (assoc _ null) ) EvaluableNode *df_vars = enm->AllocNode(ENT_ASSOC); - df_vars->SetMappedChildNode(ENBISI__, enm->AllocNode(ENT_NULL)); + df_vars->SetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI__), enm->AllocNode(ENT_NULL)); difference_function->AppendOrderedChildNode(df_vars); //update difference function to: (declare (assoc _ null) (replace _ ) ) EvaluableNode *df_replace = enm->AllocNode(ENT_REPLACE); difference_function->AppendOrderedChildNode(df_replace); - df_replace->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, ENBISI__)); + df_replace->AppendOrderedChildNode(enm->AllocNode(ENT_SYMBOL, GetStringIdFromBuiltInStringId(ENBISI__))); ////////// //find nodes that are mutually exclusive and create lookup tables diff --git a/src/Amalgam/evaluablenode/EvaluableNodeTreeFunctions.h b/src/Amalgam/evaluablenode/EvaluableNodeTreeFunctions.h index a0ead769..c301b4d3 100644 --- a/src/Amalgam/evaluablenode/EvaluableNodeTreeFunctions.h +++ b/src/Amalgam/evaluablenode/EvaluableNodeTreeFunctions.h @@ -44,14 +44,14 @@ class EvaluableNodeIDPathTraverser { } //calls AnalyzeIDPath with the same parameters - inline EvaluableNodeIDPathTraverser(EvaluableNode *id_path, StringInternRef *dest_sid_ref) + inline EvaluableNodeIDPathTraverser(EvaluableNode *id_path, StringRef *dest_sid_ref) { AnalyzeIDPath(id_path, dest_sid_ref); } //populates attributes based on the id_path //if has non-null dest_sid_ref, then it will store the pointer and use it to populate the destination string id - void AnalyzeIDPath(EvaluableNode *id_path, StringInternRef *dest_sid_ref) + void AnalyzeIDPath(EvaluableNode *id_path, StringRef *dest_sid_ref) { idPath = nullptr; idPathEntries = nullptr; @@ -63,7 +63,7 @@ class EvaluableNodeIDPathTraverser destSidReference = dest_sid_ref; //if the destination sid is requested, initialize it if(destSidReference != nullptr) - *destSidReference = StringInternRef(string_intern_pool.NOT_A_STRING_ID); + destSidReference->Clear(); //if single value, then just set and return if(EvaluableNode::IsNull(id_path)) @@ -171,14 +171,14 @@ class EvaluableNodeIDPathTraverser size_t lastIdIndex; //if not nullptr, then will be set to a reference to the destination string id - StringInternRef *destSidReference; + StringRef *destSidReference; }; template std::pair TraverseToEntityReferenceAndContainerViaEvaluableNodeID(Entity *from_entity, EvaluableNode *id_node, - StringInternRef *dest_sid_ref) + StringRef *dest_sid_ref) { if(EvaluableNode::IsNull(id_node)) return std::make_pair(EntityReferenceType(from_entity), EntityReferenceType(nullptr)); @@ -214,7 +214,7 @@ template std::pair TraverseToEntityReferenceAndContainerViaEvaluableNodeID(Entity *from_entity, EvaluableNode *id_node_1, EvaluableNode *id_node_2, - StringInternRef *dest_sid_ref) + StringRef *dest_sid_ref) { if(EvaluableNode::IsNull(id_node_1)) return TraverseToEntityReferenceAndContainerViaEvaluableNodeID(from_entity, id_node_2, dest_sid_ref); @@ -339,7 +339,7 @@ inline EntityReferenceType TraverseToExistingEntityReferenceViaEvaluableNodeIDPa template std::pair TraverseToEntityReferenceAndContainerViaEvaluableNodeIDPath( - Entity *from_entity, EvaluableNode *id_path, StringInternRef *dest_sid_ref = nullptr) + Entity *from_entity, EvaluableNode *id_path, StringRef *dest_sid_ref = nullptr) { EvaluableNodeIDPathTraverser traverser(id_path, dest_sid_ref); auto [entity, container] diff --git a/src/Amalgam/evaluablenode/EvaluableNodeTreeManipulation.cpp b/src/Amalgam/evaluablenode/EvaluableNodeTreeManipulation.cpp index ddbdf578..aa43ea7b 100644 --- a/src/Amalgam/evaluablenode/EvaluableNodeTreeManipulation.cpp +++ b/src/Amalgam/evaluablenode/EvaluableNodeTreeManipulation.cpp @@ -662,7 +662,7 @@ EvaluableNode *EvaluableNodeTreeManipulation::MergeTrees(NodesMergeMethod *mm, E EvaluableNode *EvaluableNodeTreeManipulation::MutateTree(Interpreter *interpreter, EvaluableNodeManager *enm, EvaluableNode *tree, double mutation_rate, - CompactHashMap *mutation_weights, + CompactHashMap *mutation_weights, CompactHashMap *evaluable_node_weights) { std::vector strings; @@ -1515,7 +1515,7 @@ EvaluableNode *EvaluableNodeTreeManipulation::MutateNode(EvaluableNode *n, Mutat MutateImmediateNode(n, mp.interpreter->randomStream, *mp.strings); } - StringInternPool::StringID mutation_type = mp.randMutationType->WeightedDiscreteRand(mp.interpreter->randomStream); + EvaluableNodeBuiltInStringId mutation_type = mp.randMutationType->WeightedDiscreteRand(mp.interpreter->randomStream); //only mark for likely deletion if null has no parameters if(n->GetType() == ENT_NULL && n->GetNumChildNodes() == 0 && mp.interpreter->randomStream.Rand() < 0.5) mutation_type = ENBISI_delete; @@ -1857,7 +1857,7 @@ FlatMatrix EvaluableNodeTreeManipulation::sequenceCommonalityBuffer; EvaluableNode EvaluableNodeTreeManipulation::nullEvaluableNode(ENT_NULL); -CompactHashMap EvaluableNodeTreeManipulation::mutationOperationTypeProbabilities +CompactHashMap EvaluableNodeTreeManipulation::mutationOperationTypeProbabilities { { ENBISI_change_type, 0.28 }, { ENBISI_delete, 0.12 }, @@ -1868,7 +1868,7 @@ CompactHashMap EvaluableNodeTreeManipulation { ENBISI_change_label, 0.04 } }; -EvaluableNodeTreeManipulation::MutationParameters::WeightedRandMutationType EvaluableNodeTreeManipulation::mutationOperationTypeRandomStream(mutationOperationTypeProbabilities, true); +EvaluableNodeTreeManipulation::MutationParameters::WeightedRandMutationType EvaluableNodeTreeManipulation::mutationOperationTypeRandomStream(mutationOperationTypeProbabilities, true); CompactHashMap EvaluableNodeTreeManipulation::evaluableNodeTypeProbabilities { diff --git a/src/Amalgam/evaluablenode/EvaluableNodeTreeManipulation.h b/src/Amalgam/evaluablenode/EvaluableNodeTreeManipulation.h index d0555e6d..fd0e893e 100644 --- a/src/Amalgam/evaluablenode/EvaluableNodeTreeManipulation.h +++ b/src/Amalgam/evaluablenode/EvaluableNodeTreeManipulation.h @@ -63,7 +63,7 @@ inline double NumberCommonality(double difference, double a, double b) } //for random streams that are based on an EvaluableNode MappedChildNodes -typedef WeightedDiscreteRandomStreamTransform +typedef WeightedDiscreteRandomStreamTransform EvaluableNodeMappedWeightedDiscreteRandomStreamTransform; class EvaluableNodeTreeManipulation @@ -75,8 +75,8 @@ class EvaluableNodeTreeManipulation typedef WeightedDiscreteRandomStreamTransform> WeightedRandEvaluableNodeType; - typedef WeightedDiscreteRandomStreamTransform> WeightedRandMutationType; + typedef WeightedDiscreteRandomStreamTransform> WeightedRandMutationType; Interpreter *interpreter; EvaluableNodeManager *enm; @@ -109,7 +109,7 @@ class EvaluableNodeTreeManipulation } }; - static CompactHashMap mutationOperationTypeProbabilities; + static CompactHashMap mutationOperationTypeProbabilities; static CompactHashMap evaluableNodeTypeProbabilities; //functionality to merge two nodes @@ -507,7 +507,8 @@ class EvaluableNodeTreeManipulation //Returns a tree that is a copy of tree but mutated based on mutation_rate // will create the new tree with interpreter's evaluableNodeManager and will use interpreter's RandomStream //Note that MutateTree does not guarantee that EvaluableNodeFlags will be set appropriately - static EvaluableNode *MutateTree(Interpreter *interpreter, EvaluableNodeManager *enm, EvaluableNode *tree, double mutation_rate, CompactHashMap *mutation_weights, CompactHashMap *evaluable_node_weights); + static EvaluableNode *MutateTree(Interpreter *interpreter, EvaluableNodeManager *enm, EvaluableNode *tree, double mutation_rate, + CompactHashMap *mutation_weights, CompactHashMap *evaluable_node_weights); //traverses tree and replaces any string that matches a key of to_replace with the value in to_replace static void ReplaceStringsInTree(EvaluableNode *tree, CompactHashMap &to_replace); diff --git a/src/Amalgam/interpreter/Interpreter.cpp b/src/Amalgam/interpreter/Interpreter.cpp index e23042c8..5fe4fe3f 100644 --- a/src/Amalgam/interpreter/Interpreter.cpp +++ b/src/Amalgam/interpreter/Interpreter.cpp @@ -675,11 +675,11 @@ bool Interpreter::InterpretNodeIntoBoolValue(EvaluableNode *n, bool value_if_nul return value; } -std::pair Interpreter::InterpretNodeIntoDestinationEntity(EvaluableNode *n) +std::pair Interpreter::InterpretNodeIntoDestinationEntity(EvaluableNode *n) { EvaluableNodeReference destination_entity_id_path = InterpretNodeForImmediateUse(n); - StringInternRef new_entity_id; + StringRef new_entity_id; auto [entity, entity_container] = TraverseToEntityReferenceAndContainerViaEvaluableNodeIDPath( curEntity, destination_entity_id_path, &new_entity_id); @@ -687,7 +687,7 @@ std::pair Interpreter::InterpretNodeIntoD //if it already exists, then place inside it if(entity != nullptr) - return std::make_pair(std::move(entity), StringInternRef()); + return std::make_pair(std::move(entity), StringRef()); else //return the container return std::make_pair(std::move(entity_container), new_entity_id); } diff --git a/src/Amalgam/interpreter/Interpreter.h b/src/Amalgam/interpreter/Interpreter.h index be2845be..63466d8d 100644 --- a/src/Amalgam/interpreter/Interpreter.h +++ b/src/Amalgam/interpreter/Interpreter.h @@ -507,8 +507,8 @@ class Interpreter //Calls InterpretNode on n, converts n into a destination for an Entity, relative to curEntity. // If invalid, returns a nullptr for the EntityWriteReference - //StringInternRef is an alocated string reference, and the caller is responsible for freeing it - std::pair InterpretNodeIntoDestinationEntity(EvaluableNode *n); + //StringRef is an alocated string reference, and the caller is responsible for freeing it + std::pair InterpretNodeIntoDestinationEntity(EvaluableNode *n); //traverses source based on traversal path list tpl // If create_destination_if_necessary is set, then it will expand anything in the source as appropriate diff --git a/src/Amalgam/interpreter/InterpreterOpcodesBase.cpp b/src/Amalgam/interpreter/InterpreterOpcodesBase.cpp index 8083c868..53ae1790 100644 --- a/src/Amalgam/interpreter/InterpreterOpcodesBase.cpp +++ b/src/Amalgam/interpreter/InterpreterOpcodesBase.cpp @@ -266,8 +266,8 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_GET_DEFAULTS(EvaluableNode EvaluableNode *num_node = evaluableNodeManager->AllocNode(ENT_NUMBER); num_node->SetNumberValue(node_prob); - const std::string &node_type_string = GetStringFromEvaluableNodeType(node_type, true); - out_node->SetMappedChildNode(node_type_string, num_node); + StringInternPool::StringID node_type_sid = GetStringIdFromNodeType(node_type); + out_node->SetMappedChildNode(node_type_sid, num_node); } return EvaluableNodeReference(out_node, true); @@ -281,7 +281,8 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_GET_DEFAULTS(EvaluableNode { EvaluableNode *num_node = evaluableNodeManager->AllocNode(ENT_NUMBER); num_node->SetNumberValue(op_prob); - out_node->SetMappedChildNode(op_type, num_node); + StringInternPool::StringID op_type_sid = GetStringIdFromBuiltInStringId(op_type); + out_node->SetMappedChildNode(op_type_sid, num_node); } return EvaluableNodeReference(out_node, true); @@ -918,7 +919,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_ASSIGN_and_ACCUM(Evaluable } //using a single variable - StringInternRef variable_sid; + StringRef variable_sid; variable_sid.SetIDWithReferenceHandoff(InterpretNodeIntoStringIDValueWithReference(ocn[0])); if(variable_sid == StringInternPool::NOT_A_STRING_ID) return EvaluableNodeReference::Null(); diff --git a/src/Amalgam/interpreter/InterpreterOpcodesCodeMixing.cpp b/src/Amalgam/interpreter/InterpreterOpcodesCodeMixing.cpp index 4dd7d695..8e5d15f0 100644 --- a/src/Amalgam/interpreter/InterpreterOpcodesCodeMixing.cpp +++ b/src/Amalgam/interpreter/InterpreterOpcodesCodeMixing.cpp @@ -51,7 +51,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MUTATE(EvaluableNode *en, } bool mtw_exists = false; - CompactHashMap mutation_type_weights; + CompactHashMap mutation_type_weights; if(ocn.size() > 3) { auto mutation_weights_node = InterpretNodeForImmediateUse(ocn[3]); @@ -59,14 +59,18 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MUTATE(EvaluableNode *en, { mtw_exists = true; for(auto &[node_id, node] : mutation_weights_node->GetMappedChildNodes()) - mutation_type_weights[node_id] = EvaluableNode::ToNumber(node); + { + auto bisid = GetBuiltInStringIdFromStringId(node_id); + mutation_type_weights[bisid] = EvaluableNode::ToNumber(node); + } evaluableNodeManager->FreeNodeTreeIfPossible(mutation_weights_node); } } //result contains the copied result which may incur replacements - EvaluableNode *result = EvaluableNodeTreeManipulation::MutateTree(this, evaluableNodeManager, to_mutate, mutation_rate, mtw_exists ? &mutation_type_weights : nullptr, ow_exists ? &opcode_weights : nullptr); + EvaluableNode *result = EvaluableNodeTreeManipulation::MutateTree(this, evaluableNodeManager, + to_mutate, mutation_rate, mtw_exists ? &mutation_type_weights : nullptr, ow_exists ? &opcode_weights : nullptr); EvaluableNodeManager::UpdateFlagsForNodeTree(result); return EvaluableNodeReference(result, true); } @@ -380,7 +384,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MUTATE_ENTITY(EvaluableNod } bool mtw_exists = false; - CompactHashMap mutation_type_weights; + CompactHashMap mutation_type_weights; if(ocn.size() > 4) { auto mutation_weights_node = InterpretNodeForImmediateUse(ocn[4]); @@ -388,7 +392,10 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MUTATE_ENTITY(EvaluableNod { mtw_exists = true; for(auto &[node_id, node] : mutation_weights_node->GetMappedChildNodes()) - mutation_type_weights[node_id] = EvaluableNode::ToNumber(node); + { + auto bisid = GetBuiltInStringIdFromStringId(node_id); + mutation_type_weights[bisid] = EvaluableNode::ToNumber(node); + } evaluableNodeManager->FreeNodeTreeIfPossible(mutation_weights_node); } @@ -403,7 +410,8 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MUTATE_ENTITY(EvaluableNod return EvaluableNodeReference::Null(); //create new entity by mutating - Entity *new_entity = EntityManipulation::MutateEntity(this, source_entity, mutation_rate, mtw_exists ? &mutation_type_weights : nullptr, ow_exists ? &opcode_weights : nullptr); + Entity *new_entity = EntityManipulation::MutateEntity(this, source_entity, mutation_rate, + mtw_exists ? &mutation_type_weights : nullptr, ow_exists ? &opcode_weights : nullptr); //accumulate usage if(ConstrainedAllocatedNodes()) @@ -414,7 +422,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MUTATE_ENTITY(EvaluableNod //get destination if applicable EntityWriteReference destination_entity_parent; - StringInternRef new_entity_id; + StringRef new_entity_id; if(ocn.size() > 2) std::tie(destination_entity_parent, new_entity_id) = InterpretNodeIntoDestinationEntity(ocn[2]); else @@ -496,7 +504,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_INTERSECT_ENTITIES(Evaluab //get destination if applicable EntityWriteReference destination_entity_parent; - StringInternRef new_entity_id; + StringRef new_entity_id; if(ocn.size() > 2) std::tie(destination_entity_parent, new_entity_id) = InterpretNodeIntoDestinationEntity(ocn[2]); else @@ -556,7 +564,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_UNION_ENTITIES(EvaluableNo //get destination if applicable EntityWriteReference destination_entity_parent; - StringInternRef new_entity_id; + StringRef new_entity_id; if(ocn.size() > 2) std::tie(destination_entity_parent, new_entity_id) = InterpretNodeIntoDestinationEntity(ocn[2]); else @@ -678,7 +686,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MIX_ENTITIES(EvaluableNode //get destination if applicable EntityWriteReference destination_entity_parent; - StringInternRef new_entity_id; + StringRef new_entity_id; if(ocn.size() > 6) std::tie(destination_entity_parent, new_entity_id) = InterpretNodeIntoDestinationEntity(ocn[6]); else diff --git a/src/Amalgam/interpreter/InterpreterOpcodesDataTypes.cpp b/src/Amalgam/interpreter/InterpreterOpcodesDataTypes.cpp index 10eb4567..bcc065fb 100644 --- a/src/Amalgam/interpreter/InterpreterOpcodesDataTypes.cpp +++ b/src/Amalgam/interpreter/InterpreterOpcodesDataTypes.cpp @@ -291,7 +291,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, if(ocn.size() < 3) return EvaluableNodeReference::Null(); - StringInternRef from_type, to_type; + StringRef from_type, to_type; from_type.SetIDWithReferenceHandoff(InterpretNodeIntoStringIDValueWithReference(ocn[1])); to_type.SetIDWithReferenceHandoff(InterpretNodeIntoStringIDValueWithReference(ocn[2])); @@ -324,12 +324,12 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, const std::string date_string("date:"); - if(from_type == GetStringIdFromNodeTypeFromString(ENT_NUMBER)) + if(from_type == GetStringIdFromNodeType(ENT_NUMBER)) { use_number = true; number_value = InterpretNodeIntoNumberValue(ocn[0]); } - else if(from_type == ENBISI_code) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_code)) { use_code = true; code_value = InterpretNodeForImmediateUse(ocn[0]); @@ -338,83 +338,83 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, { string_value = InterpretNodeIntoStringValueEmptyNull(ocn[0]); - if(from_type == GetStringIdFromNodeTypeFromString(ENT_STRING)) + if(from_type == GetStringIdFromNodeType(ENT_STRING)) { use_string = true; } - else if(from_type == ENBISI_Base16) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_Base16)) { use_string = true; string_value = StringManipulation::Base16ToBinaryString(string_value); } - else if(from_type == ENBISI_Base64) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_Base64)) { use_string = true; string_value = StringManipulation::Base64ToBinaryString(string_value); } - else if(from_type == ENBISI_uint8 || from_type == ENBISI_UINT8) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_uint8) || from_type == GetStringIdFromBuiltInStringId(ENBISI_UINT8)) { use_uint_number = true; uint_number_value = reinterpret_cast(string_value[0]); } - else if(from_type == ENBISI_int8 || from_type == ENBISI_INT8) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_int8) || from_type == GetStringIdFromBuiltInStringId(ENBISI_INT8)) { use_int_number = true; int_number_value = ExpandCharStorage(string_value[0]); } - else if(from_type == ENBISI_uint16) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_uint16)) { use_uint_number = true; if(string_value.size() >= 2) uint_number_value = ExpandCharStorage(string_value[0]) | (ExpandCharStorage(string_value[1]) << 8); } - else if(from_type == ENBISI_UINT16) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_UINT16)) { use_uint_number = true; if(string_value.size() >= 2) uint_number_value = ExpandCharStorage(string_value[1]) | (ExpandCharStorage(string_value[1]) << 8); } - else if(from_type == ENBISI_int16) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_int16)) { use_int_number = true; if(string_value.size() >= 2) //sign extend the most significant byte int_number_value = ExpandCharStorage(string_value[0]) | (ExpandCharStorage(string_value[1]) << 8); } - else if(from_type == ENBISI_INT16) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_INT16)) { use_int_number = true; if(string_value.size() >= 2) //sign extend the most significant byte int_number_value = ExpandCharStorage(string_value[1]) | (ExpandCharStorage(string_value[0]) << 8); } - else if(from_type == ENBISI_uint32) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_uint32)) { use_uint_number = true; if(string_value.size() >= 4) uint_number_value = ExpandCharStorage(string_value[0]) | (ExpandCharStorage(string_value[1]) << 8) | (ExpandCharStorage(string_value[2]) << 16) | (ExpandCharStorage(string_value[3]) << 24); } - else if(from_type == ENBISI_UINT32) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_UINT32)) { use_uint_number = true; if(string_value.size() >= 4) uint_number_value = ExpandCharStorage(string_value[3]) | (ExpandCharStorage(string_value[2]) << 8) | (ExpandCharStorage(string_value[1]) << 16) | (ExpandCharStorage(string_value[0]) << 24); } - else if(from_type == ENBISI_int32) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_int32)) { use_int_number = true; if(string_value.size() >= 4) //sign extend the most significant byte int_number_value = ExpandCharStorage(string_value[0]) | (ExpandCharStorage(string_value[1]) << 8) | (ExpandCharStorage(string_value[2]) << 16) | (ExpandCharStorage(string_value[3]) << 24); } - else if(from_type == ENBISI_INT32) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_INT32)) { use_int_number = true; if(string_value.size() >= 4) //sign extend the most significant byte int_number_value = ExpandCharStorage(string_value[3]) | (ExpandCharStorage(string_value[2]) << 8) | (ExpandCharStorage(string_value[1]) << 16) | (ExpandCharStorage(string_value[0]) << 24); } - else if(from_type == ENBISI_uint64) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_uint64)) { use_uint_number = true; if(string_value.size() >= 8) @@ -424,7 +424,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, | (ExpandCharStorage(string_value[4]) << 32) | (ExpandCharStorage(string_value[5]) << 40) | (ExpandCharStorage(string_value[6]) << 48) | (ExpandCharStorage(string_value[7]) << 56); } - else if(from_type == ENBISI_UINT64) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_UINT64)) { use_uint_number = true; if(string_value.size() >= 8) @@ -434,7 +434,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, | (ExpandCharStorage(string_value[3]) << 32) | (ExpandCharStorage(string_value[2]) << 40) | (ExpandCharStorage(string_value[1]) << 48) | (ExpandCharStorage(string_value[0]) << 56); } - else if(from_type == ENBISI_int64) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_int64)) { use_int_number = true; if(string_value.size() >= 8) @@ -447,7 +447,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, int_number_value = reinterpret_cast(uint_number_value); } } - else if(from_type == ENBISI_INT64) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_INT64)) { use_int_number = true; if(string_value.size() >= 8) @@ -460,7 +460,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, int_number_value = reinterpret_cast(uint_number_value); } } - else if(from_type == ENBISI_float) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_float)) { use_number = true; if(string_value.size() >= 4) @@ -471,7 +471,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, number_value = reinterpret_cast(temp); } } - else if(from_type == ENBISI_FLOAT) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_FLOAT)) { use_number = true; if(string_value.size() >= 4) @@ -482,7 +482,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, number_value = reinterpret_cast(temp); } } - else if(from_type == ENBISI_double) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_double)) { use_number = true; if(string_value.size() >= 8) @@ -495,7 +495,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, number_value = reinterpret_cast(uint_number_value); } } - else if(from_type == ENBISI_DOUBLE) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_DOUBLE)) { use_number = true; if(string_value.size() >= 8) @@ -508,12 +508,12 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, number_value = reinterpret_cast(uint_number_value); } } - else if(from_type == ENBISI_json) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_json)) { use_code = true; code_value = EvaluableNodeReference(EvaluableNodeJSONTranslation::JsonToEvaluableNode(evaluableNodeManager, string_value), true); } - else if(from_type == ENBISI_yaml) + else if(from_type == GetStringIdFromBuiltInStringId(ENBISI_yaml)) { use_code = true; code_value = EvaluableNodeReference(EvaluableNodeYAMLTranslation::YamlToEvaluableNode(evaluableNodeManager, string_value), true); @@ -531,11 +531,11 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, { auto &mcn = from_params->GetMappedChildNodesReference(); - auto found_locale = mcn.find(ENBISI_locale); + auto found_locale = mcn.find(GetStringIdFromBuiltInStringId(ENBISI_locale)); if(found_locale != end(mcn) && !EvaluableNode::IsNull(found_locale->second)) locale = EvaluableNode::ToStringPreservingOpcodeType(found_locale->second); - auto found_timezone = mcn.find(ENBISI_timezone); + auto found_timezone = mcn.find(GetStringIdFromBuiltInStringId(ENBISI_timezone)); if(found_timezone != end(mcn) && !EvaluableNode::IsNull(found_timezone->second)) timezone = EvaluableNode::ToStringPreservingOpcodeType(found_timezone->second); } @@ -556,7 +556,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, to_params = InterpretNodeForImmediateUse(ocn[4]); //convert - if(to_type == GetStringIdFromNodeTypeFromString(ENT_NUMBER)) + if(to_type == GetStringIdFromNodeType(ENT_NUMBER)) { //don't need to do anything if use_number if(use_uint_number) @@ -574,12 +574,12 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, return ReuseOrAllocOneOfReturn(to_params, code_value, number_value, immediate_result); } - else if(to_type == ENBISI_code) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_code)) { evaluableNodeManager->FreeNodeTreeIfPossible(to_params); return code_value; } - else if(to_type == GetStringIdFromNodeTypeFromString(ENT_STRING)) + else if(to_type == GetStringIdFromNodeType(ENT_STRING)) { //don't need to do anything if use_string if(use_number) @@ -595,7 +595,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, { auto &mcn = to_params->GetMappedChildNodesReference(); - auto found_sort_keys = mcn.find(ENBISI_sort_keys); + auto found_sort_keys = mcn.find(GetStringIdFromBuiltInStringId(ENBISI_sort_keys)); if(found_sort_keys != end(mcn)) sort_keys = EvaluableNode::IsTrue(found_sort_keys->second); } @@ -603,7 +603,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, string_value = Parser::Unparse(code_value, evaluableNodeManager, false, true, sort_keys); } } - else if(to_type == ENBISI_Base16 || to_type == ENBISI_Base64) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_Base16) || to_type == GetStringIdFromBuiltInStringId(ENBISI_Base64)) { if(use_number) { @@ -640,89 +640,89 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, if(use_code) string_value = Parser::Unparse(code_value, evaluableNodeManager, false); - if(to_type == ENBISI_Base16) + if(to_type == GetStringIdFromBuiltInStringId(ENBISI_Base16)) string_value = StringManipulation::BinaryStringToBase16(string_value); else //Base64 string_value = StringManipulation::BinaryStringToBase64(string_value); } - else if(to_type == ENBISI_uint8 || to_type == ENBISI_UINT8) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_uint8) || to_type == GetStringIdFromBuiltInStringId(ENBISI_UINT8)) { if(use_number) string_value = StringManipulation::To1ByteString(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To1ByteString(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To1ByteString(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To1ByteString(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_int8 || to_type == ENBISI_INT8) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_int8) || to_type == GetStringIdFromBuiltInStringId(ENBISI_INT8)) { if(use_number) string_value = StringManipulation::To1ByteString(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To1ByteString(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To1ByteString(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To1ByteString(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_uint16) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_uint16)) { if(use_number) string_value = StringManipulation::To2ByteStringLittleEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To2ByteStringLittleEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To2ByteStringLittleEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To2ByteStringLittleEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_UINT16) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_UINT16)) { if(use_number) string_value = StringManipulation::To2ByteStringBigEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To2ByteStringBigEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To2ByteStringBigEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To2ByteStringBigEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_int16) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_int16)) { if(use_number) string_value = StringManipulation::To2ByteStringLittleEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To2ByteStringLittleEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To2ByteStringLittleEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To2ByteStringLittleEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_INT16) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_INT16)) { if(use_number) string_value = StringManipulation::To2ByteStringBigEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To2ByteStringBigEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To2ByteStringBigEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To2ByteStringBigEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_uint32) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_uint32)) { if(use_number) string_value = StringManipulation::To4ByteStringLittleEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To4ByteStringLittleEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To4ByteStringLittleEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To4ByteStringLittleEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_UINT32) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_UINT32)) { if(use_number) string_value = StringManipulation::To4ByteStringBigEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To4ByteStringBigEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To4ByteStringBigEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To4ByteStringBigEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_int32) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_int32)) { if(use_number) string_value = StringManipulation::To4ByteStringLittleEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To4ByteStringLittleEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To4ByteStringLittleEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To4ByteStringLittleEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_INT32) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_INT32)) { if(use_number) string_value = StringManipulation::To4ByteStringBigEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To4ByteStringBigEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To4ByteStringBigEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To4ByteStringBigEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_uint64) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_uint64)) { if(use_number) string_value = StringManipulation::To8ByteStringLittleEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To8ByteStringLittleEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To8ByteStringLittleEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To8ByteStringLittleEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_UINT64) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_UINT64)) { if(use_number) string_value = StringManipulation::To8ByteStringBigEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To8ByteStringBigEndian(static_cast(uint_number_value)); @@ -730,49 +730,49 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, else if(use_code) string_value = StringManipulation::To8ByteStringBigEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_int64) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_int64)) { if(use_number) string_value = StringManipulation::To8ByteStringLittleEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To8ByteStringLittleEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To8ByteStringLittleEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To8ByteStringLittleEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_INT64) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_INT64)) { if(use_number) string_value = StringManipulation::To8ByteStringBigEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To8ByteStringBigEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To8ByteStringBigEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To8ByteStringBigEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_float) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_float)) { if(use_number) string_value = StringManipulation::To4ByteStringLittleEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To4ByteStringLittleEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To4ByteStringLittleEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To4ByteStringLittleEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_FLOAT) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_FLOAT)) { if(use_number) string_value = StringManipulation::To4ByteStringBigEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To4ByteStringBigEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To4ByteStringBigEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To4ByteStringBigEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_double) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_double)) { if(use_number) string_value = StringManipulation::To8ByteStringLittleEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To8ByteStringLittleEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To8ByteStringLittleEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To8ByteStringLittleEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_DOUBLE) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_DOUBLE)) { if(use_number) string_value = StringManipulation::To8ByteStringBigEndian(static_cast(number_value)); else if(use_uint_number) string_value = StringManipulation::To8ByteStringBigEndian(static_cast(uint_number_value)); else if(use_int_number) string_value = StringManipulation::To8ByteStringBigEndian(static_cast(int_number_value)); else if(use_code) string_value = StringManipulation::To8ByteStringBigEndian(static_cast(EvaluableNode::ToNumber(code_value))); } - else if(to_type == ENBISI_json) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_json)) { if(use_number) string_value = EvaluableNode::NumberToString(number_value); @@ -792,7 +792,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, { auto &mcn = to_params->GetMappedChildNodesReference(); - auto found_sort_keys = mcn.find(ENBISI_sort_keys); + auto found_sort_keys = mcn.find(GetStringIdFromBuiltInStringId(ENBISI_sort_keys)); if(found_sort_keys != end(mcn)) sort_keys = EvaluableNode::IsTrue(found_sort_keys->second); } @@ -800,7 +800,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, std::tie(string_value, valid_string_value) = EvaluableNodeJSONTranslation::EvaluableNodeToJson(code_value, sort_keys); } } - else if(to_type == ENBISI_yaml) + else if(to_type == GetStringIdFromBuiltInStringId(ENBISI_yaml)) { if(use_number) { @@ -829,7 +829,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, { auto &mcn = to_params->GetMappedChildNodesReference(); - auto found_sort_keys = mcn.find(ENBISI_sort_keys); + auto found_sort_keys = mcn.find(GetStringIdFromBuiltInStringId(ENBISI_sort_keys)); if(found_sort_keys != end(mcn)) sort_keys = EvaluableNode::IsTrue(found_sort_keys->second); } @@ -850,11 +850,11 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FORMAT(EvaluableNode *en, { auto &mcn = to_params->GetMappedChildNodesReference(); - auto found_locale = mcn.find(ENBISI_locale); + auto found_locale = mcn.find(GetStringIdFromBuiltInStringId(ENBISI_locale)); if(found_locale != end(mcn) && !EvaluableNode::IsNull(found_locale->second)) locale = EvaluableNode::ToStringPreservingOpcodeType(found_locale->second); - auto found_timezone = mcn.find(ENBISI_timezone); + auto found_timezone = mcn.find(GetStringIdFromBuiltInStringId(ENBISI_timezone)); if(found_timezone != end(mcn) && !EvaluableNode::IsNull(found_timezone->second)) timezone = EvaluableNode::ToStringPreservingOpcodeType(found_timezone->second); } @@ -955,7 +955,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_SET_LABELS(EvaluableNode * if(e != nullptr) { //obtain the label, reusing the sid reference if possible - StringInternPool::StringID label_sid = string_intern_pool.EMPTY_STRING_ID; + StringInternPool::StringID label_sid = string_intern_pool.emptyStringId; if(label_list.unique) label_sid = EvaluableNode::ToStringIDTakingReferenceAndClearing(e); else @@ -1012,7 +1012,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_ZIP_LABELS(EvaluableNode * retval_ocn[i] = evaluableNodeManager->AllocNode(retval_ocn[i]); //obtain the label, reusing the sid reference if possible - StringInternPool::StringID label_sid = string_intern_pool.EMPTY_STRING_ID; + StringInternPool::StringID label_sid = string_intern_pool.emptyStringId; if(label_list.unique) label_sid = EvaluableNode::ToStringIDTakingReferenceAndClearing(label_list_ocn[i]); else @@ -1537,12 +1537,12 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_SUBSTR(EvaluableNode *en, if(param_node->GetType() == ENT_STRING) { auto pnsid = param_node->GetStringIDReference(); - if(pnsid == ENBISI_all) + if(pnsid == GetStringIdFromBuiltInStringId(ENBISI_all)) { first_match_only = false; full_matches = true; } - else if(pnsid == ENBISI_submatches) + else if(pnsid == GetStringIdFromBuiltInStringId(ENBISI_submatches)) { first_match_only = false; submatches = true; diff --git a/src/Amalgam/interpreter/InterpreterOpcodesEntityAccess.cpp b/src/Amalgam/interpreter/InterpreterOpcodesEntityAccess.cpp index f9b38f43..d48c7ebe 100644 --- a/src/Amalgam/interpreter/InterpreterOpcodesEntityAccess.cpp +++ b/src/Amalgam/interpreter/InterpreterOpcodesEntityAccess.cpp @@ -426,7 +426,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_CALL_ENTITY_and_CALL_ENTIT if(curEntity == nullptr) return EvaluableNodeReference::Null(); - StringInternRef entity_label_sid; + StringRef entity_label_sid; if(ocn.size() > 1) entity_label_sid.SetIDWithReferenceHandoff(InterpretNodeIntoStringIDValueWithReference(ocn[1])); @@ -598,7 +598,8 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_CALL_CONTAINER(EvaluableNo //add accessing_entity to arguments. If accessing_entity already specified (it shouldn't be), let garbage collection clean it up EvaluableNode *call_stack_args = call_stack->GetOrderedChildNodesReference()[0]; - call_stack_args->SetMappedChildNode(ENBISI_accessing_entity, container->evaluableNodeManager.AllocNode(ENT_STRING, cur_entity_sid)); + call_stack_args->SetMappedChildNode(GetStringIdFromBuiltInStringId(ENBISI_accessing_entity), + container->evaluableNodeManager.AllocNode(ENT_STRING, cur_entity_sid)); PopulatePerformanceCounters(perf_constraints_ptr, container); diff --git a/src/Amalgam/interpreter/InterpreterOpcodesEntityControl.cpp b/src/Amalgam/interpreter/InterpreterOpcodesEntityControl.cpp index a72a36d5..7b1c298a 100644 --- a/src/Amalgam/interpreter/InterpreterOpcodesEntityControl.cpp +++ b/src/Amalgam/interpreter/InterpreterOpcodesEntityControl.cpp @@ -348,7 +348,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_CREATE_ENTITIES(EvaluableN //get destination if applicable EntityWriteReference entity_container; - StringInternRef new_entity_id; + StringRef new_entity_id; if(i + 1 < ocn.size()) { node_stack.PushEvaluableNode(root); @@ -428,7 +428,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_CLONE_ENTITIES(EvaluableNo //get destination if applicable EntityWriteReference destination_entity_parent; - StringInternRef new_entity_id; + StringRef new_entity_id; if(i + 1 < ocn.size()) std::tie(destination_entity_parent, new_entity_id) = InterpretNodeIntoDestinationEntity(ocn[i + 1]); @@ -504,7 +504,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MOVE_ENTITIES(EvaluableNod //get destination if applicable EntityWriteReference destination_entity_parent; - StringInternRef new_entity_id; + StringRef new_entity_id; if(i + 1 < ocn.size()) std::tie(destination_entity_parent, new_entity_id) = InterpretNodeIntoDestinationEntity(ocn[i + 1]); else @@ -633,7 +633,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_LOAD_ENTITY_and_LOAD_PERSI //get destination if applicable EntityWriteReference destination_entity_parent; - StringInternRef new_entity_id; + StringRef new_entity_id; if(ocn.size() > 1) std::tie(destination_entity_parent, new_entity_id) = InterpretNodeIntoDestinationEntity(ocn[1]); @@ -732,7 +732,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_STORE(EvaluableNode *en, b { auto &mcn = params->GetMappedChildNodesReference(); - auto found_sort_keys = mcn.find(ENBISI_sort_keys); + auto found_sort_keys = mcn.find(GetStringIdFromBuiltInStringId(ENBISI_sort_keys)); if(found_sort_keys != end(mcn)) sort_keys = EvaluableNode::IsTrue(found_sort_keys->second); } @@ -788,15 +788,15 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_STORE_ENTITY(EvaluableNode { auto &mcn = params->GetMappedChildNodesReference(); - auto found_sort_keys = mcn.find(ENBISI_sort_keys); + auto found_sort_keys = mcn.find(GetStringIdFromBuiltInStringId(ENBISI_sort_keys)); if(found_sort_keys != end(mcn)) sort_keys = EvaluableNode::IsTrue(found_sort_keys->second); - auto found_include_rand_seeds = mcn.find(ENBISI_include_rand_seeds); + auto found_include_rand_seeds = mcn.find(GetStringIdFromBuiltInStringId(ENBISI_include_rand_seeds)); if(found_include_rand_seeds != end(mcn)) include_rand_seeds = EvaluableNode::IsTrue(found_include_rand_seeds->second); - auto found_parallel_create = mcn.find(ENBISI_parallel_create); + auto found_parallel_create = mcn.find(GetStringIdFromBuiltInStringId(ENBISI_parallel_create)); if(found_parallel_create != end(mcn)) parallel_create = EvaluableNode::IsTrue(found_parallel_create->second); } diff --git a/src/Amalgam/interpreter/InterpreterOpcodesListManipulation.cpp b/src/Amalgam/interpreter/InterpreterOpcodesListManipulation.cpp index caeca996..8f09c9a6 100644 --- a/src/Amalgam/interpreter/InterpreterOpcodesListManipulation.cpp +++ b/src/Amalgam/interpreter/InterpreterOpcodesListManipulation.cpp @@ -75,7 +75,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_FIRST(EvaluableNode *en, b if(DoesEvaluableNodeTypeUseStringData(list->GetType())) { auto sid = list->GetStringIDReference(); - if(sid <= string_intern_pool.EMPTY_STRING_ID) + if(sid == string_intern_pool.NOT_A_STRING_ID || sid == string_intern_pool.emptyStringId) return AllocReturn(StringInternPool::NOT_A_STRING_ID, immediate_result); std::string s = string_intern_pool.GetStringFromID(sid); @@ -184,7 +184,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_TAIL(EvaluableNode *en, bo if(DoesEvaluableNodeTypeUseStringData(list->GetType())) { auto sid = list->GetStringIDReference(); - if(sid <= string_intern_pool.EMPTY_STRING_ID) + if(sid == string_intern_pool.NOT_A_STRING_ID || sid == string_intern_pool.emptyStringId) return AllocReturn(StringInternPool::NOT_A_STRING_ID, immediate_result); std::string s = string_intern_pool.GetStringFromID(sid); @@ -282,7 +282,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_LAST(EvaluableNode *en, bo if(DoesEvaluableNodeTypeUseStringData(list->GetType())) { auto sid = list->GetStringIDReference(); - if(sid <= string_intern_pool.EMPTY_STRING_ID) + if(sid == string_intern_pool.NOT_A_STRING_ID || sid == string_intern_pool.emptyStringId) return AllocReturn(StringInternPool::NOT_A_STRING_ID, immediate_result); std::string s = string_intern_pool.GetStringFromID(sid); @@ -389,7 +389,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_TRUNC(EvaluableNode *en, b if(DoesEvaluableNodeTypeUseStringData(list->GetType())) { auto sid = list->GetStringIDReference(); - if(sid <= string_intern_pool.EMPTY_STRING_ID) + if(sid == string_intern_pool.NOT_A_STRING_ID || sid == string_intern_pool.emptyStringId) return AllocReturn(StringInternPool::NOT_A_STRING_ID, immediate_result); std::string s = string_intern_pool.GetStringFromID(sid); diff --git a/src/Amalgam/interpreter/InterpreterOpcodesTransformations.cpp b/src/Amalgam/interpreter/InterpreterOpcodesTransformations.cpp index 194f3c51..fceebd6e 100644 --- a/src/Amalgam/interpreter/InterpreterOpcodesTransformations.cpp +++ b/src/Amalgam/interpreter/InterpreterOpcodesTransformations.cpp @@ -1622,7 +1622,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_ZIP(EvaluableNode *en, boo EvaluableNode *index = index_list_ocn[i]; //obtain the index, reusing the sid reference if possible - StringInternPool::StringID index_sid = string_intern_pool.EMPTY_STRING_ID; + StringInternPool::StringID index_sid = string_intern_pool.emptyStringId; if(index_list.unique) index_sid = EvaluableNode::ToStringIDTakingReferenceAndClearing(index); else diff --git a/src/Amalgam/out.txt b/src/Amalgam/out.txt index 01748b3a..312d9410 100644 --- a/src/Amalgam/out.txt +++ b/src/Amalgam/out.txt @@ -235,10 +235,10 @@ notakeyword (print "hello") [(null) (null) .infinity -.infinity] -{c ["alpha" "beta" "gamma"] b 2 a 1} +{b 2 c ["alpha" "beta" "gamma"] a 1} { - c ["alpha" "beta" "gamma"] b 2 + c ["alpha" "beta" "gamma"] a 1 } @@ -631,15 +631,15 @@ a { a 1 b 2 + c 3 d 4 e 5 - f 6 } -{d 4 e 5} +{a 1 e 5} { a 1 b 2 - d 4 + c 3 e 5 } { @@ -682,15 +682,15 @@ c { a 1 b 2 + c 3 d 4 e 5 - f 6 } -{d 4 e 5} +{a 1 e 5} { a 1 b 2 - d 4 + c 3 e 5 } { @@ -1042,7 +1042,7 @@ abcdef [1 3] [9 5] --indices-- -["c" "b" "a" "4"] +["b" "c" "4" "a"] [ 0 1 @@ -1054,7 +1054,7 @@ abcdef 7 ] --values-- -[3 2 1 "d"] +["d" 2 3 1] [ "a" 1 @@ -1075,7 +1075,7 @@ abcdef 4 "d" ] -[3 2 1 0 "d"] +[2 "d" 3 1 0] [ 1 2 @@ -1288,7 +1288,7 @@ current_index: 2 interpreter "C:\\Users\\Chris Hazard\\Desktop\\Howso_repos\\amalgam\\x64\\MT_Release_EXE\\Amalgam.exe" raaa 2 rwww 1 - start_time 1722895304.196965 + start_time 1723141914.850715 www 1 x 12 zz 10 @@ -1331,7 +1331,7 @@ current_index: 2 interpreter "C:\\Users\\Chris Hazard\\Desktop\\Howso_repos\\amalgam\\x64\\MT_Release_EXE\\Amalgam.exe" raaa 2 rwww 1 - start_time 1722895304.196965 + start_time 1723141914.850715 www 1 x 12 zz 10 @@ -1373,7 +1373,7 @@ current_index: 2 interpreter "C:\\Users\\Chris Hazard\\Desktop\\Howso_repos\\amalgam\\x64\\MT_Release_EXE\\Amalgam.exe" raaa 2 rwww 1 - start_time 1722895304.196965 + start_time 1723141914.850715 www 1 x 12 zz 10 @@ -1513,15 +1513,15 @@ a ["b" @(get (target 2) 0) @(get (target 2) 0) @(get (target 2) 0)] -infinity test c or d: ["d" "d" "d" "c"] +infinity test c or d: ["c" "c" "c" "d"] infinity test c or d: ["d" @(get (target 2) 0) "c" @(get (target 2) 2)] -{a 25 b 47 c 28} +{a 25 b 48 c 27} {a 24 b 52 c 24} -["4" "2" "3"] +["5" "2" "1"] --get_rand_seed-- N9˝UOaVT z @@ -1616,17 +1616,17 @@ string {a 3 b 4} {c "c"} ] -21: [{"b":4,"a":3},{"c":"c","d":null}] +21: [{"b":4,"a":3},{"d":null,"c":"c"}] 22: [{"a":3,"b":4},{"c":"c","d":null}] -23: c: 3 +23: d: 4 b: 2 +c: 3 a: 1 e: - a - b - - .inf -d: 4 24: a: 1 b: 2 @@ -1639,7 +1639,7 @@ e: - .inf 25: {a 1} -current date-time in epoch: 2024-08-05-18.01.44.7864540 +current date-time in epoch: 2024-08-08-14.31.55.2530610 2020-06-07 00:22:59 1391230800 1391230800 @@ -2179,16 +2179,6 @@ decrypted: hello {_ (null)} (replace _ - [] - (lambda - { - a 2 - g (get - (current_value 1) - "g" - ) - } - ) ["g"] (lambda [ @@ -2199,6 +2189,16 @@ decrypted: hello 4 ] ) + [] + (lambda + { + a 2 + g (get + (current_value 1) + "g" + ) + } + ) ) ) (declare @@ -2604,7 +2604,7 @@ flatten restore without seeds test (assign_entity_roots new_entity _) ) ) - (set_entity_rand_seed new_entity "1]*|#") + (set_entity_rand_seed new_entity "{'IC") (set_entity_rand_seed (first (create_entities @@ -2616,7 +2616,7 @@ flatten restore without seeds test ) ) ) - "K2aY" + "5z^\rF/VQ" ) new_entity ) @@ -2739,25 +2739,25 @@ flatten restore with parallel (get) (create_entities) 14 - (associate "a" 1 "b" (call_sandboxed)) + 6.443652046342577 ] [ 1 2 3 + 4 (-) - 5 6 + 7 (*) (*) - 9 + 10 (+) - 11 12 + 13 (+) - (+) - (associate "a" 1 "b" (+)) + (associate (+) 1 (*) 2) ] --commonality_entities-- @@ -2817,26 +2817,26 @@ _2169689611 ##p ["_3990396532" "_3990396532" "_3330773578" "_3330773578"] ) -_3330773578 +_3990396532 (associate - "e" + "E" 3 - "f" + "F" 4 - "g" + "G" 5 - "h" + "H" 6 ) -_3990396532 +_3330773578 (associate - "E" + "e" 3 - "F" + "f" 4 - "G" + "g" 5 - "H" + "h" 6 ) --difference_entities-- @@ -3167,8 +3167,14 @@ _432807187 [] (lambda { - E 3 - F 4 + E (get + (current_value 1) + "E" + ) + F (get + (current_value 1) + "F" + ) G 5 H 6 } @@ -3193,7 +3199,16 @@ _432807187 _ [] (lambda - {e 3 f 4} + { + e (get + (current_value 1) + "e" + ) + f (get + (current_value 1) + "f" + ) + } ) ) ) @@ -3225,7 +3240,89 @@ contained_entities new_entity: ["DiffEntityChild1" "OnlyIn2" "_350925375" "_2742 difference between DiffEntity2 and new_entity: (declare {_ (null) new_entity (null)} - (clone_entities _ new_entity) + (assign + "new_entity" + (first + (create_entities + new_entity + (call + (lambda + (declare + {_ (null)} + (replace _) + ) + ) + { + _ (retrieve_entity_root _) + } + ) + ) + ) + ) + (create_entities + (append new_entity "_350925375") + (call + (lambda + (declare + {_ (null)} + (replace + _ + [] + (lambda + { + E (null) + F (null) + G (get + (current_value 1) + "G" + ) + H (get + (current_value 1) + "H" + ) + } + ) + ) + ) + ) + { + _ (retrieve_entity_root + (append _ "_350925375") + ) + } + ) + ) + (create_entities + (append new_entity "_2742810479") + (call + (lambda + (declare + {_ (null)} + (replace + _ + [] + (lambda + {e (null) f (null)} + ) + ) + ) + ) + { + _ (retrieve_entity_root + (append _ "_2742810479") + ) + } + ) + ) + (clone_entities + (append _ "DiffEntityChild1") + (append new_entity "DiffEntityChild1") + ) + (clone_entities + (append _ "OnlyIn2") + (append new_entity "OnlyIn2") + ) + new_entity ) (declare {_ (null) new_entity (null)} @@ -3293,8 +3390,14 @@ difference between DiffEntity2 and new_entity: [] (lambda { - E 3 - F 4 + E (get + (current_value 1) + "E" + ) + F (get + (current_value 1) + "F" + ) G 5 H 6 } @@ -3319,7 +3422,16 @@ difference between DiffEntity2 and new_entity: _ [] (lambda - {e 3 f 4} + { + e (get + (current_value 1) + "e" + ) + f (get + (current_value 1) + "f" + ) + } ) ) ) @@ -3345,27 +3457,100 @@ contained_entities new_entity: ["OnlyIn2" "_3631850880" "_1938178219" "DiffEntit difference between DiffContainer and DiffEntity2: (declare {_ (null) new_entity (null)} - (clone_entities _ new_entity) + (assign + "new_entity" + (first + (create_entities + new_entity + (call + (lambda + (declare + {_ (null)} + (replace _) + ) + ) + { + _ (retrieve_entity_root _) + } + ) + ) + ) + ) + (create_entities + (append new_entity "_3631850880") + (call + (lambda + (declare + {_ (null)} + (replace + _ + [] + (lambda + { + E (null) + F (null) + G (get + (current_value 1) + "G" + ) + H (get + (current_value 1) + "H" + ) + } + ) + ) + ) + ) + { + _ (retrieve_entity_root + (append _ "_3631850880") + ) + } + ) + ) + (create_entities + (append new_entity "_1938178219") + (call + (lambda + (declare + {_ (null)} + (replace + _ + [] + (lambda + {e (null) f (null)} + ) + ) + ) + ) + { + _ (retrieve_entity_root + (append _ "_1938178219") + ) + } + ) + ) + (clone_entities + (append _ "OnlyIn2") + (append new_entity "OnlyIn2") + ) + (clone_entities + (append _ "DiffEntityChild1") + (append new_entity "DiffEntityChild1") + ) + new_entity ) --mix_entities-- -(associate "b" 4 "a" 3 "c" 3) +(associate "b" 4 "c" 3) MergeEntityChild1 -(associate "x" 3 "y" 4 "z" 5) +(associate "x" 3 "y" 4) MergeEntityChild2 -(associate - "p" - 3 - "q" - 4 - "v" - 6 - "w" - 7 -) +(associate "p" 3 "q" 4 "w" 7) _2280722175 (associate "E" 3 "F" 4 "H" 6) _2169689611 -(associate "e" 3 "f" 4 "g" 5) +(associate "e" 3 "f" 4 "h" 6) --get_entity_comments-- Full test This is a suite of unit tests. @@ -3443,7 +3628,7 @@ deep sets --set_entity_root_permission-- RootTest -1722895305.104673 +1723141915.486801 (true) RootTest @@ -3846,65 +4031,65 @@ store to .json normally ["Child2" "Child7"] ["Child1" "Child5"] ["Child3" "Child4"] +["Child1" "Child5" "Child6" "Child7"] ["Child3" "Child4" "Child6" "Child7"] -["Child1" "Child3" "Child6" "Child7"] ["Child4" "Child6"] --query_sample-- +["Child3"] +["Child6" "Child1"] ["Child6"] -["Child3" "Child1"] -["Child5"] ["Child4"] --query_weighted_sample-- -["Child2"] -["Child2"] +["Child1"] +["Child1"] [ "Child2" "Child1" - "Child2" - "Child1" - "Child3" - "Child1" - "Child1" "Child1" "Child1" "Child1" "Child2" - "Child1" - "Child1" + "Child2" "Child1" "Child2" + "Child1" "Child2" "Child2" "Child2" "Child1" + "Child2" "Child3" + "Child2" + "Child2" + "Child2" + "Child2" ] [ - "Child2" - "Child1" "Child2" "Child2" - "Child5" - "Child4" "Child1" - "Child5" "Child1" "Child1" + "Child2" "Child1" "Child2" + "Child2" + "Child2" + "Child1" "Child1" "Child2" - "Child3" "Child1" "Child1" - "Child5" "Child2" "Child2" + "Child1" + "Child6" + "Child1" ] [ - "Child5" - "Child7" - "Child6" + "Child2" + "Child2" + "Child2" "Child2" "Child2" "Child2" @@ -3913,7 +4098,7 @@ store to .json normally "Child2" "Child2" ] -["Child2"] +["Child2" "Child5"] --query_in_entity_list-- ["Child6" "Child7"] --query_not_in_entity_list-- @@ -3961,7 +4146,7 @@ cascading query_not_in_entity_list: ["Child6" "Child7"] unweighted query: { Child1 4 Child2 1 - Child4 100 + Child3 100 Child6 2 Child7 10 } @@ -3973,7 +4158,7 @@ weighted query: { Child7 0.2 } weighted query list of lists: [ - ["Child6" "Child7" "Child2" "Child1" "Child4"] + ["Child6" "Child7" "Child2" "Child1" "Child3"] [0.04 0.2 0.45 1.8 2] ] weighted query list of lists: [ @@ -3982,7 +4167,7 @@ weighted query list of lists: [ [-1 2 4 10 100] ] weighted query list of lists with multiple values: [ - ["Child2" "Child6" "Child1" "Child7" "Child3"] + ["Child2" "Child6" "Child1" "Child7" "Child4"] [1 2 4 10 100] [-1 2 4 10 100] [-1 1 3 0 100] @@ -4282,15 +4467,15 @@ case conviction:{ } cyclic feature nearest neighbors: {cyclic1 1 cyclic5 0.5} cyclic test expected: 155, 200, 190 ... deg values of 0 8 and 12: +155: 0.1 (null + ##deg 0 +) 200: 0.05555555555555555 (null ##deg 8 ) 190: 0.045454545454545456 (null ##deg 12 ) -155: 0.1 (null - ##deg 0 -) --contains_label-- (true) @@ -4565,13 +4750,13 @@ distance symmetry tests [ [ "B" - "C" - "D" - "A" "F" + "C" "I" - "J" + "A" + "D" "H" + "E" ] [ 0 @@ -4587,13 +4772,13 @@ distance symmetry tests [ [ "B" - "A" - "D" - "I" "C" + "D" + "A" "F" - "G" + "I" "J" + "E" ] [ 0 @@ -4787,4 +4972,4 @@ concurrent entity writes successful: (true) --clean-up test files-- --total execution time-- -1.6452000141143799 +1.5147020816802979 diff --git a/src/Amalgam/string/StringInternPool.h b/src/Amalgam/string/StringInternPool.h index 3ccd239c..0c714b04 100644 --- a/src/Amalgam/string/StringInternPool.h +++ b/src/Amalgam/string/StringInternPool.h @@ -7,28 +7,51 @@ #include "StringManipulation.h" //system headers: +#include #include #include #include +//if STRING_INTERN_POOL_VALIDATION is defined, it will validate +//every string reference, at the cost of performance + +class StringInternStringData +{ +public: + inline StringInternStringData() + : refCount(0), string() + { } + + inline StringInternStringData(const std::string &string) + : refCount(1), string(string) + { } + +#if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) + std::atomic refCount; +#else + int64_t refCount; +#endif + std::string string; +}; + +class StringInternPool; +extern StringInternPool string_intern_pool; + //manages all strings so they can be referred and compared easily by integers, across threads //depends on a method defined outside of this class, StringInternPool::InitializeStaticStrings() -// to set up all internal static strings; see the function's declaration for details +// to set up all internal strings; see the function's declaration for details //additionally StringInternPool string_intern_pool; should be defined elsewhere // if a global intern pool is desired class StringInternPool { public: - using StringID = size_t; - using StringToStringIDAssoc = FastHashMap; - - //indicates that it is not a string, like NaN or null - static constexpr size_t NOT_A_STRING_ID = 0; - static constexpr size_t EMPTY_STRING_ID = 1; - inline static const std::string EMPTY_STRING = std::string(""); + using StringID = StringInternStringData *; inline StringInternPool() { + //create the empty string first + auto inserted = stringToID.emplace("", std::make_unique("")); + emptyStringId = inserted.first->second.get(); InitializeStaticStrings(); } @@ -37,11 +60,14 @@ class StringInternPool //may invalidate the location, so a copy must be made to return the value inline const std::string GetStringFromID(StringID id) { - #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) - Concurrency::ReadLock lock(sharedMutex); + if(id == NOT_A_STRING_ID) + return EMPTY_STRING; + + #ifdef STRING_INTERN_POOL_VALIDATION + ValidateStringIdExistance(id); #endif - return idToStringAndRefCount[id].first; + return id->string; } //translates the string to the corresponding ID, 0 is the empty string, maximum value of size_t means it does not exist @@ -55,63 +81,47 @@ class StringInternPool if(id_iter == end(stringToID)) return NOT_A_STRING_ID; //the string was never entered in and don't want to cause more errors - return id_iter->second; + StringID id = id_iter->second.get(); + #ifdef STRING_INTERN_POOL_VALIDATION + ValidateStringIdExistanceUnderLock(id); + #endif + return id; } //makes a new reference to the string specified, returning the ID inline StringID CreateStringReference(const std::string &str) { - if(str.size() == 0) - return EMPTY_STRING_ID; + if(str == "") + return emptyStringId; #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) Concurrency::WriteLock lock(sharedMutex); #endif //try to insert it as a new string - auto [inserted_id, inserted] = stringToID.insert(std::make_pair(str, 0)); - if(inserted) - { - StringID id; - //new string, see if any ids are ready for reuse - if(unusedIDs.size() > 0) - { - //reuse existing, so overwrite it - id = unusedIDs.top(); - unusedIDs.pop(); - idToStringAndRefCount[id] = std::make_pair(str, 1); - } - else //need a new one - { - id = idToStringAndRefCount.size(); - idToStringAndRefCount.emplace_back(std::make_pair(str, 1)); - } - - //store the id along with the string - inserted_id->second = id; - - return id; - } - - //found, so count the reference if applicable - StringID id = inserted_id->second; - if(!IsStringIDStatic(id)) - idToStringAndRefCount[id].second++; + auto inserted = stringToID.emplace(str, nullptr); + if(inserted.second) + inserted.first->second = std::make_unique(str); + else + inserted.first->second->refCount++; + + StringID id = inserted.first->second.get(); + #ifdef STRING_INTERN_POOL_VALIDATION + ValidateStringIdExistanceUnderLock(id); + #endif return id; } //makes a new reference to the string id specified, returning the id passed in inline StringID CreateStringReference(StringID id) { - if(!IsStringIDStatic(id)) + if(id != NOT_A_STRING_ID) { - #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) - //only need a ReadLock because the count is atomic - Concurrency::ReadLock lock(sharedMutex); + #ifdef STRING_INTERN_POOL_VALIDATION + ValidateStringIdExistance(id); #endif - IncrementRefCount(id); + id->refCount++; } - return id; } @@ -121,21 +131,16 @@ class StringInternPool inline void CreateStringReferences(ReferencesContainer &references_container, GetStringIdFunction get_string_id = [](auto sid) { return sid; }) { - if(references_container.size() == 0) - return; - - #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) - //only need a ReadLock because the count is atomic - Concurrency::ReadLock lock(sharedMutex); - #endif - for(auto r : references_container) { StringID id = get_string_id(r); - if(IsStringIDStatic(id)) - continue; - - IncrementRefCount(id); + if(id != NOT_A_STRING_ID) + { + #ifdef STRING_INTERN_POOL_VALIDATION + ValidateStringIdExistance(id); + #endif + id->refCount++; + } } } @@ -147,21 +152,16 @@ class StringInternPool size_t additional_reference_count, GetStringIdFunction get_string_id = [](auto sid) { return sid; }) { - if(references_container.size() == 0) - return; - - #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) - //only need a ReadLock because the count is atomic - Concurrency::ReadLock lock(sharedMutex); - #endif - for(auto r : references_container) { StringID id = get_string_id(r); - if(IsStringIDStatic(id)) - continue; - - AdvanceRefCount(id, additional_reference_count); + if(id != NOT_A_STRING_ID) + { + #ifdef STRING_INTERN_POOL_VALIDATION + ValidateStringIdExistance(id); + #endif + id->refCount += additional_reference_count; + } } } @@ -172,28 +172,23 @@ class StringInternPool inline void CreateStringReferencesByIndex(ReferencesContainer &references_container, GetStringIdFunction get_string_id = [](auto sid) { return sid; }) { - if(references_container.size() == 0) - return; - - #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) - //only need a ReadLock because the count is atomic - Concurrency::ReadLock lock(sharedMutex); - #endif - for(size_t i = 0; i < references_container.size(); i++) { StringID id = get_string_id(references_container[i], i); - if(IsStringIDStatic(id)) - continue; - - IncrementRefCount(id); + if(id != NOT_A_STRING_ID) + { + #ifdef STRING_INTERN_POOL_VALIDATION + ValidateStringIdExistance(id); + #endif + id->refCount++; + } } } //removes a reference to the string specified by the ID inline void DestroyStringReference(StringID id) { - if(IsStringIDStatic(id)) + if(id == NOT_A_STRING_ID || id == emptyStringId) return; //get the reference count before decrement @@ -202,7 +197,11 @@ class StringInternPool Concurrency::ReadLock lock(sharedMutex); #endif - int64_t refcount = DecrementRefCount(id); + #ifdef STRING_INTERN_POOL_VALIDATION + ValidateStringIdExistanceUnderLock(id); + #endif + + int64_t refcount = id->refCount--; //if other references, then can't clear it; signed, so it won't wrap around if(refcount > 1) @@ -211,21 +210,21 @@ class StringInternPool #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) //this thread is about to free the reference, but need to acquire a write lock // so, keep the reference alive by incrementing it *before* attempting the write lock - IncrementRefCount(id); + id->refCount++; //grab a write lock lock.unlock(); Concurrency::WriteLock write_lock(sharedMutex); //with the write lock, decrement reference count in case this string should stay active - refcount = DecrementRefCount(id); + refcount = id->refCount--; //if other references, then can't clear it if(refcount > 1) return; #endif - RemoveId(id); + stringToID.erase(id->string); } @@ -243,7 +242,7 @@ class StringInternPool return; //as it goes through, if any id needs removal, will set this to true so that - // removal can be done after refernce count decreases are done + // removal can be done after reference count decreases are done bool ids_need_removal = false; //only need a ReadLock because the count is atomic @@ -252,10 +251,14 @@ class StringInternPool for(auto r : references_container) { StringID id = get_string_id(r); - if(IsStringIDStatic(id)) + if(id == NOT_A_STRING_ID || id == emptyStringId) continue; - int64_t refcount = DecrementRefCount(id); + #ifdef STRING_INTERN_POOL_VALIDATION + ValidateStringIdExistanceUnderLock(id); + #endif + + int64_t refcount = id->refCount--; //if extra references, just return, but if it is 1, then it will try to clear if(refcount <= 1) @@ -269,8 +272,8 @@ class StringInternPool for(auto r : references_container) { StringID id = get_string_id(r); - if(!IsStringIDStatic(id)) - IncrementRefCount(id); + if(id != NOT_A_STRING_ID && id != emptyStringId) + id->refCount++; } //grab a write lock @@ -280,13 +283,18 @@ class StringInternPool for(auto r : references_container) { StringID id = get_string_id(r); - if(IsStringIDStatic(id)) + if(id == NOT_A_STRING_ID || id == emptyStringId) continue; + #ifdef STRING_INTERN_POOL_VALIDATION + ValidateStringIdExistanceUnderLock(id); + #endif + //remove any that are the last reference - int64_t refcount = DecrementRefCount(id); + int64_t refcount = id->refCount--; + if(refcount <= 1) - RemoveId(id); + stringToID.erase(id->string); } #endif @@ -295,29 +303,12 @@ class StringInternPool //destroys 2 StringReferences inline void DestroyStringReferences(StringID sid_1, StringID sid_2) { - //skip overhead if possible - bool sid_1_static = IsStringIDStatic(sid_1); - bool sid_2_static = IsStringIDStatic(sid_2); - if(sid_1_static || sid_2_static) - { - //if both are static, exit - if(sid_1_static && sid_2_static) - return; - - //one is static, destroy the other - if(sid_1_static) - DestroyStringReference(sid_2); - else - DestroyStringReference(sid_1); - return; - } - std::array string_ids = { sid_1, sid_2 }; DestroyStringReferences(string_ids); } //returns the number of strings that are still allocated - //even when "empty" it will still return 2 since the NOT_A_STRING_ID and EMPTY_STRING_ID take up slots + //even when "empty" it will still return 2 since the NOT_A_STRING_ID and emptyStringId take up slots inline size_t GetNumStringsInUse() { #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) @@ -327,202 +318,168 @@ class StringInternPool return stringToID.size(); } - //returns the number of non-static strings that are still in use - size_t GetNumDynamicStringsInUse() + //returns the number of strings that are still in use + inline size_t GetNumDynamicStringsInUse() { #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) Concurrency::ReadLock lock(sharedMutex); #endif - size_t count = 0; - for(const auto &it : stringToID) - { - if(!IsStringIDStatic(it.second)) - count++; - } - return count; - } - - //returns the number of non-static string references that are currently in use - int64_t GetNumNonStaticStringReferencesInUse() - { - #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) - Concurrency::ReadLock lock(sharedMutex); - #endif - - int64_t count = 0; - for(size_t id = 0; id < idToStringAndRefCount.size(); id++) - { - if(!IsStringIDStatic(id)) - count += idToStringAndRefCount[id].second; - } - return count; + return stringToID.size() - staticStringIDToIndex.size(); } //returns a vector of all the strings still in use. Intended for debugging. - std::vector> GetNonStaticStringsInUse() + inline std::vector> GetDynamicStringsInUse() { #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) Concurrency::ReadLock lock(sharedMutex); #endif std::vector> in_use; - for(size_t id = 0; id < idToStringAndRefCount.size(); id++) + for(auto &[str, sisd] : stringToID) { - if(!IsStringIDStatic(id) && idToStringAndRefCount[id].second > 0) - in_use.emplace_back(idToStringAndRefCount[id].first, idToStringAndRefCount[id].second); + StringID sid(sisd.get()); + if(staticStringIDToIndex.find(sid) == end(staticStringIDToIndex)) + in_use.emplace_back(str, sisd->refCount); } - return in_use; - } - //returns true if the string associated with stringID id is a static string - constexpr bool IsStringIDStatic(StringID id) - { - return id < numStaticStrings; //static strings must begin at id 0, so numStaticStrings represents the first string id that is not static + return in_use; } -protected: - - //increments the reference count and returns the previous reference count - inline int64_t IncrementRefCount(StringID id) + //validates the string id, throwing an assert if it is not valid + inline void ValidateStringIdExistance(StringID sid) { #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) - //perform an atomic increment so that it can be done under a read lock - //TODO 15993: once C++20 is widely supported, change type to atomic_ref - return reinterpret_cast&>(idToStringAndRefCount[id].second).fetch_add(1); - #else - return idToStringAndRefCount[id].second++; + Concurrency::ReadLock lock(sharedMutex); #endif + ValidateStringIdExistanceUnderLock(sid); } - //adds advancement to the reference count - inline void AdvanceRefCount(StringID id, size_t advancement) - { - #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) - //perform an atomic increment so that it can be done under a read lock - //TODO 15993: once C++20 is widely supported, change type to atomic_ref - reinterpret_cast&>(idToStringAndRefCount[id].second).fetch_add(advancement); - #else - idToStringAndRefCount[id].second += advancement; - #endif - } +protected: - //decrements the reference count and returns the previous reference count - inline int64_t DecrementRefCount(StringID id) + //validates the string id, throwing an assert if it is not valid + //requires being under a lock + inline void ValidateStringIdExistanceUnderLock(StringID sid) { - #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) - //perform an atomic decrement so that it can be done under a read lock - //TODO 15993: once C++20 is widely supported, change type to atomic_ref - return reinterpret_cast&>(idToStringAndRefCount[id].second).fetch_sub(1); - #else - return idToStringAndRefCount[id].second--; - #endif - } + if(sid == NOT_A_STRING_ID) + return; - //removes everything associated with the id - inline void RemoveId(StringID id) - { - //removed last reference; clear the string and free memory - stringToID.erase(idToStringAndRefCount[id].first); - idToStringAndRefCount[id].first = ""; - idToStringAndRefCount[id].first.shrink_to_fit(); - unusedIDs.push(id); + auto found = stringToID.find(sid->string); + if(found == end(stringToID)) + { + assert(false); + return; + } + + StringID found_sid = found->second.get(); + if(sid != found_sid) + { + assert(false); + } } //must be defined outside of this class and initialize all static strings - //needs to set numStaticStrings and call EmplaceStaticString for each StringID from 0 up to numStaticStrings - // with the respective string - //the first two strings MUST be not-a-string followed by empty string void InitializeStaticStrings(); - //sets string id sid to str, assuming the position has already been allocated in idToStringAndRefCount - inline void EmplaceStaticString(StringID sid, const char *str) - { - idToStringAndRefCount[sid] = std::make_pair(str, 0); - stringToID.emplace(str, sid); - } - #if defined(MULTITHREAD_SUPPORT) || defined(MULTITHREAD_INTERFACE) Concurrency::ReadWriteMutex sharedMutex; #endif - //mapping from ID (index) to the string and the number of references - //use a signed counter in case it goes negative such that comparisons work well even if multiple threads have freed it - std::vector> idToStringAndRefCount; - - //mapping from string to ID (index of idToStringAndRefCount) - StringToStringIDAssoc stringToID; + //mapping from string to ID (index of idToRefCountAndString) + FastHashMap> stringToID; - //IDs (indexes of idToStringAndRefCount) that are now unused - std::priority_queue, std::greater > unusedIDs; +public: + //indicates that it is not a string, like NaN or null + static constexpr StringID NOT_A_STRING_ID = nullptr; + StringID emptyStringId; + inline static const std::string EMPTY_STRING = std::string(""); - //number of static strings - size_t numStaticStrings; + //data structures for static strings + std::vector staticStringsIndexToStringID; + FastHashMap staticStringIDToIndex; }; -extern StringInternPool string_intern_pool; - //A reference to a string //maintains reference counts and will clear upon destruction -class StringInternRef +class StringRef { public: - constexpr StringInternRef() : id(StringInternPool::NOT_A_STRING_ID) + inline StringRef() + : id(StringInternPool::NOT_A_STRING_ID) { } - inline StringInternRef(StringInternPool::StringID sid) + inline StringRef(StringInternPool::StringID sid) { + #ifdef STRING_INTERN_POOL_VALIDATION + string_intern_pool.ValidateStringIdExistance(sid); + #endif id = string_intern_pool.CreateStringReference(sid); } - inline StringInternRef(const std::string &str) + inline StringRef(std::string &str) { id = string_intern_pool.CreateStringReference(str); + #ifdef STRING_INTERN_POOL_VALIDATION + string_intern_pool.ValidateStringIdExistance(id); + #endif } //copy constructor - inline StringInternRef(const StringInternRef &sir) + inline StringRef(const StringRef &sir) { id = string_intern_pool.CreateStringReference(sir.id); + #ifdef STRING_INTERN_POOL_VALIDATION + string_intern_pool.ValidateStringIdExistance(id); + #endif + } + + //move constructor + inline StringRef(StringRef &&sir) + { + id = sir.id; + #ifdef STRING_INTERN_POOL_VALIDATION + string_intern_pool.ValidateStringIdExistance(id); + #endif + sir.id = nullptr; } - inline ~StringInternRef() + inline ~StringRef() { string_intern_pool.DestroyStringReference(id); } inline void Clear() { - if(id != StringInternPool::NOT_A_STRING_ID) - { - string_intern_pool.DestroyStringReference(id); - id = StringInternPool::NOT_A_STRING_ID; - } + string_intern_pool.DestroyStringReference(id); + id = StringInternPool::NOT_A_STRING_ID; } //easy-to-read way of creating an empty string - inline static StringInternRef EmptyString() - { return StringInternRef(); } + inline static StringRef EmptyString() + { return StringRef(); } //assign another string reference - inline StringInternRef &operator =(const StringInternRef &sir) + inline StringRef &operator =(const StringRef &sir) { if(id != sir.id) { string_intern_pool.DestroyStringReference(id); id = string_intern_pool.CreateStringReference(sir.id); + #ifdef STRING_INTERN_POOL_VALIDATION + string_intern_pool.ValidateStringIdExistance(id); + #endif } return *this; } //allow being able to use as a string - inline operator const std::string () + inline operator const std::string() { return string_intern_pool.GetStringFromID(id); } //allow being able to use as a string id - constexpr operator StringInternPool::StringID() + inline operator StringInternPool::StringID() { return id; } @@ -530,8 +487,12 @@ class StringInternRef //call this to set the id and create a reference inline void SetIDAndCreateReference(StringInternPool::StringID sid) { + #ifdef STRING_INTERN_POOL_VALIDATION + string_intern_pool.ValidateStringIdExistance(sid); + #endif + //if changing id, need to delete previous - if(id > string_intern_pool.EMPTY_STRING_ID && id != sid) + if(id != sid) string_intern_pool.DestroyStringReference(id); if(id != sid) @@ -544,65 +505,15 @@ class StringInternRef //only call this when the sid already has a reference and this is being used to manage it inline void SetIDWithReferenceHandoff(StringInternPool::StringID sid) { - if(id > string_intern_pool.EMPTY_STRING_ID) - { - //if the ids are different, then need to delete old - //if the ids are the same, then have a duplicate reference, so need to delete one - //so delete a reference either way - string_intern_pool.DestroyStringReference(id); - } - - id = sid; - } - -private: - - StringInternPool::StringID id; -}; - -//A weak reference to a string -// When the string does not exist, it will take on the value of the empty string -class StringInternWeakRef -{ -public: - constexpr StringInternWeakRef() - : id(StringInternPool::NOT_A_STRING_ID) - { } - - constexpr StringInternWeakRef(StringInternPool::StringID sid) - : id(sid) - { } - - StringInternWeakRef(const std::string &str) - { - id = string_intern_pool.GetIDFromString(str); - } - - constexpr StringInternWeakRef(const StringInternWeakRef &siwr) - : id(siwr.id) - { } - - //easy-to-read way of creating an empty string - inline static StringInternRef EmptyString() - { - return StringInternRef(); - } - - //allow being able to use as a string - inline operator const std::string () - { - return string_intern_pool.GetStringFromID(id); - } - - //allow being able to use as a string id - constexpr operator StringInternPool::StringID() - { - return id; - } + #ifdef STRING_INTERN_POOL_VALIDATION + string_intern_pool.ValidateStringIdExistance(sid); + #endif + + //if the ids are different, then need to delete old + //if the ids are the same, then have a duplicate reference, so need to delete one + //so delete a reference either way + string_intern_pool.DestroyStringReference(id); - //only call this when the sid already has a reference and this is being used to manage it - constexpr void SetID(StringInternPool::StringID sid) - { id = sid; }