// Copyright (c) 2023 bradson // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. namespace PerformanceFish.Cache; #pragma warning disable CS9091 public static class Database where TCache : ICacheKeyable where TValue : new() { public static object SyncLock = new(); private static Dictionary _get = Utility.AddNew>(); [ThreadStatic] private static Dictionary? _getThreadStatic; public static Dictionary Get { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _getThreadStatic ??= Utility.AddNew>(); } public static Dictionary GetDirectly { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _get; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref TValue GetOrAddReference(T1 first, T2 second) where VCache : IMemberCount, new() // new as generic constraint requires at least function pointers, // and can't be inlined. Makes this slow, unfortunately => ref Unsafe.As>(Get) .GetOrAddReference(Reflection.New(first, second)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref TValue GetOrAddReference(in TCache key) => ref Get.GetOrAddReference(ref Unsafe.AsRef(in key)); [MethodImpl(MethodImplOptions.NoInlining)] public static unsafe ref TValue GetExistingReference(T1 first, T2 second) where VCache : IMemberCount, new() { var key = Reflection.New(first, second); return ref Get.GetReference(ref Unsafe.As(ref key)); } [MethodImpl(MethodImplOptions.NoInlining)] public static ref TValue GetExistingReference(in TCache key) => ref Get.GetReference(ref Unsafe.AsRef(in key)); } #pragma warning restore CS9091