DefaultHybridCache.MutableCacheItem.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. namespace Microsoft.Extensions.Caching.Hybrid.Internal;
  4. partial class DefaultHybridCache
  5. {
  6. private sealed partial class MutableCacheItem<T> : CacheItem<T> // used to hold types that require defensive copies
  7. {
  8. private IHybridCacheSerializer<T> _serializer = null!; // deferred until SetValue
  9. private BufferChunk _buffer;
  10. public void SetValue(ref BufferChunk buffer, IHybridCacheSerializer<T> serializer)
  11. {
  12. _serializer = serializer;
  13. _buffer = buffer;
  14. buffer = default; // we're taking over the lifetime; the caller no longer has it!
  15. }
  16. public void SetValue(T value, IHybridCacheSerializer<T> serializer, int maxLength)
  17. {
  18. _serializer = serializer;
  19. var writer = RecyclableArrayBufferWriter<byte>.Create(maxLength);
  20. serializer.Serialize(value, writer);
  21. _buffer = new(writer.DetachCommitted(out var length), length, returnToPool: true);
  22. writer.Dispose(); // no buffers left (we just detached them), but just in case of other logic
  23. }
  24. public override bool NeedsEvictionCallback => _buffer.ReturnToPool;
  25. protected override void OnFinalRelease()
  26. {
  27. DebugOnlyDecrementOutstandingBuffers();
  28. _buffer.RecycleIfAppropriate();
  29. }
  30. public override bool TryGetValue(out T value)
  31. {
  32. if (!TryReserve()) // only if we haven't already burned
  33. {
  34. value = default!;
  35. return false;
  36. }
  37. try
  38. {
  39. value = _serializer.Deserialize(_buffer.AsSequence());
  40. return true;
  41. }
  42. finally
  43. {
  44. Release();
  45. }
  46. }
  47. public override bool TryReserveBuffer(out BufferChunk buffer)
  48. {
  49. if (TryReserve()) // only if we haven't already burned
  50. {
  51. buffer = _buffer.DoNotReturnToPool(); // not up to them!
  52. return true;
  53. }
  54. buffer = default;
  55. return false;
  56. }
  57. public override bool DebugIsImmutable => false;
  58. }
  59. }