Esempio n. 1
0
        /// <summary>
        /// GROUP BY: Apply groupBy expression and aggregate results in DocumentGroup
        /// </summary>
        private IEnumerable <DocumentGroup> GroupBy(IEnumerable <BsonDocument> source, GroupBy groupBy)
        {
            using (var enumerator = source.GetEnumerator())
            {
                var done = new Done {
                    Running = enumerator.MoveNext()
                };

                while (done.Running)
                {
                    var key = groupBy.Expression.ExecuteScalar(enumerator.Current);

                    groupBy.Select.Parameters["key"] = key;

                    var group = YieldDocuments(key, enumerator, groupBy, done);

                    yield return(new DocumentGroup(key, enumerator.Current, group, _lookup));
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// YieldDocuments will run over all key-ordered source and returns groups of source
        /// </summary>
        private IEnumerable <BsonDocument> YieldDocuments(BsonValue key, IEnumerator <BsonDocument> enumerator, GroupBy groupBy, Done done)
        {
            yield return(enumerator.Current);

            while (done.Running = enumerator.MoveNext())
            {
                var current = groupBy.Expression.ExecuteScalar(enumerator.Current);

                if (key == current)
                {
                    // yield return document in same key (group)
                    yield return(enumerator.Current);
                }
                else
                {
                    groupBy.Select.Parameters["key"] = current;

                    // stop current sequence
                    yield break;
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Split values in many IEnumerable. Each enumerable contains values to be insert in a single container
        /// </summary>
        private IEnumerable <IEnumerable <KeyValuePair <BsonValue, PageAddress> > > SliptValues(IEnumerable <KeyValuePair <BsonValue, PageAddress> > source, Done done)
        {
            using (var enumerator = source.GetEnumerator())
            {
                if (enumerator.MoveNext())
                {
                    done.Count = 1;

                    while (done.Running)
                    {
                        yield return(this.YieldValues(enumerator, done));
                    }
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Loop in values enumerator to return N values for a single container
        /// </summary>
        private IEnumerable <KeyValuePair <BsonValue, PageAddress> > YieldValues(IEnumerator <KeyValuePair <BsonValue, PageAddress> > source, Done done)
        {
            var size = SortContainer.GetKeyLength(source.Current.Key) + PageAddress.SIZE;

            yield return(source.Current);

            while (source.MoveNext())
            {
                var length = SortContainer.GetKeyLength(source.Current.Key) + PageAddress.SIZE;

                done.Count++;

                if (size + length > _containerSize)
                {
                    yield break;
                }

                size += length;

                yield return(source.Current);
            }

            done.Running = false;
        }
Esempio n. 5
0
        /// <summary>
        /// Loop in values enumerator to return N values for a single container
        /// </summary>
        private IEnumerable <KeyValuePair <BsonValue, PageAddress> > YieldValues(IEnumerator <KeyValuePair <BsonValue, PageAddress> > source, Done done)
        {
            var size = IndexNode.GetKeyLength(source.Current.Key, false) + PageAddress.SIZE;

            if (size > MAX_INDEX_KEY_LENGTH)
            {
                throw new LiteException(0, $"Current value are larger than {MAX_INDEX_KEY_LENGTH} bytes and can't be sorted.");
            }

            yield return(source.Current);

            while (source.MoveNext())
            {
                var length = IndexNode.GetKeyLength(source.Current.Key, false) + PageAddress.SIZE;

                done.Count++;

                if (size + length > _containerSize)
                {
                    yield break;
                }

                size += length;

                yield return(source.Current);
            }

            done.Running = false;
        }