/// <summary>
        /// PUBLIC API
        /// Find objects in space that are similar to the current object.
        /// Similar means that the properties listed in parameter must be the same.
        /// </summary>
        /// <param name="propertyIds">List of properties that must match</param>
        /// <returns>A list of objects that are similar, excluding this object. Empty list if none.</returns>
        public ICollection <ClassificationObject> FindSimilar(IEnumerable <byte> propertyIds)
        {
            COHashTable <ClassificationObject> ret = this._FindSimilar(propertyIds);

            if (ret == null)
            {
                return(EmptyCOArray);
            }
            else if (ret.Contains(this))
            {
                ret.Remove(this);
            }
            return(ret.Objects);
        }
        /// <summary>
        /// Opposite to FindSimilar(). Different means an object that has the listed properties different
        /// than the current object. The rest of the properties must be the same
        /// </summary>
        /// <param name="propertyIds">List of properties that must differ.</param>
        /// <returns>A list of different objects.</returns>
        public ICollection <ClassificationObject> FindDifferent(IEnumerable <byte> propertyIds)
        {
            // Algorithm:
            // 1. Create a list of properties that must be equal.
            // 2. Find objects that have those properties equal. (Set A)
            // 3. From setA remove objects that have diff properties equal to this
            // 4. Return SetA

            // Step 1.
            var propertiesEqual = this.EnabledProperties.Except(propertyIds).ToArray();

            // Step 2.
            COHashTable <ClassificationObject> setA = this._FindSimilar(propertiesEqual);

            // Step 3.
            foreach (var prop in propertyIds)
            {
                setA.ExceptAndRemove(this.ObjectSpace.GetObjectsAt(this.Properties[prop]));
            }

            return(setA.Objects);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets an intersection of multiple dimensions at coordinates specified by
        /// properties listed in params.
        /// </summary>
        /// <param name="properties"></param>
        /// <returns></returns>
        public COHashTable <ClassificationObject> GetDimensionIntersection(ICollection <Property> properties)
        {
            if (properties == null || properties.Count == 0)
            {
                return(COHashTable <ClassificationObject> .Empty);
            }
            if (properties.Count == 1)
            {
                return(GetObjectsAt(properties.First()));
            }
            // the order of properties does not matter for the result
            // sorting them will make sure that different calls to the method, with a different sequence of properties,
            // will result in a cache hit.
            var sortedProperties = properties.OrderBy(p => p.Id).ToArray();

            COHashTable <ClassificationObject> ret;

            ///Collect all sets of matching objects
            var resultSets = new COHashTable <ClassificationObject> [(sortedProperties.Length)];
            int i          = 0;

            foreach (Property prop in sortedProperties)
            {
                resultSets[i++] = this.GetObjectsAt(prop);
            }
            ///Sort sets from smallest to largest. This significantly improves performance of intersect in most cases.
            Array.Sort <COHashTable <ClassificationObject> >(resultSets, COHashTable <ClassificationObject> .COHashTableCountComparer);

            ///create return set
            ret = resultSets[0].Clone();

            ///intersect all sets with the initial return set
            i = 1;
            while (i < resultSets.Length && ret.Count > 0)
            {
                ret.IntersectAndRemove(resultSets[i++]);
            }
            return(ret);
        }
Ejemplo n.º 4
0
 public PropertyEntry(COHashTable <T> coSet, LinkedListNode <Property> indexEntry)
 {
     COSet      = coSet;
     IndexEntry = indexEntry;
 }