internal async Task <Tuple <bool, T> > Lookup <T>( QueryResultCache target, Uri _rootFile, string treeName, object[] inputObjects, string[] cacheStrings, QueryModel queryModel, IVariableSaver varSaver, bool checkDates = false, Func <IAddResult> generateAdder = null ) { var result = await target.Lookup <T>(target.GetKey(new Uri[] { _rootFile }, treeName, inputObjects, cacheStrings, queryModel, recheckDates: checkDates, dateChecker: u => File.GetLastWriteTime(u.LocalPath)), varSaver, null, generateAdder); Assert.IsNotNull(result, "Should never return a null lookup"); return(result); }
/// <summary> /// Lookup in our cache. Fail if we can't find things by returning null. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="sourceRootFiles"></param> /// <param name="queryModel"></param> /// <param name="varSaver"></param> /// <param name="akey"></param> /// <returns></returns> public async Task <Tuple <bool, T> > Lookup <T>(IQueryResultCacheKey akey, IVariableSaver varSaver, IDeclaredParameter theVar, Func <IAddResult> generateAdder = null) { if (akey == null || (akey as KeyInfo) == null) { throw new ArgumentNullException("the key cannot be null"); } var key = akey as KeyInfo; // Check to make sure none of the source root files have actually be altered since // the cache line was written (if there is a cache line, indeed!). if (!ROOTFileDatesOK(key)) { return(new Tuple <bool, T>(false, default)); } // Next, read in as many of the cycles of cache files as there are, // grabbing all the objects we need. var cycleObjects = new List <T>(); int index = 0; bool keepgoing = true; while (keepgoing) { var(found, val) = await LoadCacheData <T>(key, index, varSaver, theVar); keepgoing = found; if (keepgoing) { cycleObjects.Add(val); } index++; } if (cycleObjects.Count == 0 && cycleObjects.All(cval => cval != null)) { return(new Tuple <bool, T>(false, default)); } // Special case for where this a single cycle. We just read them in and push them through the saver // and return them. if (cycleObjects.Count == 1) { return(new Tuple <bool, T>(true, cycleObjects[0])); } else { // More than one cycle object. We will have to add things together before we can do anything with them. if (generateAdder == null) { throw new InvalidOperationException($"Unable to combine data types {typeof(T).Name} because an IAddResult wasn't passed to me!"); } var adder = generateAdder(); var firstObj = await adder.Clone(cycleObjects[0]); var addedValue = cycleObjects.Skip(1) .Aggregate(firstObj, (acc, newv) => adder.Update(acc, newv)); return(new Tuple <bool, T>(true, addedValue)); } }