Beispiel #1
0
    public override T[] ToArray()
    {
      T[] res = new T[size];
      int index = 0;

#if !REFBUCKET
      if (defaultvalid)
        res[index++] = defaultitem;
#endif
      for (int i = 0; i < table.Length; i++)
      {
        Bucket b = table[i];
#if LINEARPROBING
#if REFBUCKET
        if (b != null)
          res[index++] = b.item;
#else
        if (!isnull(b.item))
          res[index++] = b.item;
#endif
#else
#if REFBUCKET
        while (b != null)
        {
          res[index++] = b.item;
          b = b.overflow;
        }
#else
				if (!isnull(b.item))
				{
					res[index++] = b.item;

					OverflowBucket ob = b.overflow;

					while (ob != null)
					{
						res[index++] = ob.item;
						ob = ob.overflow;
					}
				}
#endif
#endif
      }

      Debug.Assert(size == index);
      return res;
    }
Beispiel #2
0
    private bool remove(ref T item)
    {

      if (size == 0)
        return false;
#if LINEARPROBING
#if REFBUCKET
      int hashval = gethashcode(item);
      int index = hv2i(hashval);
      Bucket b = table[index];

      while (b != null)
      {
        if (equals(item, b.item))
        {
          //ref
          item = table[index].item;
          table[index] = null;

          //Algorithm R
          int j = (index + 1) & indexmask;

          b = table[j];
          while (b != null)
          {
            int k = hv2i(b.hashval);

            if ((k <= index && index < j) || (index < j && j < k) || (j < k && k <= index))
            //if (index > j ? (j < k && k <= index): (k <= index || j < k) )
            {
              table[index] = b;
              table[j] = null;
              index = j;
            }

            j = (j + 1) & indexmask;
            b = table[j];
          }

          goto found;
        }

        b = table[index = indexmask & (index + 1)];
      }
      return false;
#else
      if (isnull(item))
      {
        if (!defaultvalid)
          return false;

        //ref
        item = defaultitem;
        defaultvalid = false;
        defaultitem = default(T); //No spaceleaks!
      }
      else
      {
        int hashval = gethashcode(item);
        int index = hv2i(hashval);
        T t = table[index].item;

        while (!isnull(t))
        {
          if (equals(item, t))
          {
            //ref
            item = table[index].item;
            table[index].item = default(T);

            //algorithm R
            int j = (index + 1) & indexmask;
            Bucket b = table[j];

            while (!isnull(b.item))
            {
              int k = hv2i(b.hashval);

              if ((k <= index && index < j) || (index < j && j < k) || (j < k && k <= index))
              {
                table[index] = b;
                table[j].item = default(T);
                index = j;
              }

              j = (j + 1) & indexmask;
              b = table[j];
            }

            goto found;
          }

          t = table[index = indexmask & (index + 1)].item;
        }

        return false;
      }
#endif
    found:
#else
#if REFBUCKET
      int hashval = gethashcode(item);
      int index = hv2i(hashval);
      Bucket b = table[index], bold;

      if (b == null)
        return false;

      if (equals(item, b.item))
      {
        //ref
        item = b.item;
        table[index] = b.overflow;
      }
      else
      {
        bold = b;
        b = b.overflow;
        while (b != null && !equals(item, b.item))
        {
          bold = b;
          b = b.overflow;
        }

        if (b == null)
          return false;

        //ref
        item = b.item;
        bold.overflow = b.overflow;
      }

#else
			if (isnull(item))
			{
				if (!defaultvalid)
					return false;

				//ref
				item = defaultitem;
				defaultvalid = false;
				defaultitem = default(T); //No spaceleaks!
			}
			else
			{
				int hashval = gethashcode(item);
				int index = hv2i(hashval);
				Bucket b = table[index];
				OverflowBucket ob = b.overflow;

				if (equals(item, b.item))
				{
					//ref
					item = b.item;
					if (ob == null)
					{
						table[index] = new Bucket();
					}
					else
					{
						b = new Bucket(ob.item, ob.hashval);
						b.overflow = ob.overflow;
						table[index] = b;
					}
				}
				else
				{
					if (ob == null)
						return false;

					if (equals(item, ob.item)) 
					{
						//ref
						item=ob.item;
						table[index].overflow = ob.overflow;
					}
					else
					{
						while (ob.overflow != null)
							if (equals(item, ob.overflow.item))
							{
								//ref
								item = ob.overflow.item;
								break;
							}
							else
								ob = ob.overflow;

						if (ob.overflow == null)
							return false;

						ob.overflow = ob.overflow.overflow;
					}
				}
			}
#endif
#endif
      size--;

      return true;
    }
