public static string MergeVectors(List <string> changeVectors) { if (_mergeVectorBuffer == null) { _mergeVectorBuffer = new EquatableList <ChangeVectorEntry>(); } _mergeVectorBuffer.Clear(); for (int i = 0; i < changeVectors.Count; i++) { ChangeVectorParser.MergeChangeVector(changeVectors[i], _mergeVectorBuffer); } return(_mergeVectorBuffer.SerializeVector()); }
public static string MergeVectors(string vectorAstring, string vectorBstring) { if (string.IsNullOrEmpty(vectorAstring)) { return(vectorBstring); } if (string.IsNullOrEmpty(vectorBstring)) { return(vectorAstring); } _mergeVectorBuffer ??= new List <ChangeVectorEntry>(); _mergeVectorBuffer.Clear(); ChangeVectorParser.MergeChangeVector(vectorAstring, _mergeVectorBuffer); ChangeVectorParser.MergeChangeVector(vectorBstring, _mergeVectorBuffer); return(_mergeVectorBuffer.SerializeVector()); }
private async Task WaitForIndexesAsync(TimeSpan timeout, string lastChangeVector, long lastTombstoneEtag, HashSet <string> modifiedCollections) { // waitForIndexesTimeout=timespan & waitForIndexThrow=false (default true) // waitForSpecificIndex=specific index1 & waitForSpecificIndex=specific index 2 if (modifiedCollections.Count == 0) { return; } var throwOnTimeout = GetBoolValueQueryString("waitForIndexThrow", required: false) ?? true; var indexesToWait = new List <WaitForIndexItem>(); var indexesToCheck = GetImpactedIndexesToWaitForToBecomeNonStale(modifiedCollections); if (indexesToCheck.Count == 0) { return; } var sp = Stopwatch.StartNew(); // we take the awaiter _before_ the indexing transaction happens, // so if there are any changes, it will already happen to it, and we'll // query the index again. This is important because of: // http://issues.hibernatingrhinos.com/issue/RavenDB-5576 foreach (var index in indexesToCheck) { var indexToWait = new WaitForIndexItem { Index = index, IndexBatchAwaiter = index.GetIndexingBatchAwaiter(), WaitForIndexing = new AsyncWaitForIndexing(sp, timeout, index) }; indexesToWait.Add(indexToWait); } using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context)) { while (true) { var hadStaleIndexes = false; using (context.OpenReadTransaction()) { foreach (var waitForIndexItem in indexesToWait) { var lastEtag = lastChangeVector != null?ChangeVectorParser.GetEtagByNode(lastChangeVector, ServerStore.NodeTag) : 0; var cutoffEtag = Math.Max(lastEtag, lastTombstoneEtag); if (waitForIndexItem.Index.IsStale(context, cutoffEtag) == false) { continue; } hadStaleIndexes = true; await waitForIndexItem.WaitForIndexing.WaitForIndexingAsync(waitForIndexItem.IndexBatchAwaiter); if (waitForIndexItem.WaitForIndexing.TimeoutExceeded && throwOnTimeout) { throw new TimeoutException( $"After waiting for {sp.Elapsed}, could not verify that {indexesToCheck.Count} " + $"indexes has caught up with the changes as of etag: {cutoffEtag}"); } } } if (hadStaleIndexes == false) { return; } } } }