Пример #1
0
        private static Cube <UValue> resolvingMerge <UValue>(IEnumerable <Dimension> dimensions, IEnumerable <Cube <TValue> > cubes, Func <Collision <TValue>, UValue> combiner)
        {
            Dictionary <Key, Collision <TValue> > lookup = new Dictionary <Key, Collision <TValue> >();

            foreach (Cube <TValue> cube in cubes)
            {
                foreach (KeyValuePair <Key, TValue> pair in cube.valueLookup)
                {
                    Collision <TValue> collisions;
                    if (lookup.ContainsKey(pair.Key))
                    {
                        collisions = lookup[pair.Key];
                    }
                    else
                    {
                        collisions = new Collision <TValue>(pair.Key);
                        lookup.Add(pair.Key, collisions);
                    }
                    collisions.Add(pair.Value);
                }
            }
            LookupBuilder <UValue> builder = new LookupBuilder <UValue>(dimensions);

            foreach (Collision <TValue> collision in lookup.Values)
            {
                UValue value = combiner(collision);
                builder.Add(collision.Key, value);
            }
            return(new Cube <UValue>(builder));
        }
Пример #2
0
        private Cube <UValue> collapse <UValue>(Dimension dimension, Func <Group <TValue>, UValue> aggregator)
        {
            IEnumerable <Dimension>           dimensions = keyLookup.Keys.Where(otherDimension => dimension != otherDimension).ToArray();
            Dictionary <Key, Group <TValue> > lookup     = new Dictionary <Key, Group <TValue> >();

            foreach (KeyValuePair <Key, TValue> pair in valueLookup)
            {
                KeyPart oldKeyPart = pair.Key.GetKeyPart(dimension);
                IEnumerable <KeyPart> newKeyParts = dimensions.Select(item => pair.Key.GetKeyPart(item));
                Key            newKey             = new Key(newKeyParts, true);
                Group <TValue> group;
                if (lookup.ContainsKey(newKey))
                {
                    group = lookup[newKey];
                }
                else
                {
                    group = new Group <TValue>(newKey);
                    lookup.Add(newKey, group);
                }
                group.AddPair(oldKeyPart, pair.Value);
            }
            LookupBuilder <UValue> builder = new LookupBuilder <UValue>(dimensions);

            foreach (KeyValuePair <Key, Group <TValue> > pair in lookup)
            {
                UValue value = aggregator(pair.Value);
                builder.Add(pair.Key, value);
            }
            return(new Cube <UValue>(builder));
        }
Пример #3
0
        /// <summary>
        /// Creates a new cube by applying an operation to every value in the cube.
        /// </summary>
        /// <typeparam name="UValue">The type of the values after the application.</typeparam>
        /// <param name="converter">The function for creating a UValue from a TValue.</param>
        /// <returns>A new cube holding the results of the application to every value in the cube.</returns>
        public Cube <UValue> Convert <UValue>(Func <TValue, UValue> converter)
        {
            if (converter == null)
            {
                throw new ArgumentNullException("applicator");
            }
            LookupBuilder <UValue> builder = new LookupBuilder <UValue>(keyLookup.Keys);

            foreach (KeyValuePair <Key, TValue> pair in this.valueLookup)
            {
                UValue value = converter(pair.Value);
                builder.Add(pair.Key, value);
            }
            return(new Cube <UValue>(builder));
        }
Пример #4
0
        /// <summary>
        /// Creates a cube with a single value associated with all of the key parts.
        /// </summary>
        /// <param name="key">The key of the singleton.</param>
        /// <param name="value">The singleton value.</param>
        /// <returns>A new cube with a single key/value pair.</returns>
        public static Cube <TValue> Singleton(Key key, TValue value)
        {
            if (key == null)
            {
                throw new ArgumentNullException("The key must not be null.");
            }
            if (key.DimensionCount == 0)
            {
                return(NullCube);
            }
            IEnumerable <Dimension> dimensions = key.GetKeyParts().Select(part => part.Dimension);
            LookupBuilder <TValue>  builder    = new LookupBuilder <TValue>(dimensions);

            builder.Add(key, value);
            return(new Cube <TValue>(builder));
        }
Пример #5
0
        private static Cube <TValue> merge(IEnumerable <Dimension> dimensions, IEnumerable <Cube <TValue> > cubes)
        {
            LookupBuilder <TValue> lookup = new LookupBuilder <TValue>(dimensions);

            foreach (Cube <TValue> cube in cubes)
            {
                foreach (KeyValuePair <Key, TValue> pair in cube.valueLookup)
                {
                    if (lookup.ContainsKey(pair.Key))
                    {
                        throw new InvalidOperationException("Two or more cubes had the same key.");
                    }
                    lookup.Add(pair.Key, pair.Value);
                }
            }
            return(new Cube <TValue>(lookup));
        }