Beispiel #3
0
    /// <summary>
    /// Search for an item equal (according to itemequalityComparer) to the supplied item.  
    /// </summary>
    /// <param name="item"></param>
    /// <param name="add">If true, add item to table if not found.</param>
    /// <param name="update">If true, update table entry if item found.</param>
    /// <param name="raise">If true raise events</param>
    /// <returns>True if found</returns>
    private bool searchoradd(ref T item, bool add, bool update, bool raise)
    {

#if LINEARPROBING
#if REFBUCKET
      int hashval = gethashcode(item);
      int i = hv2i(hashval);
      Bucket b = table[i];

      while (b != null)
      {
        T olditem = b.item;
        if (equals(olditem, item))
        {
          if (update)
            b.item = item;
          else
            item = olditem;

          if (raise && update)
            raiseForUpdate(item, olditem);
          return true;
        }

        b = table[i = indexmask & (i + 1)];
      }

      if (!add) goto notfound;

      table[i] = new Bucket(item, hashval);

#else
      if (isnull(item))
      {
        if (defaultvalid)
        {
          T olditem = defaultitem;
          if (update)
            defaultitem = item;
          else
            item = defaultitem;

          if (raise && update)
            raiseForUpdate(item, olditem);
          return true;
        }

        if (!add) goto notfound;

        defaultvalid = true;
        defaultitem = item;
      }
      else
      {
        int hashval = gethashcode(item);
        int i = hv2i(hashval);
        T t = table[i].item;

        while (!isnull(t))
        {
          if (equals(t, item))
          {
            if (update)
              table[i].item = item;
            else
              item = t;

            if (raise && update)
              raiseForUpdate(item, t);
            return true;
          }

          t = table[i = indexmask & (i + 1)].item;
        }

        if (!add) goto notfound;

        table[i] = new Bucket(item, hashval);
      }
#endif
#else
#if REFBUCKET
      int hashval = gethashcode(item);
      int i = hv2i(hashval);
      Bucket b = table[i], bold = null;

      if (b != null)
      {
        while (b != null)
        {
          T olditem = b.item;
          if (equals(olditem, item))
          {
            if (update)
            {
              b.item = item;
            }
            if (raise && update)
              raiseForUpdate(item, olditem);
            // bug20071112:
            item = olditem;
            return true;
          }

          bold = b;
          b = b.overflow;
        }

        if (!add) goto notfound;

        bold.overflow = new Bucket(item, hashval, null);
      }
      else
      {
        if (!add) goto notfound;

        table[i] = new Bucket(item, hashval, null);
      }
#else
			if (isnull(item))
			{
        if (defaultvalid)
        {
          T olditem = defaultitem;
          if (update)
            defaultitem = item;
          else
            item = defaultitem;

          if (raise && update)
            raiseForUpdate(item, olditem);
          return true;
        }

				if (!add) goto notfound;

				defaultvalid = true;
				defaultitem = item;
			}
			else
			{
				int hashval = gethashcode(item);
				int i = hv2i(hashval);
				Bucket b = table[i];

				if (!isnull(b.item))
				{
					if (equals(b.item, item))
					{
						if (update)
							table[i].item = item;
						else
							item = b.item;

            if (raise && update)
              raiseForUpdate(item, b.item);
            return true;
					}

					OverflowBucket ob = table[i].overflow;

					if (ob == null)
					{
						if (!add) goto notfound;

						table[i].overflow = new OverflowBucket(item, hashval, null);
					}
					else
					{
            T olditem = ob.item;
						while (ob.overflow != null)
						{
              if (equals(item, olditem))
              {
                if (update)
                  ob.item = item;
                else
                  item = olditem;

                if (raise && update)
                  raiseForUpdate(item, olditem);
                return true;
              }

							ob = ob.overflow;
              olditem = ob.item;
						}

            if (equals(item, olditem))
            {
              if (update)
                ob.item = item;
              else
                item = olditem;

              if (raise && update)
                raiseForUpdate(item, olditem);
              return true;
            }

						if (!add) goto notfound;

						ob.overflow = new OverflowBucket(item, hashval, null);
					}
				}
				else
				{
					if (!add) goto notfound;

					table[i] = new Bucket(item, hashval);
				}
			}
#endif
#endif
      size++;
      if (size > resizethreshhold)
        expand();
    notfound:
      if (raise && add)
        raiseForAdd(item);
      if (update)
        item = default(T);
      return false;
    }
