Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Info

The HashRing implementation as a generic class

Code Block
languagec#
//Fields
SortedDictionary<UInt32, HashRingLocation<T>> _locations;

//Properties
private SortedDictionary<UInt32, HashRingLocation<T>> LocationDictionary
{
     get
     {
          _locations = _locations ?? new SortedDictionary<uint, HashRingLocation<T>>();
          return _locations;
     }
}

public List<HashRingLocation<T>> Locations
{
    get
    {
         return LocationDictionary.Values.ToList()  /// The locations collection; 
    }
}

//Public Methods for Location
public void AddLocation(T item)
{
    item.ThrowIfNull();
    UInt32 key = Hashing.HashItem(item);
    HashRingLocation<T> location = new HashRingLocation<T>(key, item);
    LocationDictionary.Add(key, location);

    var ndx = LocationDictionary.IndexOfKey(key);
    var fromNdx = ndx < LocationDictionary.Count - 1 ? ndx + 1 : ndx;
    var fromLocation = LocationDictionary.ElementAt(fromNdx).Value;

    List<UInt32> keysToRemove = new List<uint>();
    foreach (var node in fromLocation.NodeDictionary.Where(n => n.Key <= key)){
        keysToRemove.Add(node.Key);
        location.NodeDictionary.Add(node.Key, node.Value);
    }
    foreach(var removekey in keysToRemove){
        fromLocation.NodeDictionary.Remove(removekey);
    }
}

//Public Methods for Items
public void AddItem(T item)
{
    item.ThrowIfNull();
    bool putInlastNode = true;
    UInt32 key = Hashing.HashItem(item);
    HashRingNode<T> node = new HashRingNode<T>()
    {
        Key = key,
        Item = item
    };

    foreach(var locationKey in LocationDictionary.Keys){
        if(key < locationKey){
            // Check for key collision
            if (LocationDictionary[locationKey].NodeDictionary.ContainsKey(key)) {
                var checkNode = LocationDictionary[locationKey].NodeDictionary[key].Next;
                while (checkNode != null) {
                    checkNode = checkNode.Next;
                }
                LocationDictionary[locationKey].DuplicateCount++;
                checkNode = new HashRingNode<T>() { Key = key, Item = item };
            }
            else{ LocationDictionary[locationKey].NodeDictionary.Add(key, node); }
            putInlastNode = false;
            break;
        }
    }
    if(putInlastNode && LocationDictionary.Count > 0){
        LocationDictionary.ElementAt(LocationDictionary.Count - 1).Value.NodeDictionary.Add(key, node);
    }
}
public void RemoveItem(T item)
{
    item.ThrowIfNull();
    UInt32 key = Hashing.HashItem(item);
    HashRingLocation<T> foundLocation = null;
    foreach (var locationKey in LocationDictionary.Keys){
        if (key < locationKey)
        {
            foundLocation = LocationDictionary[locationKey];
            break;
        }
    }
    if(foundLocation != null && foundLocation.NodeDictionary.ContainsKey(key)){
        foundLocation.NodeDictionary.Remove(key);
    }
}
Code Block
languagec#
// Is there a location for this item
public bool HasLocation(T item)
{
    item.ThrowIfNull();
    UInt32 key = Hashing.HashItem(item);
    return LocationDictionary.ContainsKey(key);
}
// How many locations does this HashRing have
public int LocationCount
{
    get { return LocationDictionary.Count; }
}
// Get the location for the index
public HashRingLocation<T> LocationAt(int index)
{
    return LocationDictionary.ElementAt(index).Value;
}
// Get the index for the location item
public int LocationIndexFor(T item)
{
    item.ThrowIfNull();
    UInt32 key = Hashing.HashItem(item);
    return LocationDictionary.IndexOfKey(key);
}