# Deconstructing the DuckDB Buffer System.. Part 2

After deconstructing the bufferpool, I was off to analysing the `block_manager.cpp`(here's a [link](https://github.com/duckdb/duckdb/tree/v2.0-cyanoptera/src/storage/buffer) to it). The question at the core of this component of the buffer system was "How is a disk block requested?”.

The caller identifies the block through its `BlockHandle`; it asks the `BufferManager` to pin that block. If the block's contents are not currently in RAM, DuckDB first gets a piece of RAM for that block, and then reads the block's bytes from disk into that RAM.

Alongside this question, there were many others which I encountered. Here are my answers to all of them:

> What is the difference between the roles and capabilities of `BufferPool` and `BufferManager`?

`BufferManager` manages buffers; `BufferPool` provides/manages the underlying memory resource and the mechanisms needed to make that management possible.

**BufferManager = higher-level buffer operations(receptionist & executioner)**

*   allocate memory
    
*   pin blocks
    
*   unpin blocks
    
*   coordinate loading/freeing
    
*   interact with other DuckDB components
    

**BufferPool = underlying memory-resource management**

*   tracks the available memory capacity
    
*   tracks memory consumption
    
*   participates in eviction
    
*   reclaims memory when necessary
    
*   provides the memory resource that the BufferManager operates against
    

> What is a `blockid`? What is a `BlockHandle`? How does it differ from a `BlockMemory`object?

A `blockid` is simply an identifier for a block.

A `BlockHandle` is the C++ object that holds *all* the information DuckDB needs to ‘handle’ or manage block 42.

Eg:

![](https://cdn.hashnode.com/uploads/covers/6a9c0a2185b7af57ae3ad6a6/0e0d8aa5-ecb8-495b-86c1-0880af4fedcd.png align="left")

A persistent block can have a `block_id` without currently having a `BlockHandle`.

It can exist even when the block's contents are not currently in RAM.

A `BlockMemory` object on other hand only stores information about the memory state(pinned, unpinned etc) and the location of the block in the RAM(i.e. which buffer). A `BlockMemory` object is a component i.e. subset of a `BlockHandle`object.

> What is a `BlockManager`?

An instance of `BlockManager`owns and manages a collection of `BlockHandle`objects. Here, ownership of a block means “This BlockManager keeps track of this handle”, or that the block belongs to this `BlockManager`'s storage context. Multiple blocks can have the same `blockid`, but not the same manager, therefore to refer to a block one needs 1. the instance of `BlockManager` owning that block and 2. the `blockid`. Neither of them can individually address a block.

> What’s the difference between TryGetBlock() and RegisterBlock()?

![](https://cdn.hashnode.com/uploads/covers/6a9c0a2185b7af57ae3ad6a6/c0300b5b-7873-41a8-b2ee-eaac80e10d3c.png align="left")

Does `RegisterBlock()` fill every field of a `BlockHandle` once it creates it?

No, `RegisterBlock()` itself isn't manually filling every field of a `BlockHandle`. It constructs the `BlockHandle`, and the `BlockHandle`'s implementation determines what information it contains.

> Where does the usage of weak\_ptr come in the picture of blockid, b\_handle, b\_manager etc if anywhere?

The BlockManager keeps a weak\_ptr reference to the blockhandles that correspond to that instance.

> What is the `BufferHandle`?

`BufferHandle` gives you temporary access to the RAM buffer that currently contains the block's data, not ownership/management of the block itself.

> What does expire and lock do or return wrt a weak ptr?

`lock()` returns nullptr if the object doesn’t exist anymore and a `shared_ptr` to the object if it does, whereas `expire()` gives boolean value for the same.
