private static IEnumerable <TimeSeriesEntry> ChopRelevantRange(TimeSeriesRangeResult range, DateTime from, DateTime to, int start, int pageSize)
        {
            if (range.Entries == null)
            {
                yield break;
            }

            foreach (var value in range.Entries)
            {
                if (value.Timestamp > to)
                {
                    yield break;
                }

                if (value.Timestamp < from)
                {
                    continue;
                }

                if (start-- > 0)
                {
                    continue;
                }

                if (pageSize-- <= 0)
                {
                    yield break;
                }

                yield return(value);
            }
        }
        private static IEnumerable <TimeSeriesEntry> SkipAndTrimRangeIfNeeded(
            DateTime from,
            DateTime to,
            TimeSeriesRangeResult fromRange,
            TimeSeriesRangeResult toRange,
            List <TimeSeriesEntry> values,
            int skip,
            int trim)
        {
            if (fromRange != null && fromRange.To >= from)
            {
                // need to skip a part of the first range

                if (toRange != null && toRange.From <= to)
                {
                    // also need to trim a part of the last range
                    return(values.Skip(skip).Take(values.Count - skip - trim));
                }

                return(values.Skip(skip));
            }

            if (toRange != null && toRange.From <= to)
            {
                // trim a part of the last range
                return(values.Take(values.Count - trim));
            }

            return(values);
        }
Beispiel #3
0
        public void AddIncludesToResult(TimeSeriesRangeResult rangeResult)
        {
            if (rangeResult == null || _includes?.Properties.Count > 0 == false)
            {
                return;
            }

            rangeResult.Includes = _context.ReadObject(_includes, "TimeSeriesRangeIncludes/" + _docId);
        }
        private void HandleIncludes(TimeSeriesRangeResult rangeResult)
        {
            if (rangeResult.Includes == null)
            {
                return;
            }

            using (rangeResult.Includes)
            {
                Session.RegisterIncludes(rangeResult.Includes);
            }

            rangeResult.Includes = null;
        }
        private static void WriteRange(AsyncBlittableJsonTextWriter writer, TimeSeriesRangeResult rangeResult, long?totalCount)
        {
            writer.WriteStartObject();
            {
                writer.WritePropertyName(nameof(TimeSeriesRangeResult.From));
                if (rangeResult.From == DateTime.MinValue)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteDateTime(rangeResult.From, true);
                }
                writer.WriteComma();

                writer.WritePropertyName(nameof(TimeSeriesRangeResult.To));
                if (rangeResult.To == DateTime.MaxValue)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteDateTime(rangeResult.To, true);
                }
                writer.WriteComma();

                writer.WritePropertyName(nameof(TimeSeriesRangeResult.Entries));
                WriteEntries(writer, rangeResult.Entries);

                if (totalCount.HasValue)
                {
                    // add total entries count to the response
                    writer.WriteComma();
                    writer.WritePropertyName(nameof(TimeSeriesRangeResult.TotalResults));
                    writer.WriteInteger(totalCount.Value);
                }

                if (rangeResult.Includes != null)
                {
                    // add included documents to the response
                    writer.WriteComma();
                    writer.WritePropertyName(nameof(TimeSeriesRangeResult.Includes));
                    writer.WriteObject(rangeResult.Includes);
                }
            }
            writer.WriteEndObject();
        }
        internal static unsafe TimeSeriesRangeResult GetTimeSeriesRange(DocumentsOperationContext context, string docId, string name, DateTime from, DateTime to, ref int start, ref int pageSize,
                                                                        IncludeDocumentsDuringTimeSeriesLoadingCommand includesCommand = null)
        {
            if (pageSize == 0)
            {
                return(null);
            }

            List <TimeSeriesEntry> values = new List <TimeSeriesEntry>();

            var reader = new TimeSeriesReader(context, docId, name, from, to, offset: null);

            // init hash
            var size = Sodium.crypto_generichash_bytes();

            Debug.Assert((int)size == 32);
            var cryptoGenerichashStatebytes = (int)Sodium.crypto_generichash_statebytes();
            var state = stackalloc byte[cryptoGenerichashStatebytes];

            if (Sodium.crypto_generichash_init(state, null, UIntPtr.Zero, size) != 0)
            {
                ComputeHttpEtags.ThrowFailToInitHash();
            }

            var      initialStart  = start;
            var      hasMore       = false;
            DateTime lastSeenEntry = from;

            includesCommand?.InitializeNewRangeResult(state);

            foreach (var(individualValues, segmentResult) in reader.SegmentsOrValues())
            {
                if (individualValues == null &&
                    start > segmentResult.Summary.NumberOfLiveEntries)
                {
                    lastSeenEntry = segmentResult.End;
                    start        -= segmentResult.Summary.NumberOfLiveEntries;
                    continue;
                }

                var enumerable = individualValues ?? segmentResult.Values;

                foreach (var singleResult in enumerable)
                {
                    lastSeenEntry = segmentResult.End;

                    if (start-- > 0)
                    {
                        continue;
                    }

                    if (pageSize-- <= 0)
                    {
                        hasMore = true;
                        break;
                    }

                    includesCommand?.Fill(singleResult.Tag);

                    values.Add(new TimeSeriesEntry
                    {
                        Timestamp = singleResult.Timestamp,
                        Tag       = singleResult.Tag,
                        Values    = singleResult.Values.ToArray(),
                        IsRollup  = singleResult.Type == SingleResultType.RolledUp
                    });
                }

                ComputeHttpEtags.HashChangeVector(state, segmentResult.ChangeVector);

                if (pageSize <= 0)
                {
                    break;
                }
            }

            var hash = ComputeHttpEtags.FinalizeHash(size, state);

            TimeSeriesRangeResult result;

            if (initialStart > 0 && values.Count == 0)
            {
                // this is a special case, because before the 'start' we might have values
                result = new TimeSeriesRangeResult
                {
                    From    = lastSeenEntry,
                    To      = to,
                    Entries = values.ToArray(),
                    Hash    = hash
                };
            }
            else
            {
                result = new TimeSeriesRangeResult
                {
                    From    = (initialStart > 0) ? values[0].Timestamp : from,
                    To      = hasMore ? values.Last().Timestamp : to,
                    Entries = values.ToArray(),
                    Hash    = hash
                };
            }

            includesCommand?.AddIncludesToResult(result);

            return(result);
        }