mirror of
https://github.com/StarBeat/UnityDependencyAnalyzer.git
synced 2026-03-08 05:35:27 +08:00
122 lines
3.0 KiB
C#
122 lines
3.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
#nullable enable
|
|
using System.Collections.Concurrent;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security;
|
|
|
|
namespace MemoryPack {
|
|
|
|
public static class MemoryPackWriterOptionalStatePool
|
|
{
|
|
static readonly ConcurrentQueue<MemoryPackWriterOptionalState> queue = new ConcurrentQueue<MemoryPackWriterOptionalState>();
|
|
|
|
public static MemoryPackWriterOptionalState Rent(MemoryPackSerializerOptions? options)
|
|
{
|
|
if (!queue.TryDequeue(out var state))
|
|
{
|
|
state = new MemoryPackWriterOptionalState();
|
|
}
|
|
|
|
state.Init(options);
|
|
return state;
|
|
}
|
|
|
|
internal static void Return(MemoryPackWriterOptionalState state)
|
|
{
|
|
state.Reset();
|
|
queue.Enqueue(state);
|
|
}
|
|
}
|
|
|
|
public sealed class MemoryPackWriterOptionalState : IDisposable
|
|
{
|
|
internal static readonly MemoryPackWriterOptionalState NullState = new MemoryPackWriterOptionalState(true);
|
|
|
|
uint nextId;
|
|
readonly Dictionary<object, uint> objectToRef;
|
|
|
|
public MemoryPackSerializerOptions Options { get; private set; }
|
|
|
|
internal MemoryPackWriterOptionalState()
|
|
{
|
|
objectToRef = new Dictionary<object, uint>(ReferenceEqualityComparer.Instance);
|
|
Options = null!;
|
|
nextId = 0;
|
|
}
|
|
|
|
MemoryPackWriterOptionalState(bool _)
|
|
{
|
|
objectToRef = null!;
|
|
Options = MemoryPackSerializerOptions.Default;
|
|
nextId = 0;
|
|
}
|
|
|
|
internal void Init(MemoryPackSerializerOptions? options)
|
|
{
|
|
Options = options ?? MemoryPackSerializerOptions.Default;
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
objectToRef.Clear();
|
|
Options = null!;
|
|
nextId = 0;
|
|
}
|
|
|
|
public (bool existsReference, uint id) GetOrAddReference(object value)
|
|
{
|
|
#if NET7_0_OR_GREATER
|
|
ref var id = ref CollectionsMarshal.GetValueRefOrAddDefault(objectToRef, value, out var exists);
|
|
if (exists)
|
|
{
|
|
return (true, id);
|
|
}
|
|
else
|
|
{
|
|
id = nextId++;
|
|
return (false, id);
|
|
}
|
|
#else
|
|
if (objectToRef.TryGetValue(value, out var id))
|
|
{
|
|
return (true, id);
|
|
}
|
|
else
|
|
{
|
|
id = nextId++;
|
|
objectToRef.Add(value, id);
|
|
return (false, id);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void IDisposable.Dispose()
|
|
{
|
|
MemoryPackWriterOptionalStatePool.Return(this);
|
|
}
|
|
|
|
// ReferenceEqualityComparer is exsits in .NET 6 but NetStandard 2.1 does not.
|
|
sealed class ReferenceEqualityComparer : IEqualityComparer<object>
|
|
{
|
|
ReferenceEqualityComparer() { }
|
|
|
|
public static ReferenceEqualityComparer Instance { get; } = new ReferenceEqualityComparer();
|
|
|
|
public new bool Equals(object? x, object? y) => ReferenceEquals(x, y);
|
|
|
|
public int GetHashCode(object obj)
|
|
{
|
|
return RuntimeHelpers.GetHashCode(obj);
|
|
}
|
|
}
|
|
}
|
|
|
|
} |