1#include "duckdb/storage/table/chunk_info.hpp"
2#include "duckdb/transaction/transaction.hpp"
3
4using namespace duckdb;
5using namespace std;
6
7static bool UseVersion(Transaction &transaction, transaction_t id) {
8 return id < transaction.start_time || id == transaction.transaction_id;
9}
10
11//===--------------------------------------------------------------------===//
12// Delete info
13//===--------------------------------------------------------------------===//
14ChunkDeleteInfo::ChunkDeleteInfo(VersionManager &manager, idx_t start_row, ChunkInfoType type)
15 : ChunkInfo(manager, start_row, type) {
16 for (idx_t i = 0; i < STANDARD_VECTOR_SIZE; i++) {
17 deleted[i] = NOT_DELETED_ID;
18 }
19}
20
21ChunkDeleteInfo::ChunkDeleteInfo(ChunkDeleteInfo &info, ChunkInfoType type)
22 : ChunkInfo(info.manager, info.start, type) {
23 for (idx_t i = 0; i < STANDARD_VECTOR_SIZE; i++) {
24 deleted[i] = info.deleted[i];
25 }
26}
27
28idx_t ChunkDeleteInfo::GetSelVector(Transaction &transaction, SelectionVector &sel_vector, idx_t max_count) {
29 idx_t count = 0;
30 for (idx_t i = 0; i < max_count; i++) {
31 if (!UseVersion(transaction, deleted[i])) {
32 sel_vector.set_index(count++, i);
33 }
34 }
35 return count;
36}
37
38bool ChunkDeleteInfo::Fetch(Transaction &transaction, row_t row) {
39 return !UseVersion(transaction, deleted[row]);
40}
41
42void ChunkDeleteInfo::Delete(Transaction &transaction, row_t rows[], idx_t count) {
43 // first check the chunk for conflicts
44 for (idx_t i = 0; i < count; i++) {
45 if (deleted[rows[i]] != NOT_DELETED_ID) {
46 // tuple was already deleted by another transaction
47 throw TransactionException("Conflict on tuple deletion!");
48 }
49 }
50 // after verifying that there are no conflicts we mark the tuples as deleted
51 for (idx_t i = 0; i < count; i++) {
52 deleted[rows[i]] = transaction.transaction_id;
53 }
54}
55
56void ChunkDeleteInfo::CommitDelete(transaction_t commit_id, row_t rows[], idx_t count) {
57 for (idx_t i = 0; i < count; i++) {
58 deleted[rows[i]] = commit_id;
59 }
60}
61
62//===--------------------------------------------------------------------===//
63// Insert info
64//===--------------------------------------------------------------------===//
65ChunkInsertInfo::ChunkInsertInfo(VersionManager &manager, idx_t start_row)
66 : ChunkDeleteInfo(manager, start_row, ChunkInfoType::INSERT_INFO) {
67 for (idx_t i = 0; i < STANDARD_VECTOR_SIZE; i++) {
68 inserted[i] = NOT_DELETED_ID;
69 }
70}
71
72ChunkInsertInfo::ChunkInsertInfo(ChunkDeleteInfo &info) : ChunkDeleteInfo(info, ChunkInfoType::INSERT_INFO) {
73 for (idx_t i = 0; i < STANDARD_VECTOR_SIZE; i++) {
74 inserted[i] = NOT_DELETED_ID;
75 }
76}
77
78idx_t ChunkInsertInfo::GetSelVector(Transaction &transaction, SelectionVector &sel_vector, idx_t max_count) {
79 idx_t count = 0;
80 for (idx_t i = 0; i < max_count; i++) {
81 if (UseVersion(transaction, inserted[i]) && !UseVersion(transaction, deleted[i])) {
82 sel_vector.set_index(count++, i);
83 }
84 }
85 return count;
86}
87
88bool ChunkInsertInfo::Fetch(Transaction &transaction, row_t row) {
89 return UseVersion(transaction, inserted[row]) && !UseVersion(transaction, deleted[row]);
90}
91