示例#1
0
        /// <summary>
        /// Reclaim unused space (Directly on the table, stopping the defragmentation can result in permanent corruption)
        /// </summary>
        /// <returns>The number of bytes saved</returns>
        public async ValueTask <int> UnsafeDefragment(CancellationToken cancellationToken = default)
        {
            ClearTrie();
            await ClearFileStream();

            int saved    = 0;
            var fileName = await tx.Schema.GetFileNameOrCreate(tableName);

            if (!await tx._Engine.Storages.Exists(fileName.ToString()))
            {
                return(0);
            }
            await using var fs = await tx._Engine.Storages.OpenStorage(fileName.ToString());

            await using var cache = new CacheStorage(fs, false, PagePool, true);
            var trie = await LTrie.OpenFromStorage(cache);

            saved = await trie.Defragment(cancellationToken);

            await cache.Flush();

            await fs.Flush();

            return(saved);
        }
示例#2
0
        /// <summary>
        /// Reclaim unused space (Copy the table in a temporary file, defragment and replace the original table)
        /// </summary>
        /// <returns>The number of bytes saved</returns>
        public async ValueTask <int> Defragment(CancellationToken cancellationToken = default)
        {
            ClearTrie();
            await ClearFileStream();

            // We copy the current table on a temporary file, then defragment that
            // once defragmentation is complete, we copy the temp file to the current table
            // this prevent corruption if anything happen on the middle of the defragmentation
            var fileName = await tx.Schema.GetFileNameOrCreate(tableName);

            var tmpFile = $"{fileName}_tmp";

            if (!await tx._Engine.Storages.Exists(fileName.ToString()))
            {
                return(0);
            }
            await tx._Engine.Storages.Copy(fileName.ToString(), tmpFile);

            int saved = 0;

            try
            {
                await using var fs = await tx._Engine.Storages.OpenStorage(tmpFile);

                await using var cache = new CacheStorage(fs, false, PagePool, true);
                var trie = await LTrie.OpenFromStorage(cache);

                saved = await trie.Defragment(cancellationToken);

                await cache.Flush();

                await fs.Flush();
            }
            catch
            {
                await tx._Engine.Storages.Delete(tmpFile);

                throw;
            }
            await tx._Engine.Storages.Move(tmpFile, fileName.ToString());

            return(saved);
        }