Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify locator map recycling by using a FILO approach #61

Merged
merged 1 commit into from
Jan 19, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 8 additions & 26 deletions Svelto.ECS/EnginesRoot.LocatorMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,20 @@ void CreateReferenceLocator(EGID egid)
{
// Check if we need to create a new EntityLocator or whether we can recycle an existing one.s
EntityReference reference;
if (_nextEntityId == _entityLocatorMap.count)
if (_nextReferenceIndex == _entityLocatorMap.count)
{
_entityLocatorMap.Add(new EntityLocatorMapElement(egid));
reference = new EntityReference(_nextEntityId++);
reference = new EntityReference(_nextReferenceIndex++);
}
else
{
ref var element = ref _entityLocatorMap[_nextEntityId];
reference = new EntityReference(_nextEntityId, element.version);
ref var element = ref _entityLocatorMap[_nextReferenceIndex];
reference = new EntityReference(_nextReferenceIndex, element.version);
// The recycle entities form a linked list, using the egid.entityID to store the next element.
_nextEntityId = element.egid.entityID;
_nextReferenceIndex = element.egid.entityID;
element.egid = egid;
}

// When we create a new one there is nothing to recycle anymore, so we need to update the last recycle entityId.
if (_nextEntityId == _entityLocatorMap.count)
{
_lastEntityId = (uint)_entityLocatorMap.count;
}

// Update reverse map from egid to locator.
if (_egidToLocatorMap.TryGetValue(egid.groupID, out var groupMap) == false)
{
Expand Down Expand Up @@ -81,23 +75,12 @@ void RemoveReferenceLocator(EGID egid)
}
#endif

// Check if this is the first recycled element.
if (_lastEntityId == _entityLocatorMap.count)
{
_nextEntityId = locator.uniqueID;
}
// Otherwise add it as the last recycled element.
else
{
_entityLocatorMap[_lastEntityId].egid = new EGID(locator.uniqueID, 0);
}

// Invalidate the entity locator element by bumping its version and setting the egid to point to a unexisting element.
_entityLocatorMap[locator.uniqueID].egid = new EGID((uint)_entityLocatorMap.count, 0);
_entityLocatorMap[locator.uniqueID].egid = new EGID(_nextReferenceIndex, 0);
_entityLocatorMap[locator.uniqueID].version++;

// Mark the element as the last element used.
_lastEntityId = locator.uniqueID;
_nextReferenceIndex = locator.uniqueID;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down Expand Up @@ -183,8 +166,7 @@ bool IEntityReferenceLocatorMap.TryGetEGID(EntityReference reference, out EGID e
return false;
}

uint _nextEntityId;
uint _lastEntityId;
uint _nextReferenceIndex;
readonly FasterList<EntityLocatorMapElement> _entityLocatorMap;
readonly FasterDictionary<uint, FasterDictionary<uint, EntityReference>> _egidToLocatorMap;
}
Expand Down