Skip to content

Commit

Permalink
PVS pooling
Browse files Browse the repository at this point in the history
- Pool a lot more stuff with PVS under the assumption once GameState / MsgState are serialized it's safe to fuck with it. I tried using Collections.Pooled although then you need IList and it becomes a lot more scrunkly with serializing it so I just kept using ObjectPool for now. Maybe someday it'd be better to swap as the pooled data could be re-used across more systems although this PVS data allocs to shit on live.
- Move _deletionHistory out of PVSCollection to PvsSystem with the goal of nuking RobustTree someday.
  • Loading branch information
metalgearsloth committed Nov 19, 2023
1 parent 2459a9d commit 412a626
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 138 deletions.
57 changes: 0 additions & 57 deletions Robust.Server/GameStates/PvsCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,6 @@ public interface IPVSCollection

public void RemoveMap(MapId mapId);

/// <summary>
/// Remove all deletions up to a <see cref="GameTick"/>.
/// </summary>
/// <param name="tick">The <see cref="GameTick"/> before which all deletions should be removed.</param>
public void CullDeletionHistoryUntil(GameTick tick);

public bool IsDirty(IChunkIndexLocation location);

public bool MarkDirty(IChunkIndexLocation location);
Expand Down Expand Up @@ -102,11 +96,6 @@ public static Vector2i GetChunkIndices(Vector2 coordinates)
/// </summary>
private readonly Dictionary<ICommonSession, HashSet<TIndex>> _lastSeen = new();

/// <summary>
/// History of deletion-tuples, containing the <see cref="GameTick"/> of the deletion, as well as the <see cref="TIndex"/> of the object which was deleted.
/// </summary>
private readonly List<(GameTick tick, TIndex index)> _deletionHistory = new();

/// <summary>
/// An index containing the <see cref="IIndexLocation"/>s of all <see cref="TIndex"/>.
/// </summary>
Expand Down Expand Up @@ -151,7 +140,6 @@ public void Process()

foreach (var (index, tick) in _removalBuffer)
{
_deletionHistory.Add((tick, index));
_changedIndices.Remove(index);
var location = RemoveIndexInternal(index);
if (location == null)
Expand Down Expand Up @@ -341,51 +329,6 @@ public void RemoveIndex(GameTick tick, TIndex index)
_removalBuffer[index] = tick;
}

/// <inheritdoc />
public void CullDeletionHistoryUntil(GameTick tick)
{
if (tick == GameTick.MaxValue)
{
_deletionHistory.Clear();
return;
}

for (var i = _deletionHistory.Count - 1; i >= 0; i--)
{
var hist = _deletionHistory[i].tick;
if (hist <= tick)
{
_deletionHistory.RemoveSwap(i);
if (_largestCulled < hist)
_largestCulled = hist;
}
}
}

private GameTick _largestCulled;

public List<TIndex>? GetDeletedIndices(GameTick fromTick)
{
if (fromTick == GameTick.Zero)
return null;

// I'm 99% sure this can never happen, but it is hard to test real laggy/lossy networks with many players.
if (_largestCulled > fromTick)
{
_sawmill.Error($"Culled required deletion history! culled: {_largestCulled}. requested: > {fromTick}");
_largestCulled = GameTick.Zero;
}

var list = new List<TIndex>();
foreach (var (tick, id) in _deletionHistory)
{
if (tick > fromTick)
list.Add(id);
}

return list.Count > 0 ? list : null;
}

#endregion

#region UpdateIndex
Expand Down
56 changes: 56 additions & 0 deletions Robust.Server/GameStates/PvsSystem.Deletion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System.Collections.Generic;
using Robust.Shared.GameObjects;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Robust.Server.GameStates;

internal sealed partial class PvsSystem
{
/// <summary>
/// History of deletion-tuples, containing the <see cref="GameTick"/> of the deletion, as well as the <see cref="TIndex"/> of the object which was deleted.
/// </summary>
private readonly List<(GameTick tick, NetEntity ent)> _deletionHistory = new();

/// <inheritdoc />
public void CullDeletionHistoryUntil(GameTick tick)
{
if (tick == GameTick.MaxValue)
{
_deletionHistory.Clear();
return;
}

for (var i = _deletionHistory.Count - 1; i >= 0; i--)
{
var hist = _deletionHistory[i].tick;
if (hist <= tick)
{
_deletionHistory.RemoveSwap(i);
if (_largestCulled < hist)
_largestCulled = hist;
}
}
}

private GameTick _largestCulled;

public void GetDeletedEntities(GameTick fromTick, IList<NetEntity> ents)
{
if (fromTick == GameTick.Zero)
return;

// I'm 99% sure this can never happen, but it is hard to test real laggy/lossy networks with many players.
if (_largestCulled > fromTick)
{
Log.Error($"Culled required deletion history! culled: {_largestCulled}. requested: > {fromTick}");
_largestCulled = GameTick.Zero;
}

foreach (var (tick, id) in _deletionHistory)
{
if (tick > fromTick)
ents.Add(id);
}
}
}
4 changes: 2 additions & 2 deletions Robust.Server/GameStates/PvsSystem.Dirty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ internal sealed partial class PvsSystem
/// <summary>
/// if it's a new entity we need to GetEntityState from tick 0.
/// </summary>
private HashSet<EntityUid>[] _addEntities = new HashSet<EntityUid>[DirtyBufferSize];
private HashSet<EntityUid>[] _dirtyEntities = new HashSet<EntityUid>[DirtyBufferSize];
private readonly HashSet<EntityUid>[] _addEntities = new HashSet<EntityUid>[DirtyBufferSize];
private readonly HashSet<EntityUid>[] _dirtyEntities = new HashSet<EntityUid>[DirtyBufferSize];
private int _currentIndex = 1;

private void InitializeDirty()
Expand Down
Loading

0 comments on commit 412a626

Please sign in to comment.