Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace PocketGoogle
- {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- public class Indexer : IIndexer
- {
- protected Registry<string, int, List<int>> registry;
- private readonly HashSet<char> stdSeparators = new HashSet<char>() { ' ', '.', ',', '!', '?', ':', '-', '\r', '\n' };
- public Indexer()
- {
- registry = new Registry<string, int, List<int>>();
- }
- public void Add(int id, string documentText)
- {
- int pointer = 0;
- while (pointer < documentText.Length)
- {
- pointer = SkipSeparators(pointer, documentText);
- var length = GetPartLength(documentText, pointer);
- var word = documentText.Substring(pointer, length);
- AddToRegistry(id, pointer, word);
- pointer += length;
- }
- }
- public List<int> GetIds(string word)
- {
- return registry.GetNestedKeys(word).ToList();
- }
- public List<int> GetPositions(int id, string word)
- {
- if (registry.ContainsKey(word))
- {
- if (registry[word].ContainsKey(id))
- return registry[word][id];
- }
- return new List<int>();
- }
- public void Remove(int id)
- {
- registry.Cleanup(id);
- }
- private int GetPartLength(string src, int startFrom)
- {
- var end = startFrom;
- while (end < src.Length && !stdSeparators.Contains(src[end]))
- end++;
- return end - startFrom;
- }
- private int SkipSeparators(int pointer, string documentText)
- {
- var temp = pointer;
- while (temp < documentText.Length && stdSeparators.Contains(documentText[temp]))
- temp++;
- return temp;
- }
- private void AddToRegistry(int docID, int pos, string word)
- {
- if (registry.ContainsKey(word))
- {
- if (registry[word].ContainsKey(docID))
- registry[word][docID].Add(pos);
- else
- registry[word].Add(docID, new List<int>() { pos });
- return;
- }
- registry.AddBranch(word, new Dictionary<int, List<int>>() { { docID, new List<int>() { pos } } });
- }
- }
- public sealed class Registry<TRoot, TKey, TValue> : Dictionary<TRoot, Dictionary<TKey, TValue>>
- {
- //Класс унаследован от стандартного типа, по этому добавлены все конструкторы, объявленные в Dictionary<>
- //За исключением конструктора с параметрами для сериализации, ибо Registry<> сериализацию не поддерживает. Хотя, в идеале, надо бы.
- public Registry() : base() { }
- public Registry(int depth) : base(depth) { }
- public Registry(IEqualityComparer<TRoot> comparer) : base(comparer) { }
- public Registry(IDictionary<TRoot, Dictionary<TKey, TValue>> initiator) : base(initiator) { }
- public Registry(int depth, IEqualityComparer<TRoot> comparer) : base(depth, comparer) { }
- public Registry(IDictionary<TRoot, Dictionary<TKey, TValue>> initiator, IEqualityComparer<TRoot> comparer) : base(initiator, comparer) { }
- public void AddBranch(TRoot branchID, Dictionary<TKey, TValue> branch)
- {
- if (ContainsKey(branchID))
- throw new RegistryBranchCreationException($"Can not create new branch with ID {branchID}, cause branch with such ID already exists");
- Add(branchID, branch);
- }
- public void BranchExtend(TRoot branchID, Dictionary<TKey, TValue> branch)
- {
- if (ContainsKey(branchID))
- {
- foreach (var pair in branch)
- this[branchID].Add(pair.Key, pair.Value);
- return;
- }
- AddBranch(branchID, branch);
- }
- /// <summary>
- /// Возвращает все ключи, находящиеся в разделе указанного корневого ключа
- /// </summary>
- /// <param name="rootKey">Корневой ключ</param>
- public IList<TKey> GetNestedKeys(TRoot rootKey)
- {
- if (!ContainsKey(rootKey))
- return new List<TKey>();
- return this[rootKey].Keys.ToList();
- }
- /// <summary>
- /// Перебирает все корневые ключи реестра, определяя наличие в соответсвующем разлделе указанного вложенного ключа,
- /// и удаляет его в случае обнаружения
- /// </summary>
- /// <param name="value">Искомое значение вложенного ключа</param>
- public void Cleanup(TKey key)
- {
- foreach (var branch in Keys)
- {
- this[branch].Remove(key);
- }
- }
- }
- internal sealed class RegistryBranchCreationException : Exception
- {
- public RegistryBranchCreationException() : base() { }
- public RegistryBranchCreationException(string error) : base(error) { }
- public RegistryBranchCreationException(string error, Exception innerExc) : base(error, innerExc) { }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement