/// <summary> /// Adds to map. /// </summary> /// <param name="definition">The definition.</param> /// <param name="forceIgnoreHierarchical">if set to <c>true</c> [force ignore hierarchical].</param> public void AddToMap(IDefinition definition, bool forceIgnoreHierarchical = false) { MapKeys(fileKeys, definition.FileCI); MapKeys(typeKeys, definition.Type); MapKeys(typeAndIdKeys, ConstructKey(definition.Type, definition.Id)); MapKeys(allFileKeys, definition.FileCI); MapKeys(directoryKeys, definition.ParentDirectory); if (!string.IsNullOrWhiteSpace(definition.DiskFile)) { MapKeys(allFileKeys, definition.DiskFile.ToLowerInvariant()); } if (definition.OverwrittenFileNames?.Count > 0) { foreach (var item in definition.OverwrittenFileNames) { MapKeys(allFileKeys, item.ToLowerInvariant()); } } if (useHierarchalMap && !forceIgnoreHierarchical) { MapHierarchicalDefinition(definition); } if (definition.IsFromGame) { gameDefinitionsCount++; } definitions.Add(definition); }
/// <summary> /// Maps the pretty print hierarchy. /// </summary> /// <param name="definition">The definition.</param> private void MapHierarchicalDefinition(IDefinition definition) { bool shouldAdd = false; var parentDirectoryCI = ResolveHierarchalParentDirectory(definition); var hierarchicalDefinition = mainHierarchalDefinitions.GetFirstByNameNoLock(nameof(IHierarchicalDefinitions.Name), parentDirectoryCI); if (hierarchicalDefinition == null) { hierarchicalDefinition = DIResolver.Get <IHierarchicalDefinitions>(); hierarchicalDefinition.Name = parentDirectoryCI; childHierarchicalDefinitions.TryAdd(parentDirectoryCI, new ConcurrentIndexedList <IHierarchicalDefinitions>(nameof(IHierarchicalDefinitions.Name))); shouldAdd = true; } bool exists = false; IHierarchicalDefinitions child = null; if (childHierarchicalDefinitions.TryGetValue(hierarchicalDefinition.Name, out var children)) { child = children.GetFirstByNameNoLock(nameof(IHierarchicalDefinitions.Name), definition.Id); exists = child != null; } if (!exists) { child = DIResolver.Get <IHierarchicalDefinitions>(); child.Name = definition.Id; child.Key = definition.TypeAndId; child.FileNames.Add(definition.FileCI); children.Add(child); if (shouldAdd) { mainHierarchalDefinitions.Add(hierarchicalDefinition); } } else { if (!child.FileNames.Contains(definition.FileCI)) { child.FileNames.Add(definition.FileCI); } } if (child.Mods == null) { child.Mods = new List <string>(); } if (!child.Mods.Contains(definition.ModName)) { child.Mods.Add(definition.ModName); } if (hierarchicalDefinition.Mods == null) { hierarchicalDefinition.Mods = new List <string>(); } if (!hierarchicalDefinition.Mods.Contains(definition.ModName)) { hierarchicalDefinition.Mods.Add(definition.ModName); } }
/// <summary> /// Adds to map. /// </summary> /// <param name="definition">The definition.</param> /// <param name="forceIgnoreHierarchical">if set to <c>true</c> [force ignore hierarchical].</param> public void AddToMap(IDefinition definition, bool forceIgnoreHierarchical = false) { MapKeys(fileKeys, definition.FileCI); MapKeys(typeKeys, definition.Type); MapKeys(typeAndIdKeys, ConstructKey(definition.Type, definition.Id)); MapKeys(allFileKeys, definition.FileCI); if (definition.OverwrittenFileNames?.Count > 0) { foreach (var item in definition.OverwrittenFileNames) { MapKeys(allFileKeys, item.ToLowerInvariant()); } } if (useHierarchalMap && !forceIgnoreHierarchical) { MapHierarchicalDefinition(definition); } definitions.Add(definition); }
public void AddByQuery <T>(IEnumerable <T> list, string text, object[] parms = null, int?expirySeconds = null, CacheBehavior?mode = null) where T : class, new() { var ss = CEF.CurrentServiceScope; if (mode == null) { mode = ss.ResolvedCacheBehaviorForType(typeof(T)); } if ((mode & CacheBehavior.QueryBased) == 0 && (mode & CacheBehavior.ConvertQueryToIdentity) != 0 && ((mode & CacheBehavior.ForAllDoesntConvertToIdentity) == 0 || string.Compare(text, "All", true) != 0)) { // All we can do is for all list items, add to identity cache void act2() { try { Interlocked.Increment(ref _working); Parallel.ForEach(list, (i) => { using (CEF.UseServiceScope(ss)) { AddByIdentity <T>(i, expirySeconds: expirySeconds); } }); } catch (Exception ex) { CEFDebug.WriteInfo($"Exception in cache serializer: {ex.Message}"); } finally { Interlocked.Decrement(ref _working); } } if (Globals.AsyncCacheUpdates) { Task.Factory.StartNew(act2); } else { act2(); } return; } if ((mode & CacheBehavior.OnlyForAllQuery) != 0 && string.Compare(text, "All", true) != 0) { return; } StringBuilder sb = new StringBuilder(128); sb.Append(typeof(T).Name); sb.Append(text.ToUpperInvariant()); if (parms != null) { foreach (var k in parms) { sb.Append(k); } } string hash; using (SHA256Managed hasher = new SHA256Managed()) { hash = Convert.ToBase64String(hasher.ComputeHash(Encoding.ASCII.GetBytes(sb.ToString()))); } var c = _index.GetFirstByName(nameof(MFSEntry.ByQuerySHA), hash); if (!expirySeconds.HasValue) { expirySeconds = CEF.CurrentServiceScope.ResolvedCacheDurationForType(typeof(T)); } var newExpDate = DateTime.Now.AddSeconds(expirySeconds.GetValueOrDefault(DefaultCacheIntervalSeconds)); if (c == null) { c = new MFSEntry(); if (list.Any()) { c.ObjectTypeName = list.First().GetBaseType().Name; } else { c.ObjectTypeName = typeof(T).Name; } c.ByQuerySHA = hash; c.FileName = BuildNewFileName(typeof(T)); c.QueryForAll = string.Compare(text, "All", true) == 0; _index.Add(c); } long current; lock (c.ObjSync) { current = ++c.Sequence; c.ExpiryDate = newExpDate; c.SourceList = list; c.Active = true; } void act() { try { Interlocked.Increment(ref _working); using (CEF.UseServiceScope(ss)) { // Process all items in parallel, building a list we'll turn into json but also potentially caching "by identity" per row ConcurrentBag <IDictionary <string, object> > rows = new ConcurrentBag <IDictionary <string, object> >(); var aiw = list.AllAsInfraWrapped().ToArray(); Parallel.ForEach(aiw, (iw) => { using (CEF.UseServiceScope(ss)) { rows.Add(iw.GetAllValues(true, true)); if ((mode & CacheBehavior.ConvertQueryToIdentity) != 0 && ((mode & CacheBehavior.ForAllDoesntConvertToIdentity) == 0 || string.Compare(text, "All", true) != 0)) { var uw = iw.AsUnwrapped() as T; if (uw != null) { AddByIdentity <T>(uw, expirySeconds: expirySeconds); } } } }); lock (c.ObjSync) { if (c.Sequence == current) { c.Rows = rows; c.SourceList = null; } } } } catch (Exception ex) { CEFDebug.WriteInfo($"Exception in cache serializer: {ex.Message}"); // Invalidate the entry is probably the safest c.Active = false; c.Properties = null; c.Rows = null; } finally { Interlocked.Decrement(ref _working); } } if (Globals.AsyncCacheUpdates) { Task.Factory.StartNew(act); } else { act(); } }