Beispiel #1
0
        /// <summary>
        /// Enumerates all pages starting at the specified `pageId`.
        /// This method yields back an enumeration of different page instances which could be used
        /// for parallel processing unless `preallocatedPage` is supplied in which case that given page instance is re-used
        /// for enumeration of the archive, consequently making it NOT a thread-safe operation.
        /// Existing page instances are used as optimization technique for tight read loops and should only be used in special cases
        /// to prevent extra page instance allocation (thus making it NOT thread-safe). The thread-safety concern only pertains to
        /// the instances returned by the enumerator. The IEnumerator itself is NOT thread-safe
        /// </summary>
        public IEnumerable <Page> GetPagesStartingAt(long startPageId, bool skipCorruptPages = false, Page preallocatedPage = null)
        {
            //local flow average is needed because not all of the archive pages are necessarily the same size:
            //they are the similar size around the same read area, consequently the local EMA provide more accurate estimate
            float emaSize = AveragePageSizeBytes;

            var i       = 0;
            var current = startPageId;

            while (true)
            {
                var page = preallocatedPage;

                if (page == null)
                {
                    page = getPageInstance((int)emaSize);
                }
                else
                {
                    page.AdjustDefaultCapacity((int)emaSize);
                }

                try
                {
                    current = Volume.ReadPage(current, page);
                }
                catch (ArchivingException)
                {
                    if (skipCorruptPages)
                    {
                        current++; //re-align to next page header
                        current = IntUtils.Align16(current);
                        continue;
                    }
                    throw;
                }

                if (page.State == Page.Status.Reading)
                {
                    var sz = (float)page.Data.Count;
                    emaSize = (sz * EMA_PAGE_SIZE_K) + (emaSize * EMA_PAGE_SIZE_J);

                    if ((i++ & 0b11) == 0)//every 4 iterations, calculate the average for the whole class based on an already averaged local
                    {
                        m_AveragePageSizeBytes = (int)((emaSize * EMA_PAGE_SIZE_K) + (m_AveragePageSizeBytes * EMA_PAGE_SIZE_J));
                    }

                    yield return(page);
                }

                if (current <= 0)
                {
                    break;
                }
            }
        }
Beispiel #2
0
        public void Align16_long()
        {
            Aver.AreEqual(16, IntUtils.Align16(3L));
            Aver.AreEqual(48, IntUtils.Align16(33L));
            Aver.AreEqual(0, IntUtils.Align16(0L));
            Aver.AreEqual(16, IntUtils.Align16(8L));
            Aver.AreEqual(16, IntUtils.Align16(16L));
            Aver.AreEqual(32, IntUtils.Align16(17L));
            Aver.AreEqual(128, IntUtils.Align16(127L));
            Aver.AreEqual(128, IntUtils.Align16(128L));
            Aver.AreEqual(144, IntUtils.Align16(129L));

            Aver.AreEqual(0, IntUtils.Align16(-5L));
            Aver.AreEqual(-16, IntUtils.Align16(-17L));
        }
Beispiel #3
0
        public void Align16_int()
        {
            Aver.AreEqual(16, IntUtils.Align16(3));
            Aver.AreEqual(48, IntUtils.Align16(33));
            Aver.AreEqual(0, IntUtils.Align16(0));
            Aver.AreEqual(16, IntUtils.Align16(8));
            Aver.AreEqual(16, IntUtils.Align16(16));
            Aver.AreEqual(32, IntUtils.Align16(17));
            Aver.AreEqual(128, IntUtils.Align16(127));
            Aver.AreEqual(128, IntUtils.Align16(128));
            Aver.AreEqual(144, IntUtils.Align16(129));

            Aver.AreEqual(0, IntUtils.Align16(-5));
            Aver.AreEqual(-16, IntUtils.Align16(-17));
        }
Beispiel #4
0
        private static Type readHeader(Stream stream)
        {
            var buf = Format.getBuff32();

            Format.readFromStream(stream, buf, Format.HEADER_BUF.Length);
            for (var i = 0; i < Format.HEADER_BUF.Length; i++)
            {
                if (buf[i] != Format.HEADER_BUF[i])
                {
                    throw new BinLogException(StringConsts.BINLOG_STREAM_CORRUPTED_ERROR + "bad header");
                }
            }

            var tn = Format.ReadString(stream);

            if (tn.IsNullOrWhiteSpace())
            {
                throw new BinLogException(StringConsts.BINLOG_STREAM_CORRUPTED_ERROR + "bad type");
            }

            var pos   = stream.Position;
            var start = IntUtils.Align16(pos);

            while (pos < start)
            {
                if (Format.ReadByte(stream) != 0)
                {
                    throw new BinLogException(StringConsts.BINLOG_STREAM_CORRUPTED_ERROR + "bad header pad");
                }
            }

            var result = Type.GetType(tn, false);

            if (result == null || !typeof(LogReader).IsAssignableFrom(result))
            {
                throw new BinLogException(StringConsts.BINLOG_BAD_READER_TYPE_ERROR + tn);
            }

            return(result);
        }
Beispiel #5
0
        public IEnumerable <object> read(bool includeMetadata)
        {
            DateTime current = DateUtils.UNIX_EPOCH_START_DATE;

            while (App.Active)
            {
                while (App.Active)
                {
                    var h = Format.TryReadPageHeader(m_Stream, ref current);
                    if (h == Format.PageHeaderReadStatus.OK)
                    {
                        break;
                    }
                    if (h == Format.PageHeaderReadStatus.EOF)
                    {
                        yield break;
                    }
                    var pos    = Stream.Position;
                    var newPos = IntUtils.Align16(pos);
                    var delta  = newPos - pos;

                    var eof = true;
                    try
                    {
                        if (delta > 0)
                        {
                            Stream.Seek(delta, SeekOrigin.Current);
                        }
                        eof = false;
                    }
                    catch {}
                    if (eof)
                    {
                        yield break;
                    }
                }//page

                while (App.Active)
                {
                    byte rec = Format.REC_INVALID;
                    try{ rec = Format.ReadByte(m_Stream); } catch {}

                    if (rec == Format.REC_EOF)
                    {
                        break;
                    }
                    else if (rec == Format.REC_TIMESTAMP)
                    {
                        DateTime ts = DateTime.MinValue;
                        try{ ts = Format.ReadTimeStamp(m_Stream); } catch {}

                        if (ts <= DateUtils.UNIX_EPOCH_START_DATE || ts < current)//corruption
                        {
                            if (includeMetadata)
                            {
                                yield return(LogCorruption.Instance);
                            }
                            break;
                        }
                        current = ts;
                        if (includeMetadata)
                        {
                            yield return(new LogUTCTimeStamp(ts));
                        }
                    }
                    else if (rec == Format.REC_SERIALIZER)
                    {
                        //todo deserialize
                    }
                    else
                    {
                        if (includeMetadata)
                        {
                            yield return(LogCorruption.Instance);
                        }
                        break;
                    }
                } //records
            }     //outer
        }