Example #1
0
        public unsafe void Commit()
        {
            if (Flags != (TransactionFlags.ReadWrite))
            {
                return;                 // nothing to do
            }
            FlushAllMultiValues();

            _freeSpaceRepository.FlushFreeState(this);

            foreach (var kvp in _treesInfo)
            {
                var txInfo = kvp.Value;
                var tree   = kvp.Key;
                tree.DebugValidateTree(this, txInfo.RootPageNumber);
                txInfo.Flush();
                if (string.IsNullOrEmpty(kvp.Key.Name))
                {
                    continue;
                }

                var treePtr = (TreeRootHeader *)_env.Root.DirectAdd(this, tree.Name, sizeof(TreeRootHeader));
                tree.State.CopyTo(treePtr);
            }

            FlushFreePages();               // this is the the free space that is available when all concurrent transactions are done

            if (_rootTreeData != null)
            {
                _env.Root.DebugValidateTree(this, _rootTreeData.RootPageNumber);
                _rootTreeData.Flush();
            }

            if (_fresSpaceTreeData != null)
            {
                _env.FreeSpaceRoot.DebugValidateTree(this, _fresSpaceTreeData.RootPageNumber);
                _fresSpaceTreeData.Flush();
            }

#if DEBUG
            if (_env.Root != null && _env.FreeSpaceRoot != null)
            {
                Debug.Assert(_env.Root.State.RootPageNumber != _env.FreeSpaceRoot.State.RootPageNumber);
            }
#endif

            _env.NextPageNumber = NextPageNumber;

            // Because we don't know in what order the OS will flush the pages
            // we need to do this twice, once for the data, and then once for the metadata

            var sortedPagesToFlush = _dirtyPages.Select(x => x.Value).Distinct().ToList();
            sortedPagesToFlush.Sort();
            _pager.Flush(sortedPagesToFlush);

            if (_freeSpaceRepository != null)
            {
                _freeSpaceRepository.LastTransactionPageUsage(sortedPagesToFlush.Count);
            }

            WriteHeader(_pager.Get(this, _id & 1)); // this will cycle between the first and second pages

            _pager.Flush(_id & 1);                  // and now we flush the metadata as well

            _pager.Sync();
        }