Ejemplo n.º 1
0
        public void RemoveDocumentsMatching([NotNull] Func <DocumentInfo, bool> predicate)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException("predicate");
            }

            lock (lockIndex)
            {
                var oldDocuments         = state.documents;
                var allDocumentsToRemove = new HashSet <DocumentInfo>(oldDocuments.Where(predicate));
                if (!allDocumentsToRemove.Any())
                {
                    return;
                }
                var newDocuments = oldDocuments.Except(allDocumentsToRemove);

                predicate = allDocumentsToRemove.Contains;

                var oldIndex = state.wordIndex;
                var newIndex = new InternalSortedList <string, IImmutableSet <DocumentInfo> >(this.wordComparer, oldIndex.Count);
                foreach (var item in oldIndex)
                {
                    var newValue = item.Value.Except(item.Value.Where(predicate));
                    if (newValue.Count > 0)
                    {
                        newIndex.AddSorted(item.Key, newValue);
                    }
                }
                this.state = new State(newIndex, newDocuments);
            }
        }
Ejemplo n.º 2
0
        public Task Merge([NotNull] DocumentInfo document, [NotNull] IEnumerable <string> indexWords)
        {
            if (document == null)
            {
                throw new ArgumentNullException("document");
            }
            if (indexWords == null)
            {
                throw new ArgumentNullException("indexWords");
            }

            var  sourceWords        = new SortedSet <string>(indexWords, wordComparer).ToList();
            bool hasWords           = sourceWords.Any();
            var  singleDocumentList = ImmutableHashSet.Create(document);

            // Merge join sorted word list with wordIndex list
            lock (lockIndex)
            {
                IImmutableSet <DocumentInfo> oldDocuments = state.documents;
                IImmutableSet <DocumentInfo> newDocuments;
                bool isNewDocument;
                if (hasWords)
                {
                    newDocuments  = oldDocuments.Add(document);
                    isNewDocument = newDocuments != oldDocuments; // new if was added to document set
                }
                else
                {
                    newDocuments  = oldDocuments.Remove(document);
                    isNewDocument = newDocuments == oldDocuments; // new if wasn't contained before in document set
                    if (isNewDocument)
                    {
                        return(CompletedTask.Instance);
                    }
                }

                var oldIndex  = state.wordIndex;
                var newIndex  = new InternalSortedList <string, IImmutableSet <DocumentInfo> >(this.wordComparer, oldIndex.Count + sourceWords.Count);
                int idxSource = 0;
                int idxTarget = 0;

                while (true)
                {
                    int compareResult = 0;
                    if (idxTarget >= oldIndex.Count)
                    {
                        compareResult = -1;
                    }
                    if (idxSource >= sourceWords.Count)
                    {
                        if (compareResult != 0)
                        {
                            break;
                        }
                        compareResult = 1;
                    }
                    if (compareResult == 0)
                    {
                        compareResult = wordComparer.Compare(sourceWords[idxSource], oldIndex[idxTarget].Key);
                    }

                    if (compareResult < 0)
                    {
                        // add and include
                        newIndex.AddSorted(sourceWords[idxSource], singleDocumentList);
                        idxSource += 1;
                        //idxTarget += 1;
                    }
                    else if (compareResult > 0)
                    {
                        var item = oldIndex[idxTarget];
                        if (!isNewDocument)
                        {
                            var newValue = item.Value.Remove(document);
                            if (newValue.Count > 0)
                            {
                                newIndex.AddSorted(item.Key, newValue);
                            }
                        }
                        else
                        {
                            newIndex.AddSorted(item.Key, item.Value);
                        }
                        idxTarget += 1;
                    }
                    else
                    {
                        var item = oldIndex[idxTarget];
                        newIndex.AddSorted(item.Key, item.Value.Add(document));
                        idxSource += 1;
                        idxTarget += 1;
                    }
                }
                this.state = new State(newIndex, newDocuments);
            }
            return(CompletedTask.Instance);
        }