-
-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added pooled connection library (#99)
- Loading branch information
1 parent
788ffad
commit 338bea6
Showing
21 changed files
with
9,483 additions
and
1 deletion.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
OctaneEngine/.idea/.idea.OctaneEngine.dir/.idea/indexLayout.xml
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
25 changes: 25 additions & 0 deletions
25
OctaneEngine/.idea/.idea.OctaneEngine.dir/.idea/workspace.xml
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System; | ||
using System.Runtime.CompilerServices; | ||
|
||
namespace Collections.Pooled | ||
{ | ||
internal ref struct BitHelper | ||
{ | ||
private const int IntSize = sizeof(int) * 8; | ||
private readonly Span<int> _span; | ||
|
||
internal BitHelper(Span<int> span, bool clear) | ||
{ | ||
if (clear) | ||
{ | ||
span.Clear(); | ||
} | ||
_span = span; | ||
} | ||
|
||
internal void MarkBit(int bitPosition) | ||
{ | ||
int bitArrayIndex = bitPosition / IntSize; | ||
if ((uint)bitArrayIndex < (uint)_span.Length) | ||
{ | ||
_span[bitArrayIndex] |= (1 << (bitPosition % IntSize)); | ||
} | ||
} | ||
|
||
internal bool IsMarked(int bitPosition) | ||
{ | ||
int bitArrayIndex = bitPosition / IntSize; | ||
return | ||
(uint)bitArrayIndex < (uint)_span.Length && | ||
(_span[bitArrayIndex] & (1 << (bitPosition % IntSize))) != 0; | ||
} | ||
|
||
internal int FindFirstUnmarked(int startPosition = 0) | ||
{ | ||
int i = startPosition; | ||
for (int bi = i / IntSize; (uint)bi < (uint)_span.Length; bi = ++i / IntSize) | ||
{ | ||
if ((_span[bi] & (1 << (i % IntSize))) == 0) | ||
return i; | ||
} | ||
return -1; | ||
} | ||
|
||
internal int FindFirstMarked(int startPosition = 0) | ||
{ | ||
int i = startPosition; | ||
for (int bi = i / IntSize; (uint)bi < (uint)_span.Length; bi = ++i / IntSize) | ||
{ | ||
if ((_span[bi] & (1 << (i % IntSize))) != 0) | ||
return i; | ||
} | ||
return -1; | ||
} | ||
|
||
/// <summary>How many ints must be allocated to represent n bits. Returns (n+31)/32, but avoids overflow.</summary> | ||
internal static int ToIntArrayLength(int n) => n > 0 ? ((n - 1) / IntSize + 1) : 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
namespace Collections.Pooled | ||
{ | ||
/// <summary> | ||
/// This enum allows control over how data is treated when internal | ||
/// arrays are returned to the ArrayPool. Be careful to understand | ||
/// what each option does before using anything other than the default | ||
/// of Auto. | ||
/// </summary> | ||
public enum ClearMode | ||
{ | ||
/// <summary> | ||
/// <para><code>Auto</code> has different behavior depending on the host project's target framework.</para> | ||
/// <para>.NET Core 2.1: Reference types and value types that contain reference types are cleared | ||
/// when the internal arrays are returned to the pool. Value types that do not contain reference | ||
/// types are not cleared when returned to the pool.</para> | ||
/// <para>.NET Standard 2.0: All user types are cleared before returning to the pool, in case they | ||
/// contain reference types. | ||
/// For .NET Standard, Auto and Always have the same behavior.</para> | ||
/// </summary> | ||
Auto = 0, | ||
/// <summary> | ||
/// The <para><code>Always</code> setting has the effect of always clearing user types before returning to the pool. | ||
/// This is the default behavior on .NET Standard.</para><para>You might want to turn this on in a .NET Core project | ||
/// if you were concerned about sensitive data stored in value types leaking to other pars of your application.</para> | ||
/// </summary> | ||
Always = 1, | ||
/// <summary> | ||
/// <para><code>Never</code> will cause pooled collections to never clear user types before returning them to the pool.</para> | ||
/// <para>You might want to use this setting in a .NET Standard project when you know that a particular collection stores | ||
/// only value types and you want the performance benefit of not taking time to reset array items to their default value.</para> | ||
/// <para>Be careful with this setting: if used for a collection that contains reference types, or value types that contain | ||
/// reference types, this setting could cause memory issues by making the garbage collector unable to clean up instances | ||
/// that are still being referenced by arrays sitting in the ArrayPool.</para> | ||
/// </summary> | ||
Never = 2 | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
OctaneEngine/Collections.Pooled/HashHelpers.SerializationInfoTable.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
// Used by Hashtable and Dictionary's SeralizationInfo .ctor's to store the SeralizationInfo | ||
// object until OnDeserialization is called. | ||
|
||
using System.Threading; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.Serialization; | ||
|
||
namespace Collections.Pooled | ||
{ | ||
internal static partial class HashHelpers | ||
{ | ||
private static ConditionalWeakTable<object, SerializationInfo> s_serializationInfoTable; | ||
|
||
public static ConditionalWeakTable<object, SerializationInfo> SerializationInfoTable | ||
{ | ||
get | ||
{ | ||
if (s_serializationInfoTable == null) | ||
Interlocked.CompareExchange(ref s_serializationInfoTable, new ConditionalWeakTable<object, SerializationInfo>(), null); | ||
|
||
return s_serializationInfoTable; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
|
||
using System; | ||
using System.Diagnostics; | ||
|
||
namespace Collections.Pooled | ||
{ | ||
internal static partial class HashHelpers | ||
{ | ||
public const int HashCollisionThreshold = 100; | ||
|
||
// This is the maximum prime smaller than Array.MaxArrayLength | ||
public const int MaxPrimeArrayLength = 0x7FEFFFFD; | ||
|
||
public const int HashPrime = 101; | ||
|
||
// Table of prime numbers to use as hash table sizes. | ||
// A typical resize algorithm would pick the smallest prime number in this array | ||
// that is larger than twice the previous capacity. | ||
// Suppose our Hashtable currently has capacity x and enough elements are added | ||
// such that a resize needs to occur. Resizing first computes 2x then finds the | ||
// first prime in the table greater than 2x, i.e. if primes are ordered | ||
// p_1, p_2, ..., p_i, ..., it finds p_n such that p_n-1 < 2x < p_n. | ||
// Doubling is important for preserving the asymptotic complexity of the | ||
// hashtable operations such as add. Having a prime guarantees that double | ||
// hashing does not lead to infinite loops. IE, your hash function will be | ||
// h1(key) + i*h2(key), 0 <= i < size. h2 and the size must be relatively prime. | ||
// We prefer the low computation costs of higher prime numbers over the increased | ||
// memory allocation of a fixed prime number i.e. when right sizing a HashSet. | ||
public static readonly int[] primes = { | ||
3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919, | ||
1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591, | ||
17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437, | ||
187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263, | ||
1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369 }; | ||
|
||
public static bool IsPrime(int candidate) | ||
{ | ||
if ((candidate & 1) != 0) | ||
{ | ||
int limit = (int)Math.Sqrt(candidate); | ||
for (int divisor = 3; divisor <= limit; divisor += 2) | ||
{ | ||
if ((candidate % divisor) == 0) | ||
return false; | ||
} | ||
return true; | ||
} | ||
return (candidate == 2); | ||
} | ||
|
||
public static int GetPrime(int min) | ||
{ | ||
if (min < 0) | ||
throw new ArgumentException("Cannot get the next prime from a negative number."); | ||
|
||
for (int i = 0; i < primes.Length; i++) | ||
{ | ||
int prime = primes[i]; | ||
if (prime >= min) | ||
return prime; | ||
} | ||
|
||
//outside of our predefined table. | ||
//compute the hard way. | ||
for (int i = (min | 1); i < int.MaxValue; i += 2) | ||
{ | ||
if (IsPrime(i) && ((i - 1) % HashPrime != 0)) | ||
return i; | ||
} | ||
return min; | ||
} | ||
|
||
// Returns size of hashtable to grow to. | ||
public static int ExpandPrime(int oldSize) | ||
{ | ||
int newSize = 2 * oldSize; | ||
|
||
// Allow the hashtables to grow to maximum possible size (~2G elements) before encountering capacity overflow. | ||
// Note that this check works even when _items.Length overflowed thanks to the (uint) cast | ||
if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize) | ||
{ | ||
Debug.Assert(MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength"); | ||
return MaxPrimeArrayLength; | ||
} | ||
|
||
return GetPrime(newSize); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
|
||
namespace Collections.Pooled | ||
{ | ||
internal sealed class ICollectionDebugView<T> | ||
{ | ||
private readonly ICollection<T> _collection; | ||
|
||
public ICollectionDebugView(ICollection<T> collection) | ||
{ | ||
_collection = collection ?? throw new ArgumentNullException(nameof(collection)); | ||
} | ||
|
||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] | ||
public T[] Items | ||
{ | ||
get | ||
{ | ||
T[] items = new T[_collection.Count]; | ||
_collection.CopyTo(items, 0); | ||
return items; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
|
||
namespace Collections.Pooled | ||
{ | ||
internal sealed class IDictionaryDebugView<K, V> | ||
{ | ||
private readonly IDictionary<K, V> _dict; | ||
|
||
public IDictionaryDebugView(IDictionary<K, V> dictionary) | ||
{ | ||
_dict = dictionary ?? throw new ArgumentNullException(nameof(dictionary)); | ||
} | ||
|
||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] | ||
public KeyValuePair<K, V>[] Items | ||
{ | ||
get | ||
{ | ||
KeyValuePair<K, V>[] items = new KeyValuePair<K, V>[_dict.Count]; | ||
_dict.CopyTo(items, 0); | ||
return items; | ||
} | ||
} | ||
} | ||
|
||
internal sealed class DictionaryKeyCollectionDebugView<TKey, TValue> | ||
{ | ||
private readonly ICollection<TKey> _collection; | ||
|
||
public DictionaryKeyCollectionDebugView(ICollection<TKey> collection) | ||
{ | ||
_collection = collection ?? throw new ArgumentNullException(nameof(collection)); | ||
} | ||
|
||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] | ||
public TKey[] Items | ||
{ | ||
get | ||
{ | ||
TKey[] items = new TKey[_collection.Count]; | ||
_collection.CopyTo(items, 0); | ||
return items; | ||
} | ||
} | ||
} | ||
|
||
internal sealed class DictionaryValueCollectionDebugView<TKey, TValue> | ||
{ | ||
private readonly ICollection<TValue> _collection; | ||
|
||
public DictionaryValueCollectionDebugView(ICollection<TValue> collection) | ||
{ | ||
_collection = collection ?? throw new ArgumentNullException(nameof(collection)); | ||
} | ||
|
||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] | ||
public TValue[] Items | ||
{ | ||
get | ||
{ | ||
TValue[] items = new TValue[_collection.Count]; | ||
_collection.CopyTo(items, 0); | ||
return items; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace Collections.Pooled | ||
{ | ||
/// <summary> | ||
/// Represents a read-only collection of pooled elements that can be accessed by index | ||
/// </summary> | ||
/// <typeparam name="T">The type of elements in the read-only pooled list.</typeparam> | ||
|
||
public interface IReadOnlyPooledList<T> : IReadOnlyList<T> | ||
{ | ||
/// <summary> | ||
/// Gets a <see cref="System.ReadOnlySpan{T}"/> for the items currently in the collection. | ||
/// </summary> | ||
ReadOnlySpan<T> Span { get; } | ||
} | ||
} |
Oops, something went wrong.