1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/transaction/undo_buffer.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/common/common.hpp"
12#include "duckdb/common/enums/undo_flags.hpp"
13#include "duckdb/storage/arena_allocator.hpp"
14
15namespace duckdb {
16
17class WriteAheadLog;
18
19//! The undo buffer of a transaction is used to hold previous versions of tuples
20//! that might be required in the future (because of rollbacks or previous
21//! transactions accessing them)
22class UndoBuffer {
23public:
24 struct IteratorState {
25 ArenaChunk *current;
26 data_ptr_t start;
27 data_ptr_t end;
28 };
29
30public:
31 UndoBuffer(ClientContext &context);
32
33 //! Reserve space for an entry of the specified type and length in the undo
34 //! buffer
35 data_ptr_t CreateEntry(UndoFlags type, idx_t len);
36
37 bool ChangesMade();
38 idx_t EstimatedSize();
39
40 //! Cleanup the undo buffer
41 void Cleanup();
42 //! Commit the changes made in the UndoBuffer: should be called on commit
43 void Commit(UndoBuffer::IteratorState &iterator_state, optional_ptr<WriteAheadLog> log, transaction_t commit_id);
44 //! Revert committed changes made in the UndoBuffer up until the currently committed state
45 void RevertCommit(UndoBuffer::IteratorState &iterator_state, transaction_t transaction_id);
46 //! Rollback the changes made in this UndoBuffer: should be called on
47 //! rollback
48 void Rollback() noexcept;
49
50private:
51 ClientContext &context;
52 ArenaAllocator allocator;
53
54private:
55 template <class T>
56 void IterateEntries(UndoBuffer::IteratorState &state, T &&callback);
57 template <class T>
58 void IterateEntries(UndoBuffer::IteratorState &state, UndoBuffer::IteratorState &end_state, T &&callback);
59 template <class T>
60 void ReverseIterateEntries(T &&callback);
61};
62
63} // namespace duckdb
64