diff --git a/Assets/FishNet/Runtime/Serializing/WriterPool.cs b/Assets/FishNet/Runtime/Serializing/WriterPool.cs
index 7a6b85e6..d3b5a852 100644
--- a/Assets/FishNet/Runtime/Serializing/WriterPool.cs
+++ b/Assets/FishNet/Runtime/Serializing/WriterPool.cs
@@ -89,6 +89,14 @@ public static PooledWriter Retrieve(NetworkManager networkManager, int length)
PooledWriter result;
// There is already one pooled.
if (_lengthPool.TryGetValue(index, out stack) && stack.TryPop(out result))
+ {
+ if (stack.Count == 0)
+ _lengthPool.Remove(index);
+
+ result.Clear(networkManager);
+ }
+ // There is a larger writer pooled.
+ else if (TryPopLengthWriterAbove(index, out result))
{
result.Clear(networkManager);
}
@@ -107,6 +115,46 @@ public static PooledWriter Retrieve(NetworkManager networkManager, int length)
return result;
}
+ ///
+ /// Tries to pop the closest writer from a bucket above minimum index.
+ ///
+ private static bool TryPopLengthWriterAbove(int minimumIndex, out PooledWriter writer)
+ {
+ int foundIndex = int.MaxValue;
+ Stack foundStack = null;
+
+ foreach (KeyValuePair> entry in _lengthPool)
+ {
+ if (entry.Key <= minimumIndex)
+ continue;
+ if (entry.Value.Count == 0)
+ continue;
+ if (entry.Key < foundIndex)
+ {
+ foundIndex = entry.Key;
+ foundStack = entry.Value;
+ }
+ }
+
+ if (foundStack == null)
+ {
+ writer = null;
+ return false;
+ }
+
+ bool popped = foundStack.TryPop(out writer);
+ if (!popped)
+ {
+ writer = null;
+ return false;
+ }
+
+ if (foundStack.Count == 0)
+ _lengthPool.Remove(foundIndex);
+
+ return true;
+ }
+
///
/// Returns a writer to the appropriate length pool.
/// Writers must be a minimum of 1000 bytes in length to be sorted by length.