Пример #1
0
        /// <summary>
        /// Trims an existing list to the specified length and returns the excess blocks as a new list.
        /// </summary>
        /// <param name="listHeadBlockIndex">The starting block of the list to trim.</param>
        /// <param name="newListLength">The length in blocks that the list will be shortened to.</param>
        /// <returns>The index of the head node of the removed blocks.</returns>
        public int Trim(int listHeadBlockIndex, int newListLength)
        {
            int blocksRemaining = newListLength;
            int nextEntry       = BlockToEntryIndex(listHeadBlockIndex);
            int listAIndex      = -1;
            int listBIndex      = -1;

            while (blocksRemaining > 0)
            {
                if (nextEntry == 0)
                {
                    return(-1);
                }

                int currentEntryIndex = nextEntry;

                ReadEntry(EntryIndexToBlock(currentEntryIndex), out int nextBlock, out int _, out int segmentLength);

                nextEntry = BlockToEntryIndex(nextBlock);

                if (segmentLength == blocksRemaining)
                {
                    listAIndex = currentEntryIndex;
                    listBIndex = nextEntry;
                }
                else if (segmentLength > blocksRemaining)
                {
                    Split(EntryIndexToBlock(currentEntryIndex), blocksRemaining);

                    listAIndex = currentEntryIndex;
                    listBIndex = currentEntryIndex + blocksRemaining;
                }

                blocksRemaining -= segmentLength;
            }

            if (listAIndex == -1 || listBIndex == -1)
            {
                return(-1);
            }

            AllocationTableEntry listANode = ReadEntry(listAIndex);
            AllocationTableEntry listBNode = ReadEntry(listBIndex);

            listANode.SetNext(0);
            listBNode.MakeListStart();

            WriteEntry(listAIndex, listANode);
            WriteEntry(listBIndex, listBNode);

            return(EntryIndexToBlock(listBIndex));
        }