Beispiel #4
0
    void resize(int bits)
    {
      //Console.WriteLine(String.Format("Resize to {0} bits", bits));
      this.bits = bits;
      bitsc = 32 - bits;
      indexmask = (1 << bits) - 1;

      Bucket[] newtable = new Bucket[indexmask + 1];

      for (int i = 0, s = table.Length; i < s; i++)
      {
        Bucket b = table[i];

#if LINEARPROBING
#if REFBUCKET
        if (b != null)
        {
          int j = hv2i(b.hashval);

          while (newtable[j] != null) { j = indexmask & (j + 1); }

          newtable[j] = b;
        }
#else
        if (!isnull(b.item))
        {
          int j = hv2i(b.hashval);

          while (!isnull(newtable[j].item)) { j = indexmask & (j + 1); }

          newtable[j] = b;
        }
#endif
#else
#if REFBUCKET
        while (b != null)
        {
          int j = hv2i(b.hashval);

          newtable[j] = new Bucket(b.item, b.hashval, newtable[j]);
          b = b.overflow;
        }
#else
				if (!isnull(b.item))
				{
					insert(b.item, b.hashval, newtable);

					OverflowBucket ob = b.overflow;

					while (ob != null)
					{
						insert(ob.item, ob.hashval, newtable);
						ob = ob.overflow;
					}
				}
#endif
#endif
      }

      table = newtable;
      resizethreshhold = (int)(table.Length * fillfactor);
      //Console.WriteLine(String.Format("Resize to {0} bits done", bits));
    }
Beispiel #5
0
			internal OverflowBucket(T item, int hashval, OverflowBucket overflow)
			{
				this.item = item;
				this.hashval = hashval;
				this.overflow = overflow;
			}
Beispiel #6
0
    public ISortedDictionary<int, int> BucketCostDistribution()
    {
      TreeDictionary<int, int> res = new TreeDictionary<int, int>();
#if LINEARPROBING
      int count = 0;
#if REFBUCKET
      while (table[count] != null)
#else
      while (!isnull(table[count].item))
#endif
        count++;
      for (int i = table.Length - 1; i >= 0; i--)
      {
#if REFBUCKET
        if (table[i] != null)
#else
        if (!isnull(table[i].item))
#endif
          count++;
        else
          count = 0;
        if (res.Contains(count))
          res[count]++;
        else
          res[count] = 1;
      }

      return res;
#else
      for (int i = 0, s = table.Length; i < s; i++)
      {
        int count = 0;
#if REFBUCKET
        Bucket b = table[i];

        while (b != null)
        {
          count++;
          b = b.overflow;
        }
#else
				Bucket b = table[i];

				if (!isnull(b.item))
				{
					count = 1;

					OverflowBucket ob = b.overflow;

					while (ob != null)
					{
						count++;
						ob = ob.overflow;
					}
				}
#endif
        if (res.Contains(count))
          res[count]++;
        else
          res[count] = 1;
      }

      return res;
#endif
    }
