Exemple #1
0
        /// <summary>
        /// Load all confirmed transactions from log file (used only when open datafile)
        /// Don't need lock because it's called on ctor of LiteEngine
        /// Update _disk instance with last log position
        /// </summary>
        public void RestoreIndex(HeaderPage header)
        {
            // get all page positions
            var positions = new Dictionary <long, List <PagePosition> >();
            var last      = 0L;

            // read all pages to get confirmed transactions (do not read page content, only page header)
            foreach (var buffer in _disk.ReadLog(true))
            {
                // read direct from buffer to avoid create BasePage structure
                var pageID        = buffer.ReadUInt32(BasePage.P_PAGE_ID);
                var isConfirmed   = buffer.ReadBool(BasePage.P_IS_CONFIRMED);
                var transactionID = buffer.ReadUInt32(BasePage.P_TRANSACTION_ID);

                if (transactionID == 0 || transactionID == uint.MaxValue)
                {
                    continue;
                }

                var position = new PagePosition(pageID, buffer.Position);

                if (positions.TryGetValue(transactionID, out var list))
                {
                    list.Add(position);
                }
                else
                {
                    positions[transactionID] = new List <PagePosition> {
                        position
                    };
                }

                if (isConfirmed)
                {
                    // update last IsConfirmed page
                    last = buffer.Position;

                    this.ConfirmTransaction(transactionID, positions[transactionID]);

                    var pageType = (PageType)buffer.ReadByte(BasePage.P_PAGE_TYPE);

                    // when a header is modified in transaction, must always be the last page inside log file (per transaction)
                    if (pageType == PageType.Header)
                    {
                        // copy this buffer block into original header block
                        Buffer.BlockCopy(buffer.Array, buffer.Offset, header.Buffer.Array, header.Buffer.Offset, PAGE_SIZE);

                        header.LoadPage();
                    }
                }

                // update last transaction ID
                _lastTransactionID = (int)transactionID;
            }

            // update last log position acording with last IsConfirmed on log
            if (last > 0)
            {
                _disk.LogEndPosition = last + PAGE_SIZE;
            }
        }