andrew4582

ReferenceSet

Aug 2nd, 2011
244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.94 KB | None | 0 0
  1. using System;
  2.  
  3. namespace Core.Collections {
  4.     /// <summary>
  5.     /// Detects cycles by detecting duplicates in the a set of object references
  6.     /// </summary>
  7.     public class ReferenceSet {
  8.         #region Constants
  9.  
  10.         private static readonly object[] EmptyArray = new object[0];
  11.         private const int InitialSize = 4;
  12.         private const int GrowthFactor = 2;
  13.  
  14.         #endregion Constants
  15.  
  16.         #region Fields
  17.  
  18.         private object[] array = ReferenceSet.EmptyArray;
  19.         private int size;
  20.  
  21.         #endregion Fields
  22.  
  23.         #region Methods
  24.  
  25.         /// <summary>
  26.         /// Adds a reference to the set
  27.         /// </summary>
  28.         /// <param name="item"></param>
  29.         /// <returns>true if object already existed within set</returns>
  30.         public bool Add(object item) {
  31.             if(item == null || item is ValueType || item is string) {
  32.                 // ignore these as they are not indicative of graph cycles
  33.                 return false;
  34.             }
  35.  
  36.             // check for duplicates
  37.             for(int i = this.size - 1;i >= 0;i--) {
  38.                 if(Object.ReferenceEquals(this.array[i],item)) {
  39.                     return true;
  40.                 }
  41.             }
  42.  
  43.             if(this.size >= this.array.Length) {
  44.                 object[] destArray = new object[(this.array.Length == 0) ? InitialSize : (GrowthFactor * this.array.Length)];
  45.                 if(this.size > 0) {
  46.                     Array.Copy(this.array,0,destArray,0,this.size);
  47.                 }
  48.                 this.array = destArray;
  49.             }
  50.  
  51.             this.array[this.size++] = item;
  52.  
  53.             return false;
  54.         }
  55.  
  56.         /// <summary>
  57.         /// Removes a reference from the set
  58.         /// </summary>
  59.         /// <param name="item"></param>
  60.         public void Remove(object item) {
  61.             if(item == null || item is ValueType || item is string) {
  62.                 // ignore these as they are not indicative of graph cycles
  63.                 return;
  64.             }
  65.  
  66.             // check for existance
  67.             for(int i = this.size - 1;i >= 0;i--) {
  68.                 if(Object.ReferenceEquals(this.array[i],item)) {
  69.                     if(i + 1 == this.size) {
  70.                         this.array[i] = null;
  71.                         this.size--;
  72.                     }
  73.                     else {
  74.                         // according to MSDN, this is safe: "If sourceArray and destinationArray overlap,
  75.                         // this method behaves as if the original values of sourceArray were preserved in
  76.                         // a temporary location before destinationArray is overwritten. "
  77.  
  78.                         // shift buffer to zero aligned
  79.                         Array.Copy(this.array,i + 1,this.array,i,this.size - i);
  80.                     }
  81.                     return;
  82.                 }
  83.             }
  84.  
  85.             return;
  86.         }
  87.  
  88.         #endregion Methods
  89.     }
  90.  
  91. }
Advertisement
Add Comment
Please, Sign In to add comment