Implementation:ClickHouse ClickHouse BorrowedObjectPool
| Knowledge Sources | |
|---|---|
| Domains | Concurrency, Resource_Management |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
A thread-safe object pool that manages reusable objects with borrowing semantics and optional size limits.
Description
`BorrowedObjectPool` is a generic template class that maintains a pool of reusable objects that can be borrowed by threads and returned later. It supports unlimited or limited pool sizes, lazy object creation via factory functions, and blocking or timeout-based borrowing. Objects are allocated on-demand and reused across multiple borrow/return cycles, reducing allocation overhead. The implementation uses mutexes and condition variables to coordinate access between threads, ensuring thread-safe borrowing and returning operations.
Key features include:
- Lazy initialization - objects created only when needed
- Optional size limits with blocking when pool is exhausted
- Timeout support for non-blocking borrow attempts
- Factory function pattern for flexible object creation
- Thread-safe access tracking
Usage
Use this implementation when you need to:
- Reuse expensive-to-create objects across threads
- Limit the number of concurrent resource handles (database connections, file handles)
- Implement object recycling to reduce allocation overhead
- Coordinate resource access between multiple threads
Code Reference
Source Location
- Repository: ClickHouse
- File: base/base/BorrowedObjectPool.h
- Lines: 1-158
Signature
template <typename T>
class BorrowedObjectPool
{
public:
explicit BorrowedObjectPool(size_t max_size_);
template <typename FactoryFunc>
void borrowObject(T & dest, FactoryFunc && func);
template <typename FactoryFunc>
bool tryBorrowObject(T & dest, FactoryFunc && func, size_t timeout_in_milliseconds = 0);
void returnObject(T && object_to_return);
size_t maxSize() const;
size_t allocatedObjectsSize() const;
size_t borrowedObjectsSize() const;
bool isFull() const;
};
Import
#include <base/BorrowedObjectPool.h>
I/O Contract
| Input | Type | Description |
|---|---|---|
| max_size | size_t | Maximum pool size (0 = unlimited) |
| factory_func | FactoryFunc | Function to create new objects: T () |
| timeout_ms | size_t | Timeout for tryBorrowObject in milliseconds |
| Output | Type | Description |
|---|---|---|
| dest | T& | Borrowed object (via reference parameter) |
| success | bool | Whether borrow succeeded (for tryBorrowObject) |
Usage Examples
#include <base/BorrowedObjectPool.h>
#include <memory>
#include <string>
// Pool for database connections
struct DBConnection { /* ... */ };
BorrowedObjectPool<std::shared_ptr<DBConnection>> connection_pool(10);
// Borrow with factory function
std::shared_ptr<DBConnection> conn;
connection_pool.borrowObject(conn, []() {
return std::make_shared<DBConnection>("localhost", 5432);
});
// Use connection...
connection_pool.returnObject(std::move(conn));
// Try borrow with timeout
std::shared_ptr<DBConnection> conn2;
if (connection_pool.tryBorrowObject(conn2, []() {
return std::make_shared<DBConnection>("localhost", 5432);
}, 1000)) {
// Use connection...
connection_pool.returnObject(std::move(conn2));
} else {
// Timeout - pool exhausted
}
// Check pool status
size_t allocated = connection_pool.allocatedObjectsSize();
size_t borrowed = connection_pool.borrowedObjectsSize();
bool full = connection_pool.isFull();
// Unlimited size pool
BorrowedObjectPool<std::string> string_pool(0);