// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SRC_DAWN_NATIVE_BUDDYALLOCATOR_H_
#define SRC_DAWN_NATIVE_BUDDYALLOCATOR_H_

#include <cstddef>
#include <cstdint>
#include <limits>
#include <vector>

namespace dawn::native {

    // Buddy allocator uses the buddy memory allocation technique to satisfy an allocation request.
    // Memory is split into halves until just large enough to fit to the request. This
    // requires the allocation size to be a power-of-two value. The allocator "allocates" a block by
    // returning the starting offset whose size is guaranteed to be greater than or equal to the
    // allocation size. To deallocate, the same offset is used to find the corresponding block.
    //
    // Internally, it manages a free list to track free blocks in a full binary tree.
    // Every index in the free list corresponds to a level in the tree. That level also determines
    // the size of the block to be used to satisfy the request. The first level (index=0) represents
    // the root whose size is also called the max block size.
    //
    class BuddyAllocator {
      public:
        explicit BuddyAllocator(uint64_t maxSize);
        ~BuddyAllocator();

        // Required methods.
        uint64_t Allocate(uint64_t allocationSize, uint64_t alignment = 1);
        void Deallocate(uint64_t offset);

        // For testing purposes only.
        uint64_t ComputeTotalNumOfFreeBlocksForTesting() const;

        static constexpr uint64_t kInvalidOffset = std::numeric_limits<uint64_t>::max();

      private:
        uint32_t ComputeLevelFromBlockSize(uint64_t blockSize) const;
        uint64_t GetNextFreeAlignedBlock(size_t allocationBlockLevel, uint64_t alignment) const;

        enum class BlockState { Free, Split, Allocated };

        struct BuddyBlock {
            BuddyBlock(uint64_t size, uint64_t offset)
                : mOffset(offset), mSize(size), mState(BlockState::Free) {
                free.pPrev = nullptr;
                free.pNext = nullptr;
            }

            uint64_t mOffset;
            uint64_t mSize;

            // Pointer to this block's buddy, iff parent is split.
            // Used to quickly merge buddy blocks upon de-allocate.
            BuddyBlock* pBuddy = nullptr;
            BuddyBlock* pParent = nullptr;

            // Track whether this block has been split or not.
            BlockState mState;

            struct FreeLinks {
                BuddyBlock* pPrev;
                BuddyBlock* pNext;
            };

            struct SplitLink {
                BuddyBlock* pLeft;
            };

            union {
                // Used upon allocation.
                // Avoids searching for the next free block.
                FreeLinks free;

                // Used upon de-allocation.
                // Had this block split upon allocation, it and it's buddy is to be deleted.
                SplitLink split;
            };
        };

        void InsertFreeBlock(BuddyBlock* block, size_t level);
        void RemoveFreeBlock(BuddyBlock* block, size_t level);
        void DeleteBlock(BuddyBlock* block);

        uint64_t ComputeNumOfFreeBlocks(BuddyBlock* block) const;

        // Keep track the head and tail (for faster insertion/removal).
        struct BlockList {
            BuddyBlock* head = nullptr;  // First free block in level.
            // TODO(crbug.com/dawn/827): Track the tail.
        };

        BuddyBlock* mRoot = nullptr;  // Used to deallocate non-free blocks.

        uint64_t mMaxBlockSize = 0;

        // List of linked-lists of free blocks where the index is a level that
        // corresponds to a power-of-two sized block.
        std::vector<BlockList> mFreeLists;
    };

}  // namespace dawn::native

#endif  // SRC_DAWN_NATIVE_BUDDYALLOCATOR_H_
