SearchBox/SearchBox/SearchBox.cs

68 lines
1.9 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace LibSearchBox
{
public class SearchBoxException : Exception { public SearchBoxException(string message) : base(message) { } }
[JsonObject(MemberSerialization.OptIn)]
public class SearchBox
{
private IdMap idMap = new IdMap();
[JsonProperty("ids")]
public Dictionary<int, string> IdMap {
get {
Dictionary<int, string> result = idMap.MapOut;
if (result.Count == 0) return null;
return result;
}
set {
if (value == null) return;
idMap.Import(value);
}
}
[JsonProperty]
public ConcurrentDictionary<int, DocumentMeta> metaTable = new ConcurrentDictionary<int, DocumentMeta>();
[JsonProperty]
public InvertedIndex index = new InvertedIndex();
public SearchBox()
{
}
public void AddDocument(string title, IEnumerable<string> tags, string content)
{
DocumentMeta info = new DocumentMeta(title, tags);
int id = idMap.GetId(info.Title);
metaTable.AddOrUpdate(id, info, (key, oldValue) => info);
Index upsideIndex = new Index(content);
index.AddIndex(id, upsideIndex);
}
public void UpdateDocument(string title, IEnumerable<string> newTags, string oldContent, string newContent)
{
int id = idMap.GetId(title);
DocumentMeta info = metaTable[id];
info.ReplaceTags(newTags);
Index oldIndex = new Index(oldContent), newIndex = new Index(newContent);
if (!index.ReplaceIndex(id, oldIndex, newIndex))
throw new SearchBoxException($"Error: Failed to replace index for document with title {title}.");
}
public void RemoveDocument(string title)
{
int id = idMap.DeletePageName(title);
metaTable.TryRemove(id, out DocumentMeta noop);
if (!index.RemoveById(id))
throw new SearchBoxException($"Failed to remove page with title '{title}' from inverted index.");
}
}
}