Guest User

Untitled

a guest
Jan 16th, 2019
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.59 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using Baseline;
  6. using Marten.Util;
  7.  
  8. namespace Marten.Services
  9. {
  10. public enum UnitOfWorkOrigin
  11. {
  12. Stored,
  13. Loaded
  14. }
  15.  
  16. public abstract class IdentityMap<TCacheValue> : IIdentityMap
  17. {
  18. private readonly IEnumerable<IDocumentSessionListener> _listeners;
  19.  
  20. protected IdentityMap(ISerializer serializer, IEnumerable<IDocumentSessionListener> listeners)
  21. {
  22. Serializer = serializer;
  23. _listeners = listeners ?? new IDocumentSessionListener[] { };
  24. }
  25.  
  26. protected Ref<ImHashMap<Type, ImHashMap<object, TCacheValue>>> Cache { get; }
  27. = Ref.Of(ImHashMap<Type, ImHashMap<object, TCacheValue>>.Empty);
  28.  
  29. public ISerializer Serializer { get; }
  30.  
  31. public T Get<T>(object id, TextReader json, Guid? version)
  32. {
  33. return Get<T>(id, typeof(T), json, version);
  34. }
  35.  
  36. public T Get<T>(object id, Type concreteType, TextReader json, Guid? version)
  37. {
  38.  
  39. if (Cache.Value.TryFind(typeof(T), out var t) && t.TryFind(id, out var value))
  40. {
  41. return FromCache<T>(value);
  42. }
  43.  
  44. if (version.HasValue)
  45. Versions.Store<T>(id, version.Value);
  46.  
  47. var document = Serializer.FromJson(concreteType, json);
  48.  
  49. _listeners.Each(listener => listener.DocumentLoaded(id, document));
  50.  
  51. var cacheValue = ToCache(id, concreteType, document, json);
  52.  
  53. Cache.Swap(c => c.AddOrUpdate(typeof(T),
  54. (c.GetValueOrDefault(typeof(T)) ?? ImHashMap<object, TCacheValue>.Empty).AddOrUpdate(id, cacheValue)));
  55.  
  56. return FromCache<T>(cacheValue);
  57. }
  58.  
  59. public void Remove<T>(object id)
  60. {
  61. Cache.Swap(c => c.AddOrUpdate(typeof(T),
  62. (c.GetValueOrDefault(typeof(T)) ?? ImHashMap<object, TCacheValue>.Empty).Remove(id)));
  63. }
  64.  
  65. public void RemoveAllOfType(Type type)
  66. {
  67. Cache.Swap(c => c.AddOrUpdate(type, ImHashMap<object, TCacheValue>.Empty));
  68. }
  69.  
  70. public void Store<T>(object id, T entity, Guid? version = null)
  71. {
  72. if (version.HasValue)
  73. Versions.Store<T>(id, version.Value);
  74.  
  75. if (Cache.Value.TryFind(typeof(T), out var dictionary) && dictionary.TryFind(id, out var value))
  76. {
  77. var existing = FromCache<T>(value);
  78. if (existing != null && !ReferenceEquals(existing, entity))
  79. throw new InvalidOperationException(
  80. $"Document '{typeof(T).FullName}' with same Id already added to the session.");
  81. }
  82.  
  83. _listeners.Each(listener => listener.DocumentAddedForStorage(id, entity));
  84.  
  85. var cacheValue = ToCache(id, typeof(T), entity, null, UnitOfWorkOrigin.Stored);
  86.  
  87. Cache.Swap(c => c.AddOrUpdate(typeof(T),
  88. (c.GetValueOrDefault(typeof(T)) ?? ImHashMap<object, TCacheValue>.Empty).AddOrUpdate(id, cacheValue)));
  89. }
  90.  
  91. public bool Has<T>(object id)
  92. {
  93. return Cache.Value.TryFind(typeof(T), out var dict) && dict.TryFind(id, out _);
  94. }
  95.  
  96. public T Retrieve<T>(object id)
  97. {
  98. if (Cache.Value.TryFind(typeof(T), out var dict) && dict.TryFind(id, out var value))
  99. {
  100. return FromCache<T>(value);
  101. }
  102. return default(T);
  103. }
  104.  
  105. public IIdentityMap ForQuery()
  106. {
  107. return this;
  108. }
  109.  
  110. public VersionTracker Versions { get; set; } = new VersionTracker();
  111.  
  112. public virtual void ClearChanges()
  113. {
  114. }
  115.  
  116. protected IEnumerable<TCacheValue> allCachedValues()
  117. {
  118. return Cache.Value.Enumerate().SelectMany(x => x.Value.Enumerate().Select(t => t.Value));
  119. }
  120.  
  121. protected abstract TCacheValue ToCache(object id, Type concreteType, object document, TextReader json,
  122. UnitOfWorkOrigin origin = UnitOfWorkOrigin.Loaded);
  123.  
  124. protected abstract T FromCache<T>(TCacheValue cacheValue);
  125. }
  126.  
  127. public class IdentityMap : IdentityMap<object>
  128. {
  129. public IdentityMap(ISerializer serializer, IEnumerable<IDocumentSessionListener> listeners)
  130. : base(serializer, listeners)
  131. {
  132. }
  133.  
  134. protected override object ToCache(object id, Type concreteType, object document, TextReader json,
  135. UnitOfWorkOrigin origin = UnitOfWorkOrigin.Loaded)
  136. {
  137. return document;
  138. }
  139.  
  140. protected override T FromCache<T>(object cacheValue)
  141. {
  142. return cacheValue.As<T>();
  143. }
  144. }
  145. }
Add Comment
Please, Sign In to add comment