| 121 | } |
| 122 | |
| 123 | void DiskArrayInternal::update(const Transaction* transaction, uint64_t idx, |
| 124 | std::span<std::byte> val) { |
| 125 | std::unique_lock xLck{diskArraySharedMtx}; |
| 126 | hasTransactionalUpdates = true; |
| 127 | DASSERT(checkOutOfBoundAccess(transaction->getType(), idx)); |
| 128 | auto apCursor = getAPIdxAndOffsetInAP(storageInfo, idx); |
| 129 | // TODO: We are currently supporting only DiskArrays that can grow in size and not |
| 130 | // those that can shrink in size. That is why we can use |
| 131 | // getAPPageIdxNoLock(apIdx, Transaction::WRITE) directly to compute the physical page Idx |
| 132 | // because any apIdx is guaranteed to be either in an existing PIP or a new PIP we added, which |
| 133 | // getAPPageIdxNoLock will correctly locate: this function simply searches an existing PIP if |
| 134 | // apIdx < numAPs stored in "previous" PIP; otherwise one of the newly inserted PIPs stored in |
| 135 | // pipPageIdxsOfInsertedPIPs. If within a single transaction we could grow or shrink, then |
| 136 | // getAPPageIdxNoLock logic needs to change to give the same guarantee (e.g., an apIdx = 0, may |
| 137 | // no longer to be guaranteed to be in pips[0].) |
| 138 | page_idx_t apPageIdx = getAPPageIdxNoLock(apCursor.pageIdx, transaction->getType()); |
| 139 | updatePage(apPageIdx, false /*isNewPage=*/, [&apCursor, &val](uint8_t* frame) -> void { |
| 140 | memcpy(frame + apCursor.elemPosInPage, val.data(), val.size()); |
| 141 | }); |
| 142 | } |
| 143 | |
| 144 | uint64_t DiskArrayInternal::resize(PageAllocator& pageAllocator, const Transaction* transaction, |
| 145 | uint64_t newNumElements, std::span<std::byte> defaultVal) { |
nothing calls this directly
no test coverage detected