using System;
using System.Collections.Generic;
using System.Text;
namespace ScrewTurn.Wiki.SearchEngine {
///
/// Implements a IDocument-SortedBasicWordInfo dictionary which treats IDocuments as value type.
///
/// All instance members are not thread-safe.
public class OccurrenceDictionary : IDictionary {
private Dictionary dictionary;
private Dictionary mappings; // Used for performance purposes
///
/// Initializes a new instance of the class.
///
/// The initial capacity of the dictionary.
/// If is less than or equal to zero.
public OccurrenceDictionary(int capacity) {
if(capacity < 0) throw new ArgumentOutOfRangeException("capacity", "Capacity must be greater than zero");
mappings = new Dictionary(capacity);
dictionary = new Dictionary(capacity);
}
///
/// Initializes a new instance of the class.
///
public OccurrenceDictionary()
: this(10) { }
///
/// Gets the number of elements in the dictionary.
///
public int Count {
get { return dictionary.Count; }
}
///
/// Adds the specified key and value to the dictionary.
///
/// The key of the element to add.
/// The value of the element to add.
/// If or are null.
/// If is already present in the dictionary.
public void Add(IDocument key, SortedBasicWordInfoSet value) {
if(key == null) throw new ArgumentNullException("key");
if(value == null) throw new ArgumentNullException("value");
if(ContainsKey(key)) throw new ArgumentException("The specified key is already contained in the dictionary", "key");
mappings.Add(key.Name, key);
dictionary.Add(key, value);
}
///
/// Adds the specified key-value pair to the dictionary.
///
/// The key-value pair to add.
public void Add(KeyValuePair item) {
Add(item.Key, item.Value);
}
///
/// Determines whether the dictionary contains the specified key.
///
/// The key to locate.
/// true if the dictionary contains the specified key, false otherwise.
/// If is null.
public bool ContainsKey(IDocument key) {
if(key == null) throw new ArgumentNullException("key");
return FindKey(key) != null;
}
///
/// Gets the keys of the dictionary.
///
public ICollection Keys {
get { return dictionary.Keys; }
}
///
/// Removes an element from the dictionary.
///
/// The key of the element to remove.
/// true if the element is removed, false otherwise.
/// If is null.
public bool Remove(IDocument key) {
if(key == null) throw new ArgumentNullException("key");
try {
// The removal is considered to be successful even if no word mappings are removed
RemoveExtended(key, uint.MaxValue);
return true;
}
catch(KeyNotFoundException) {
return false;
}
}
///
/// Removes an element from the dictionary.
///
/// The element to remove.
/// true if the element is removed, false otherwise.
public bool Remove(KeyValuePair item) {
return Remove(item.Key);
}
///
/// Removes an element from the dictionary.
///
/// The key of the element to remove.
/// The unique ID of the word that is being removed.
/// The list of removed words mappings, in dumpable format.
/// If key is not found, a is thrown.
/// If is null.
/// If is not present in the dictionary.
public List RemoveExtended(IDocument key, uint wordId) {
if(key == null) throw new ArgumentNullException("key");
IDocument target = FindKey(key);
if(target == null) throw new KeyNotFoundException("Specified IDocument was not found");
else {
IDocument mappedDoc = mappings[key.Name];
if(mappings.Remove(target.Name)) {
// Prepare the list of DumpedWordMapping objects
SortedBasicWordInfoSet set = dictionary[mappedDoc];
List dump = new List(set.Count);
foreach(BasicWordInfo w in set) {
dump.Add(new DumpedWordMapping(wordId, key.ID, w));
}
if(!dictionary.Remove(target)) throw new InvalidOperationException("Internal data is broken");
return dump;
}
else throw new InvalidOperationException("Internal data is broken");
}
}
///
/// Finds an actual key in the mappings dictionary.
///
/// The document.
/// The key, or null.
/// If is null.
private IDocument FindKey(IDocument key) {
if(key == null) throw new ArgumentNullException("key");
IDocument target = null;
if(mappings.TryGetValue(key.Name, out target)) return target;
else return null;
}
///
/// Tries to retrieve a value from the dictionary.
///
/// The key of the value to retrieve.
/// The resulting value, or null.
/// true if the value is retrieved, false otherwise.
/// If is null.
public bool TryGetValue(IDocument key, out SortedBasicWordInfoSet value) {
if(key == null) throw new ArgumentNullException("key");
IDocument target = FindKey(key);
if(target == null) {
value = null;
return false;
}
else {
value = dictionary[target];
return true;
}
}
///
/// Gets the values of the dictionary.
///
public ICollection Values {
get { return dictionary.Values; }
}
///
/// Gets or sets a value in the dictionary.
///
/// The key of the value to ger or set.
/// The value.
/// If is null.
/// If the key is not found.
public SortedBasicWordInfoSet this[IDocument key] {
get {
if(key == null) throw new ArgumentNullException("key");
IDocument target = FindKey(key);
if(target == null) throw new IndexOutOfRangeException("The specified key was not found");
else return dictionary[target];
}
set {
if(key == null) throw new ArgumentNullException("key");
if(value == null) throw new ArgumentNullException("value");
IDocument target = FindKey(key);
if(target == null) throw new IndexOutOfRangeException("The specified key was not found");
else dictionary[target] = value;
}
}
///
/// Clears the dictionary.
///
public void Clear() {
mappings.Clear();
dictionary.Clear();
}
///
/// Determines whether the dictionary contains an element.
///
/// The key-value pair representing the element.
/// true if the dictionary contains the element, false otherwise.
public bool Contains(KeyValuePair item) {
return ContainsKey(item.Key);
}
///
/// Gets a value indicating whether the dictionary is read-only.
///
public bool IsReadOnly {
get { return false; }
}
///
/// Copies the content of the dictionary to a key-value pairs array.
///
/// The output array.
/// The index at which the copy begins.
/// If is null.
public void CopyTo(KeyValuePair[] array, int arrayIndex) {
if(array == null) throw new ArgumentNullException("array");
int i = 0;
foreach(KeyValuePair pair in dictionary) {
array[arrayIndex + i] = pair;
i++;
}
}
///
/// Returns an enumerator that iterates through the elements in the dictionary.
///
/// The iterator.
public IEnumerator> GetEnumerator() {
return dictionary.GetEnumerator();
}
///
/// Returns an enumerator that iterates through the elements in the dictionary.
///
/// The iterator.
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return dictionary.GetEnumerator();
}
}
}