/// <summary> /// Loads initial cache data /// </summary> /// <param name="initialLoader"></param> /// <param name="cfg"></param> private void LoadData(ICacheLoadProvider <TValue, TKey> initialLoader, Config <TValue, TKey> cfg) { if (initialLoader != null) { var intLoadTimeMaxSecs = cfg.LoadCacheMaxSeconds; var numberOfSets = this.Config.NumberOfSets; var itemsPerSet = this.Config.ItemsPerSet; var arrSetIDXs = new int[this.Config.NumberOfSets]; arrSetIDXs[0] = -1; int totalNumberLoaded = 0; int totalNumberOfFullSets = 0; DateTime start = DateTime.UtcNow; while (initialLoader.GetNextKey(totalNumberLoaded, cfg, (iSet) => { return((iSet > -1 && iSet < numberOfSets) ? arrSetIDXs[iSet] : -1); }, out TKey key)) { int setNumber = FindSetNumber(key, out CacheItem <TValue, TKey>[] d); if (setNumber > -1) { var idxMax = arrSetIDXs[setNumber]; if ((idxMax == 0 && setNumber > 0) || (idxMax == -1 && setNumber == 0) || (idxMax > 0 && (idxMax < itemsPerSet - 1))) //Check if this set is not full { TValue val = initialLoader.GetValue(key); if (idxMax < 0) { idxMax = 0; } d[idxMax + this.SetNumberToSetAddress(setNumber)] = m_itemCreateHr(val, key); arrSetIDXs[setNumber] = idxMax + 1; totalNumberLoaded += 1; if (idxMax >= (itemsPerSet - 1)) { totalNumberOfFullSets += 1; } } if ((totalNumberOfFullSets >= numberOfSets) || (intLoadTimeMaxSecs > 0 && (DateTime.UtcNow - start).TotalSeconds >= intLoadTimeMaxSecs)) { break; //finish when all sets are full or the time elapsed is greater than a limit set by Config } } } } }
/// <summary> /// Constructs new cache object for a given <see cref="Config{TValue, TKey}"/> and initialLoader object. /// </summary> /// <param name="config">Cache configuration obect to be used for cache construction purposes.</param> /// <param name="initialLoader">Initial loader implementation to be used for cache initialization</param> public Cache(Config <TValue, TKey> config, ICacheLoadProvider <TValue, TKey> initialLoader) : base() { if (config == null) { throw new ArgumentException("config argument is reguired."); } this.Config = config; if (config.Strategy == ReplacementStrategy.Custom && (config.ReplacementHandler != null)) { m_replacementHandler = config.ReplacementHandler; } m_cachePlus = new CacheItem <TValue, TKey> [config.Size - 1]; m_cacheMinus = new CacheItem <TValue, TKey> [config.Size - 1]; if (config.CacheType != CachingAlgorithm.FullyAssociative) { m_SetAddressMask = (uint)(2 << config.SetSizeBits) - 1; } m_HashCalc = config.HashCalculator ?? DefaultCalcHashFunc; m_itemCreateHr = config.CreateItemHandler ?? DefaultItemCreateHr; m_LoadHandler = config.LoadHandler; m_MaxScanThreads = (config.ThreadsMaxNumberOfScan > 0)? config.ThreadsMaxNumberOfScan : Config <TValue, TKey> .DefaultMaxNumberOfScanThreads; LoadData(initialLoader, config); }