private Value[][] GetInternal(GetRequest[] valuesToGet, int backupIndex) { var results = new Value[valuesToGet.Length][]; var groupedByEndpoint = from req in valuesToGet let er = new { OriginalIndex = Array.IndexOf(valuesToGet, req), Get = new ExtendedGetRequest { Key = req.Key, SpecifiedVersion = req.SpecifiedVersion, Segment = GetSegmentFromKey(req.Key), } } group er by GetEndpointByBackupIndex(topology.Segments[er.Get.Segment], backupIndex) into g select g; foreach (var endpoint in groupedByEndpoint) { if (endpoint.Key == null) throw new NoMoreBackupsException(); var requests = endpoint.ToArray(); var getRequests = requests.Select(x => x.Get).ToArray(); var putsResults = GetGetsResults(endpoint.Key, getRequests, backupIndex); for (var i = 0; i < putsResults.Length; i++) { results[requests[i].OriginalIndex] = putsResults[i]; } } return results; }
public Value[] Get(GetRequest request) { var values = new List<Value>(); var activeVersions = request.SpecifiedVersion == null ? GatherActiveVersions(request.Key) : new[] { request.SpecifiedVersion }; var foundAllInCache = true; foreach (var activeVersion in activeVersions) { var cachedValue = cache[GetKey(request.Key, activeVersion)] as Value; if (cachedValue == null || (cachedValue.ExpiresAt.HasValue && DateTime.Now < cachedValue.ExpiresAt.Value)) { values.Clear(); foundAllInCache = false; break; } values.Add(cachedValue); } if (foundAllInCache) return values.ToArray(); ApplyToKeyAndActiveVersions(data, activeVersions, request.Key, version => { var value = ReadValueFromDataTable(version, request.Key); if (value != null) values.Add(value); else // remove it from the cache if exists commitSyncronization.Add(() => cache.Remove(GetKey(request.Key, version))); }); commitSyncronization.Add(delegate { foreach (var value in values) { cache[GetKey(value.Key, value.Version)] = value; } cache[GetKey(request.Key)] = activeVersions; }); return values.ToArray(); }