Skip to content

Commit

Permalink
18575: Reduces memory and storage overhead from saving and loading en…
Browse files Browse the repository at this point in the history
…tities, also reduces lock contention from string ids and minor overhead reduction from parsing (#37)
  • Loading branch information
howsohazard authored Dec 2, 2023
1 parent 5dd04a8 commit 54704d5
Show file tree
Hide file tree
Showing 14 changed files with 122 additions and 208 deletions.
14 changes: 7 additions & 7 deletions src/Amalgam/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,14 +376,14 @@ void Parser::SkipToEndOfIdentifier(bool allow_leading_label_marks)
while(pos < code->size())
{
auto cur_char = code->at(pos);
if(!std::isspace(static_cast<unsigned char>(cur_char))
&& cur_char != ')'
&& cur_char != '('
&& cur_char != '#'
&& cur_char != ';')
pos++;
else
if(cur_char == '\t' || cur_char == '\n' || cur_char == '\v' || cur_char == '\f'
|| cur_char == '\r' || cur_char == ' '
|| cur_char == '#'
|| cur_char == '(' || cur_char == ')'
|| cur_char == ';')
break;

pos++;
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Amalgam/entity/EntityManipulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ EvaluableNodeReference EntityManipulation::DifferenceEntities(Interpreter *inter
// (call *entity difference code*
// (assoc _ (get_entity_code (append new_entity *relative id*)) )
// )
EvaluableNode *src_id_list = GetTraversalIDPathListFromAToB(enm, entity2, entity_to_create);
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(src_id_list);
Expand Down Expand Up @@ -383,7 +383,7 @@ EvaluableNodeReference EntityManipulation::DifferenceEntities(Interpreter *inter
EvaluableNode *clone_entity = enm->AllocNode(ENT_CLONE_ENTITIES);
let_new_entity->AppendOrderedChildNode(clone_entity);

EvaluableNode *src_id_list = GetTraversalIDPathListFromAToB(enm, entity2, entity_to_clone);
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(src_id_list);
Expand Down Expand Up @@ -750,7 +750,7 @@ EvaluableNodeReference EntityManipulation::FlattenEntity(Interpreter *interprete
// )
EvaluableNode *create_entity = enm->AllocNode(ENT_CREATE_ENTITIES);

EvaluableNode *src_id_list = GetTraversalIDPathListFromAToB(enm, entity, cur_entity);
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(src_id_list);
Expand Down
2 changes: 1 addition & 1 deletion src/Amalgam/entity/EntityWriteListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ EvaluableNode *EntityWriteListener::BuildNewWriteOperation(EvaluableNodeType ass

if(target_entity != listeningEntity)
{
EvaluableNode *id_list = GetTraversalIDPathListFromAToB(&listenerStorage, listeningEntity, target_entity);
EvaluableNode *id_list = GetTraversalIDPathFromAToB(&listenerStorage, listeningEntity, target_entity);
new_write->AppendOrderedChildNode(id_list);
}

Expand Down
7 changes: 2 additions & 5 deletions src/Amalgam/evaluablenode/EvaluableNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1589,8 +1589,7 @@ void EvaluableNode::DestructValue()
break;
case ENT_STRING:
case ENT_SYMBOL:
string_intern_pool.DestroyStringReference(value.stringValueContainer.stringID);
string_intern_pool.DestroyStringReference(value.stringValueContainer.labelStringID);
string_intern_pool.DestroyStringReferences(value.stringValueContainer.stringID, value.stringValueContainer.labelStringID);
break;
case ENT_ASSOC:
value.DestructMappedChildNodes();
Expand Down Expand Up @@ -1636,8 +1635,7 @@ void EvaluableNode::Invalidate()
break;
case ENT_STRING:
case ENT_SYMBOL:
string_intern_pool.DestroyStringReference(value.stringValueContainer.stringID);
string_intern_pool.DestroyStringReference(value.stringValueContainer.labelStringID);
string_intern_pool.DestroyStringReferences(value.stringValueContainer.stringID, value.stringValueContainer.labelStringID);
break;
case ENT_ASSOC:
value.DestructMappedChildNodes();
Expand Down Expand Up @@ -1676,7 +1674,6 @@ void EvaluableNode::Invalidate()

//delete extended if haven't returned yet
string_intern_pool.DestroyStringReferences(value.extension.extendedValue->labelsStringIds);

string_intern_pool.DestroyStringReference(value.extension.commentsStringId);

delete value.extension.extendedValue;
Expand Down
4 changes: 2 additions & 2 deletions src/Amalgam/evaluablenode/EvaluableNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ union EvaluableNodeImmediateValue
}

//copies the value from en and returns the EvaluableNodeConcreteValueType
EvaluableNodeImmediateValueType CopyValueFromEvaluableNode(EvaluableNode *en)
inline EvaluableNodeImmediateValueType CopyValueFromEvaluableNode(EvaluableNode *en)
{
if(en == nullptr)
{
Expand Down Expand Up @@ -1007,7 +1007,7 @@ union EvaluableNodeImmediateValue
}

//returns true if it is a null or null equivalent
static bool IsNullEquivalent(EvaluableNodeImmediateValueType type, EvaluableNodeImmediateValue &value)
static constexpr bool IsNullEquivalent(EvaluableNodeImmediateValueType type, EvaluableNodeImmediateValue &value)
{
return (type == ENIVT_NULL
|| (type == ENIVT_NUMBER && FastIsNaN(value.number))
Expand Down
10 changes: 9 additions & 1 deletion src/Amalgam/evaluablenode/EvaluableNodeTreeFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,16 @@ void TraverseEntityToNewDestinationViaEvaluableNodeIDPath(Entity *container, Eva
destination_entity_parent = container;
}

EvaluableNode *GetTraversalIDPathListFromAToB(EvaluableNodeManager *enm, Entity *a, Entity *b)
EvaluableNode *GetTraversalIDPathFromAToB(EvaluableNodeManager *enm, Entity *a, Entity *b)
{
//shouldn't happen, but check
if(b == nullptr)
return nullptr;

//if immediate entity, can return a string instead of a list
if(b->GetContainer() == a)
return enm->AllocNode(ENT_STRING, b->GetIdStringId());

//create list to address entity
EvaluableNode *id_list = enm->AllocNode(ENT_LIST);
auto &ocn = id_list->GetOrderedChildNodes();
Expand Down
8 changes: 4 additions & 4 deletions src/Amalgam/evaluablenode/EvaluableNodeTreeFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class CustomEvaluableNodeComparator
//returns a newly sorted list
std::vector<EvaluableNode *> CustomEvaluableNodeOrderedChildNodesSort(std::vector<EvaluableNode *> &list, CustomEvaluableNodeComparator &cenc);

//Starts at the container specified and traverses the id list specified, finding the relative Entity from container
//Starts at the container specified and traverses the id path specified, finding the relative Entity from container
// if id_path is nullptr, then it will set relative_entity to the container itself, leaving relative_entity_parent to nullptr
// if id_path is invalid or container is nullptr, then it will set both relative_entity and relative_entity_parent to nullptr
// if id_path is any form of a list, then it will treat the ids as a sequence of subcontainers
Expand All @@ -45,7 +45,7 @@ std::vector<EvaluableNode *> CustomEvaluableNodeOrderedChildNodesSort(std::vecto
//Note that id is allocated in the string_intern_pool, and the caller is responsible for freeing the allocation
void TraverseToEntityViaEvaluableNodeIDPath(Entity *container, EvaluableNode *id_path, Entity *&relative_entity_parent, StringInternRef &id, Entity *&relative_entity);

//Starts at the container specified and traverses the id list specified, finding the relative Entity from container
//Starts at the container specified and traverses the id path specified, finding the relative Entity from container
// if id_path does not exist or is invalid then returns nullptr
template<typename EntityReferenceType>
EntityReferenceType TraverseToExistingEntityReferenceViaEvaluableNodeIDPath(Entity *container, EvaluableNode *id_path)
Expand Down Expand Up @@ -97,8 +97,8 @@ EntityReferenceType TraverseToExistingEntityReferenceViaEvaluableNodeIDPath(Enti
//Note that destination_id is allocated in the string_intern_pool, and the caller is responsible for freeing the allocation
void TraverseEntityToNewDestinationViaEvaluableNodeIDPath(Entity *container, EvaluableNode *id_path, Entity *&destination_entity_parent, StringInternRef &destination_id);

//constructs a list of IDs that will traverse frome a to b, assuming that b is contained somewhere within a
EvaluableNode *GetTraversalIDPathListFromAToB(EvaluableNodeManager *enm, Entity *a, Entity *b);
//constructs an ID or list of IDs that will traverse frome a to b, assuming that b is contained somewhere within a
EvaluableNode *GetTraversalIDPathFromAToB(EvaluableNodeManager *enm, Entity *a, Entity *b);

//similar to Parser::GetCodeForPathFromAToB, but instead returns a list of how to traverse each node, such as which index or which key to use to traverse
// returns nullptr if no path exists
Expand Down
7 changes: 6 additions & 1 deletion src/Amalgam/interpreter/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,8 +635,13 @@ EvaluableNode *Interpreter::InterpretNodeIntoUniqueStringIDValueEvaluableNode(Ev

double Interpreter::InterpretNodeIntoNumberValue(EvaluableNode *n)
{
if(n == nullptr)
return std::numeric_limits<double>::quiet_NaN();

auto type = n->GetType();

//shortcut if the node has what is being asked
if(n != nullptr && n->GetType() == ENT_NUMBER)
if(type == ENT_NUMBER)
return n->GetNumberValueReference();

auto result = InterpretNodeForImmediateUse(n);
Expand Down
8 changes: 4 additions & 4 deletions src/Amalgam/interpreter/InterpreterOpcodesCodeMixing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MUTATE_ENTITY(EvaluableNod
if(destination_entity_parent == curEntity)
return EvaluableNodeReference(evaluableNodeManager->AllocNode(ENT_STRING, new_entity_id), true);
else //need to return an id list
return EvaluableNodeReference(GetTraversalIDPathListFromAToB(evaluableNodeManager, curEntity, new_entity), true);
return EvaluableNodeReference(GetTraversalIDPathFromAToB(evaluableNodeManager, curEntity, new_entity), true);
}

EvaluableNodeReference Interpreter::InterpretNode_ENT_COMMONALITY_ENTITIES(EvaluableNode *en)
Expand Down Expand Up @@ -506,7 +506,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_INTERSECT_ENTITIES(Evaluab
if(destination_entity_parent == curEntity)
return EvaluableNodeReference(evaluableNodeManager->AllocNode(ENT_STRING, new_entity_id), true);
else //need to return an id list
return EvaluableNodeReference(GetTraversalIDPathListFromAToB(evaluableNodeManager, curEntity, new_entity), true);
return EvaluableNodeReference(GetTraversalIDPathFromAToB(evaluableNodeManager, curEntity, new_entity), true);
}

EvaluableNodeReference Interpreter::InterpretNode_ENT_UNION_ENTITIES(EvaluableNode *en)
Expand Down Expand Up @@ -559,7 +559,7 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_UNION_ENTITIES(EvaluableNo
if(destination_entity_parent == curEntity)
return EvaluableNodeReference(evaluableNodeManager->AllocNode(ENT_STRING, new_entity_id), true);
else //need to return an id list
return EvaluableNodeReference(GetTraversalIDPathListFromAToB(evaluableNodeManager, curEntity, new_entity), true);
return EvaluableNodeReference(GetTraversalIDPathFromAToB(evaluableNodeManager, curEntity, new_entity), true);
}

EvaluableNodeReference Interpreter::InterpretNode_ENT_DIFFERENCE_ENTITIES(EvaluableNode *en)
Expand Down Expand Up @@ -656,5 +656,5 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MIX_ENTITIES(EvaluableNode
if(destination_entity_parent == curEntity)
return EvaluableNodeReference(evaluableNodeManager->AllocNode(ENT_STRING, new_entity_id), true);
else //need to return an id list
return EvaluableNodeReference(GetTraversalIDPathListFromAToB(evaluableNodeManager, curEntity, new_entity), true);
return EvaluableNodeReference(GetTraversalIDPathFromAToB(evaluableNodeManager, curEntity, new_entity), true);
}
16 changes: 8 additions & 8 deletions src/Amalgam/interpreter/InterpreterOpcodesEntityControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,8 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_CREATE_ENTITIES(EvaluableN

if(destination_entity_parent == curEntity)
new_entity_ids_list->AppendOrderedChildNode(evaluableNodeManager->AllocNode(ENT_STRING, new_entity_id));
else //need an id list
new_entity_ids_list->AppendOrderedChildNode(GetTraversalIDPathListFromAToB(evaluableNodeManager, curEntity, new_entity));
else //need an id path
new_entity_ids_list->AppendOrderedChildNode(GetTraversalIDPathFromAToB(evaluableNodeManager, curEntity, new_entity));
}

return new_entity_ids_list;
Expand Down Expand Up @@ -430,8 +430,8 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_CLONE_ENTITIES(EvaluableNo

if(destination_entity_parent == curEntity)
new_entity_ids_list->AppendOrderedChildNode(evaluableNodeManager->AllocNode(ENT_STRING, new_entity_id));
else //need an id list
new_entity_ids_list->AppendOrderedChildNode(GetTraversalIDPathListFromAToB(evaluableNodeManager, curEntity, new_entity));
else //need an id path
new_entity_ids_list->AppendOrderedChildNode(GetTraversalIDPathFromAToB(evaluableNodeManager, curEntity, new_entity));
}

return new_entity_ids_list;
Expand Down Expand Up @@ -499,8 +499,8 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MOVE_ENTITIES(EvaluableNod

if(destination_entity_parent == curEntity)
new_entity_ids_list->AppendOrderedChildNode(evaluableNodeManager->AllocNode(ENT_STRING, new_entity_id));
else //need an id list
new_entity_ids_list->AppendOrderedChildNode(GetTraversalIDPathListFromAToB(evaluableNodeManager, curEntity, source_entity));
else //need an id path
new_entity_ids_list->AppendOrderedChildNode(GetTraversalIDPathFromAToB(evaluableNodeManager, curEntity, source_entity));
}

return new_entity_ids_list;
Expand Down Expand Up @@ -640,8 +640,8 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_LOAD_ENTITY_and_LOAD_PERSI

if(destination_entity_parent == curEntity)
return EvaluableNodeReference(evaluableNodeManager->AllocNode(ENT_STRING, new_entity_id), true);
else //need to return an id list
return EvaluableNodeReference(GetTraversalIDPathListFromAToB(evaluableNodeManager, curEntity, loaded_entity), true);
else //need to return an id path
return EvaluableNodeReference(GetTraversalIDPathFromAToB(evaluableNodeManager, curEntity, loaded_entity), true);
}

EvaluableNodeReference Interpreter::InterpretNode_ENT_STORE(EvaluableNode *en)
Expand Down
Loading

0 comments on commit 54704d5

Please sign in to comment.