/// <summary>Return a set of keys such that the value of that key is not null.</summary> /// <returns> /// A hash set such that each element of the set is a key in this CoreMap that has a /// non-null value. /// </returns> public virtual ICollection <Type> KeySetNotNull() { ICollection <Type> mapKeys = new IdentityHashSet <Type>(); for (int i = 0; i < Size(); ++i) { if (values[i] != null) { mapKeys.Add(this.keys[i]); } } return(mapKeys); }
/// <summary> /// Returns a composite hashCode over all the keys and values currently /// stored in the map. /// </summary> /// <remarks> /// Returns a composite hashCode over all the keys and values currently /// stored in the map. Because they may change over time, this class /// is not appropriate for use as map keys. /// </remarks> public override int GetHashCode() { IdentityHashSet <ICoreMap> calledSet = hashCodeCalled.Get(); bool createdCalledSet = (calledSet == null); if (createdCalledSet) { calledSet = new IdentityHashSet <ICoreMap>(); hashCodeCalled.Set(calledSet); } if (calledSet.Contains(this)) { return(0); } calledSet.Add(this); int keysCode = 0; int valuesCode = 0; for (int i = 0; i < size; i++) { keysCode += (i < keys.Length && values[i] != null ? keys[i].GetHashCode() : 0); valuesCode += (i < values.Length && values[i] != null ? values[i].GetHashCode() : 0); } if (createdCalledSet) { hashCodeCalled.Set(null); } else { // Remove the object after processing is complete so that if // there are multiple instances of this CoreMap in the overall // object graph, they each have their hash code calculated. // TODO: can we cache this for later? calledSet.Remove(this); } return(keysCode * 37 + valuesCode); }
/// <summary>Prints a full dump of a CoreMap.</summary> /// <remarks> /// Prints a full dump of a CoreMap. This method is robust to /// circularity in the CoreMap. /// </remarks> /// <returns>A String representation of the CoreMap</returns> public override string ToString() { IdentityHashSet <ICoreMap> calledSet = toStringCalled.Get(); bool createdCalledSet = calledSet.IsEmpty(); if (calledSet.Contains(this)) { return("[...]"); } calledSet.Add(this); StringBuilder s = new StringBuilder("["); for (int i = 0; i < size; i++) { s.Append(keys[i].GetSimpleName()); s.Append('='); s.Append(values[i]); if (i < size - 1) { s.Append(' '); } } s.Append(']'); if (createdCalledSet) { toStringCalled.Remove(); } else { // Remove the object from the already called set so that // potential later calls in this object graph have something // more description than [...] calledSet.Remove(this); } return(s.ToString()); }