Пример #6
0
        /// <summary>
        /// Creates an empty cube with the given dimensions.
        /// </summary>
        /// <param name="dimensions">The dimensions in the cube.</param>
        /// <returns>A new empty cube with the given dimensions.</returns>
        public static Cube <TValue> Define(IEnumerable <Dimension> dimensions)
        {
            if (dimensions == null)
            {
                throw new ArgumentNullException("The dimensions list must not be null.");
            }
            if (!dimensions.Any())
            {
                return(NullCube);
            }
            if (dimensions.Any(dimension => dimension == null))
            {
                throw new ArgumentException("One or more of the dimensions were null.", "dimensions");
            }
            LookupBuilder <TValue> builder = new LookupBuilder <TValue>(dimensions);

            return(new Cube <TValue>(builder));
        }
Пример #7
0
        /// <summary>
        /// Creates a copy of the cube, excluding values whose keys have a matching key part value.
        /// </summary>
        /// <param name="keyPart">The dimension and key value of items to be removed.</param>
        /// <returns>A new cube where the values matching the key part have been removed.</returns>
        public Cube <TValue> Exclude(KeyPart keyPart)
        {
            if (keyPart == null)
            {
                throw new ArgumentNullException("keyPart");
            }
            if (!keyLookup.ContainsKey(keyPart.Dimension))
            {
                throw new ArgumentException("Cannot filter by a dimension that is not in the cube.", "dimension");
            }
            LookupBuilder <TValue> builder = new LookupBuilder <TValue>(keyLookup.Keys);

            foreach (KeyValuePair <Key, TValue> pair in valueLookup)
            {
                if (!keyPart.Equals(pair.Key.GetKeyPart(keyPart.Dimension)))
                {
                    builder.Add(pair.Key, pair.Value);
                }
            }
            return(new Cube <TValue>(builder));
        }
Пример #8
0
        /// <summary>
        /// Creates a new cube where the key part value in the specified dimension equals the given key part's value.
        /// </summary>
        /// <param name="keyPart">The value the keys in the given dimension must equal.</param>
        /// <returns>A new cube where the keys in the specified dimension equal the given value.</returns>
        public Cube <TValue> Splice(KeyPart keyPart)
        {
            if (keyPart == null)
            {
                throw new ArgumentNullException("keyPart");
            }
            if (!keyLookup.ContainsKey(keyPart.Dimension))
            {
                throw new ArgumentException("Cannot splice a dimension that does not exist in the cube", "dimension");
            }
            Dictionary <KeyPart, List <Key> > dimensionLookup = keyLookup[keyPart.Dimension];
            LookupBuilder <TValue>            builder         = new LookupBuilder <TValue>(keyLookup.Keys);
            List <Key> keys;

            if (dimensionLookup.TryGetValue(keyPart, out keys))
            {
                foreach (Key key in keys)
                {
                    TValue value = valueLookup[key];
                    builder.Add(key, value);
                }
            }
            return(new Cube <TValue>(builder));
        }
Пример #9
0
        /// <summary>
        /// Creates a cube with a new dimension where all the values from the current cube are associated with the given key part value.
        /// </summary>
        /// <param name="keyPart">The dimension/key value pair to append to the cube.</param>
        /// <returns>A new cube with the added dimension and values.</returns>
        public Cube <TValue> AddDimension(KeyPart keyPart)
        {
            if (keyPart == null)
            {
                throw new ArgumentNullException("keyPart");
            }
            if (keyLookup.ContainsKey(keyPart.Dimension))
            {
                throw new ArgumentException("The given dimension already exists.", "dimension");
            }
            List <Dimension> dimensions = keyLookup.Keys.ToList();

            dimensions.Add(keyPart.Dimension);
            LookupBuilder <TValue> builder = new LookupBuilder <TValue>(dimensions);

            foreach (KeyValuePair <Key, TValue> pair in valueLookup)
            {
                List <KeyPart> keyParts = new List <KeyPart>(pair.Key.GetKeyParts());
                keyParts.Add(keyPart);
                Key newKey = new Key(keyParts, true);
                builder.Add(newKey, pair.Value);
            }
            return(new Cube <TValue>(builder));
        }
Пример #10
0
        /// <summary>
        /// Creates an empty cube with the same dimensions of the current cube.
        /// </summary>
        /// <returns>The new empty cube.</returns>
        public Cube <TValue> Empty()
        {
            LookupBuilder <TValue> builder = new LookupBuilder <TValue>(keyLookup.Keys);

            return(new Cube <TValue>(builder));
        }
Пример #11
0
 /// <summary>
 /// Initializes a new instance of a Cube.
 /// </summary>
 /// <param name="builder">The builder used to build the lookups.</param>
 private Cube(LookupBuilder <TValue> builder)
 {
     this.valueLookup = builder.ValueLookup;
     this.keyLookup   = builder.KeyLookup;
 }