Beispiel #7
0
    public virtual bool Check()
    {
      int count = 0;
#if LINEARPROBING
      int lasthole = table.Length - 1;

#if REFBUCKET
      while (lasthole >= 0 && table[lasthole] != null)
#else
      while (lasthole >= 0 && !isnull(table[lasthole].item))
#endif
      {
        lasthole--;
        count++;
      }

      if (lasthole < 0)
      {
        Console.WriteLine("Table is completely filled!");
        return false;
      }

      for (int cellindex = lasthole + 1, s = table.Length; cellindex < s; cellindex++)
      {
        Bucket b = table[cellindex];
        int hashindex = hv2i(b.hashval);

        if (hashindex <= lasthole || hashindex > cellindex)
        {
          Console.WriteLine("Bad cell item={0}, hashval={1}, hashindex={2}, cellindex={3}, lasthole={4}", b.item, b.hashval, hashindex, cellindex, lasthole);
          return false;
        }
      }

      int latesthole = -1;

      for (int cellindex = 0; cellindex < lasthole; cellindex++)
      {
        Bucket b = table[cellindex];

#if REFBUCKET
        if (b != null)
#else
        if (!isnull(b.item))
#endif
        {
          count++;

          int hashindex = hv2i(b.hashval);

          if (cellindex < hashindex && hashindex <= lasthole)
          {
            Console.WriteLine("Bad cell item={0}, hashval={1}, hashindex={2}, cellindex={3}, latesthole={4}", b.item, b.hashval, hashindex, cellindex, latesthole);
            return false;
          }
        }
        else
        {
          latesthole = cellindex;
          break;
        }
      }

      for (int cellindex = latesthole + 1; cellindex < lasthole; cellindex++)
      {
        Bucket b = table[cellindex];

#if REFBUCKET
        if (b != null)
#else
        if (!isnull(b.item))
#endif
        {
          count++;

          int hashindex = hv2i(b.hashval);

          if (hashindex <= latesthole || cellindex < hashindex)
          {
            Console.WriteLine("Bad cell item={0}, hashval={1}, hashindex={2}, cellindex={3}, latesthole={4}", b.item, b.hashval, hashindex, cellindex, latesthole);
            return false;
          }
        }
        else
        {
          latesthole = cellindex;
        }
      }

      return true;
#else
      bool retval = true;

      if (bitsc != 32 - bits)
      {
        Console.WriteLine("bitsc != 32 - bits ({0}, {1})", bitsc, bits);
        retval = false;
      }
      if (indexmask != (1 << bits) - 1)
      {
        Console.WriteLine("indexmask != (1 << bits) - 1 ({0}, {1})", indexmask, bits);
        retval = false;
      }
      if (table.Length != indexmask + 1)
      {
        Console.WriteLine("table.Length != indexmask + 1 ({0}, {1})", table.Length, indexmask);
        retval = false;
      }
      if (bitsc != 32 - bits)
      {
        Console.WriteLine("resizethreshhold != (int)(table.Length * fillfactor) ({0}, {1}, {2})", resizethreshhold, table.Length, fillfactor);
        retval = false;
      }

      for (int i = 0, s = table.Length; i < s; i++)
      {
        int level = 0;
        Bucket b = table[i];
#if REFBUCKET
        while (b != null)
        {
          if (i != hv2i(b.hashval))
          {
            Console.WriteLine("Bad cell item={0}, hashval={1}, index={2}, level={3}", b.item, b.hashval, i, level);
            retval = false;
          }

          count++;
          level++;
          b = b.overflow;
        }
#else
				if (!isnull(b.item))
				{
					count++;
					if (i != hv2i(b.hashval))
					{
						Console.WriteLine("Bad cell item={0}, hashval={1}, index={2}, level={3}", b.item, b.hashval, i, level);
						retval = false;
					}

					OverflowBucket ob = b.overflow;

					while (ob != null)
					{
						level++;
						count++;
						if (i != hv2i(ob.hashval))
						{
							Console.WriteLine("Bad cell item={0}, hashval={1}, index={2}, level={3}", b.item, b.hashval, i, level);
							retval = false;
						}

						ob = ob.overflow;
					}
				}
#endif
      }

      if (count != size)
      {
        Console.WriteLine("size({0}) != count({1})", size, count);
        retval = false;
      }

      return retval;
#endif
    }
Beispiel #8
0
    public override SCG.IEnumerator<T> GetEnumerator()
    {
      int index = -1;
      int mystamp = stamp;
      int len = table.Length;

#if LINEARPROBING
#if REFBUCKET
      while (++index < len)
      {
        if (mystamp != stamp) throw new CollectionModifiedException();

        if (table[index] != null) yield return table[index].item;
      }
#else
      if (defaultvalid)
        yield return defaultitem;

      while (++index < len)
      {
        if (mystamp != stamp) throw new CollectionModifiedException();

        T item = table[index].item;

        if (!isnull(item)) yield return item;
      }
#endif
#else
#if REFBUCKET
      Bucket b = null;
#else
			OverflowBucket ob = null;

			if (defaultvalid)
				yield return defaultitem;
#endif
      while (true)
      {
        if (mystamp != stamp)
          throw new CollectionModifiedException();

#if REFBUCKET
        if (b == null || b.overflow == null)
        {
          do
          {
            if (++index >= len) yield break;
          } while (table[index] == null);

          b = table[index];
          yield return b.item;
        }
        else
        {
          b = b.overflow;
          yield return b.item;
        }
#else
				if (ob != null && ob.overflow != null)
				{
					ob = ob.overflow;
					yield return ob.item;
				}
				else if (index >= 0 && ob == null && (ob = table[index].overflow) != null)
				{
					yield return  ob.item;
				}
				else
				{
					do
					{
						if (++index >= len) yield break;
					} while (isnull(table[index].item));

          yield return table[index].item;
          ob = null;
				}
#endif
      }
#endif
    }