#pragma once #include "duckdb/common/mutex.hpp" #include "duckdb/common/file_buffer.hpp" #include "duckdb/storage/buffer/block_handle.hpp" namespace duckdb { struct EvictionQueue; struct BufferEvictionNode { BufferEvictionNode() { } BufferEvictionNode(weak_ptr handle_p, idx_t timestamp_p) : handle(std::move(handle_p)), timestamp(timestamp_p) { D_ASSERT(!handle.expired()); } weak_ptr handle; idx_t timestamp; bool CanUnload(BlockHandle &handle_p); shared_ptr TryGetBlockHandle(); }; //! The BufferPool is in charge of handling memory management for one or more databases. It defines memory limits //! and implements priority eviction among all users of the pool. class BufferPool { friend class BlockHandle; friend class BlockManager; friend class BufferManager; friend class StandardBufferManager; public: explicit BufferPool(idx_t maximum_memory); virtual ~BufferPool(); //! Set a new memory limit to the buffer pool, throws an exception if the new limit is too low and not enough //! blocks can be evicted void SetLimit(idx_t limit, const char *exception_postscript); void IncreaseUsedMemory(idx_t size); idx_t GetUsedMemory(); idx_t GetMaxMemory(); protected: //! Evict blocks until the currently used memory + extra_memory fit, returns false if this was not possible //! (i.e. not enough blocks could be evicted) //! If the "buffer" argument is specified AND the system can find a buffer to re-use for the given allocation size //! "buffer" will be made to point to the re-usable memory. Note that this is not guaranteed. //! Returns a pair. result.first indicates if eviction was successful. result.second contains the //! reservation handle, which can be moved to the BlockHandle that will own the reservation. struct EvictionResult { bool success; TempBufferPoolReservation reservation; }; virtual EvictionResult EvictBlocks(idx_t extra_memory, idx_t memory_limit, unique_ptr *buffer = nullptr); //! Garbage collect eviction queue void PurgeQueue(); void AddToEvictionQueue(shared_ptr &handle); private: //! The lock for changing the memory limit mutex limit_lock; //! The current amount of memory that is occupied by the buffer manager (in bytes) atomic current_memory; //! The maximum amount of memory that the buffer manager can keep (in bytes) atomic maximum_memory; //! Eviction queue unique_ptr queue; //! Total number of insertions into the eviction queue. This guides the schedule for calling PurgeQueue. atomic queue_insertions; }; } // namespace duckdb