Skip to content

Commit 1f0db37

Browse files
abhinavdangetichiyoung
authored andcommitted
MB-20323: New way of tracking file linkage with compaction
+ Getting rid of prevFile, newFile pointers + Adding a new parameter to the FileMgr class: newFileName + oldFileName and newFileName will be used to track the compaction order. + The next or the previous FileMgr pointer will now be retrieved from the FileMgrMap using strings: oldFileName and newFileName. Change-Id: Ia3c7f1a8370c1119f1e2aa1d3d8d4f845e5c9e03 Reviewed-on: http://review.couchbase.org/66318 Tested-by: buildbot <[email protected]> Reviewed-by: Chiyoung Seo <[email protected]>
1 parent 826cdcc commit 1f0db37

File tree

4 files changed

+128
-112
lines changed

4 files changed

+128
-112
lines changed

src/filemgr.cc

Lines changed: 64 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ void FileMgrMap::removeEntry(const std::string filename) {
231231
}
232232

233233
FileMgr* FileMgrMap::fetchEntry(const std::string filename) {
234+
if (filename.empty()) {
235+
return nullptr;
236+
}
237+
234238
FileMgr *file;
235239
spin_lock(&fileMapLock);
236240
auto it = fileMap.find(filename);
@@ -275,10 +279,10 @@ FileMgr::FileMgr()
275279
: refCount(1), fMgrFlags(0x00), blockSize(global_config.getBlockSize()),
276280
fopsHandle(nullptr), lastPos(0), lastCommit(0), lastWritableBmpRevnum(0),
277281
ioInprog(0), fMgrWal(nullptr), fMgrOps(nullptr), fMgrStatus(FILE_NORMAL),
278-
fileConfig(nullptr), newFile(nullptr), prevFile(nullptr), bCache(nullptr),
279-
inPlaceCompaction(false), fsType(0), kvHeader(nullptr),
280-
throttlingDelay(0), fMgrVersion(0), fMgrSb(nullptr), kvsStatOps(this),
281-
crcMode(CRC_DEFAULT), staleData(nullptr), latestDirtyUpdate(nullptr)
282+
fileConfig(nullptr), bCache(nullptr), inPlaceCompaction(false),
283+
fsType(0), kvHeader(nullptr), throttlingDelay(0), fMgrVersion(0),
284+
fMgrSb(nullptr), kvsStatOps(this), crcMode(CRC_DEFAULT),
285+
staleData(nullptr), latestDirtyUpdate(nullptr)
282286
{
283287

284288
fMgrHeader.bid = 0;
@@ -1521,28 +1525,6 @@ uint64_t FileMgr::fetchPrevHeader(uint64_t bid, void *buf, size_t *len,
15211525
return bid;
15221526
}
15231527

1524-
void FileMgr::updateFilePointers() {
1525-
// Update new_file pointers of all previously redirected downstream files
1526-
FileMgr *temp = getPrevFile();
1527-
while (temp != NULL) {
1528-
temp->acquireSpinLock();
1529-
if (temp->getNewFile() == this) {
1530-
temp->setNewFile(getNewFile());
1531-
}
1532-
temp->releaseSpinLock();
1533-
temp = temp->getPrevFile();
1534-
}
1535-
// Update prev_file pointer of the upstream file if any
1536-
FileMgr *new_file = getNewFile();
1537-
if (new_file != NULL) {
1538-
new_file->acquireSpinLock();
1539-
if (new_file->getPrevFile() == this) {
1540-
new_file->setPrevFile(getPrevFile());
1541-
}
1542-
new_file->releaseSpinLock();
1543-
}
1544-
}
1545-
15461528
fdb_status FileMgr::fileClose(struct filemgr_ops *ops,
15471529
fdb_fileops_handle fops_handle)
15481530
{
@@ -1598,10 +1580,11 @@ fdb_status FileMgr::close(FileMgr *file,
15981580
if (file->fMgrStatus.load() == FILE_REMOVED_PENDING) {
15991581

16001582
bool foreground_deletion = false;
1583+
FileMgr *new_file = FileMgrMap::get()->fetchEntry(file->newFileName);
16011584

16021585
// immediately remove file if background remove function is not set
16031586
if (!lazyFileDeletionEnabled ||
1604-
(file->newFile && file->newFile->inPlaceCompaction)) {
1587+
(new_file && new_file->inPlaceCompaction)) {
16051588
// TODO: to avoid the scenario below, we prevent background
16061589
// deletion of in-place compacted files at this time.
16071590
// 1) In-place compacted from 'A' to 'A.1'.
@@ -1627,7 +1610,6 @@ fdb_status FileMgr::close(FileMgr *file,
16271610
file->releaseSpinLock();
16281611
FileMgrMap::get()->removeEntry(file->getFileName());
16291612

1630-
file->updateFilePointers();
16311613
spin_unlock(&fileMgrOpenlock);
16321614

16331615
if (foreground_deletion) {
@@ -1645,13 +1627,11 @@ fdb_status FileMgr::close(FileMgr *file,
16451627
uint32_t old_file_refcount = 0;
16461628
FileMgr *orig_file = FileMgrMap::get()->fetchEntry(
16471629
orig_file_name);
1648-
if (!file->oldFileName.empty()) {
1649-
// get old file's ref count if exists
1650-
FileMgr *old_file = FileMgrMap::get()->fetchEntry(
1651-
file->oldFileName);
1652-
if (old_file) {
1653-
old_file_refcount = old_file->refCount.load();
1654-
}
1630+
// get old file's ref count if exists
1631+
FileMgr *old_file = FileMgrMap::get()->fetchEntry(
1632+
file->oldFileName);
1633+
if (old_file) {
1634+
old_file_refcount = old_file->refCount.load();
16551635
}
16561636

16571637
// If old file is opened by other handle, renaming should be
@@ -1677,7 +1657,6 @@ fdb_status FileMgr::close(FileMgr *file,
16771657
// Clean up FileMgrFactory's unordered map, WAL index, and buffer cache.
16781658
FileMgrMap::get()->removeEntry(file->getFileName());
16791659

1680-
file->updateFilePointers();
16811660
spin_unlock(&fileMgrOpenlock);
16821661

16831662
FileMgr::freeFunc(file);
@@ -1779,8 +1758,10 @@ void FileMgr::removeFile(FileMgr *file,
17791758
FileMgrMap::get()->removeEntry(file->fileName);
17801759
spin_unlock(&fileMgrOpenlock);
17811760

1761+
FileMgr *new_file = FileMgrMap::get()->fetchEntry(file->newFileName);
1762+
17821763
if (!lazyFileDeletionEnabled ||
1783-
(file->newFile && file->newFile->inPlaceCompaction)) {
1764+
(new_file && new_file->inPlaceCompaction)) {
17841765
FileMgr::freeFunc(file);
17851766
} else {
17861767
registerFileRemoval(file, log_callback);
@@ -2566,33 +2547,48 @@ fdb_status FileMgr::copyFileRange(FileMgr *src_file,
25662547
return FDB_RESULT_SUCCESS;
25672548
}
25682549

2569-
int FileMgr::updateFileStatus(file_status_t status, const char *old_filename) {
2570-
int ret = 1;
2550+
void FileMgr::updateFileStatus(file_status_t status) {
25712551
acquireSpinLock();
25722552
fMgrStatus = status;
2553+
releaseSpinLock();
2554+
}
2555+
2556+
bool FileMgr::updateFileLinkage(const char *old_filename,
2557+
const char *new_filename) {
2558+
bool ret = true;
2559+
acquireSpinLock();
25732560
if (old_filename) {
25742561
if (oldFileName.empty()) {
25752562
oldFileName = std::string(old_filename);
25762563
} else {
2577-
ret = 0;
2564+
ret = false;
25782565
fdb_assert(refCount.load(), refCount.load(), 0);
25792566
}
25802567
}
2568+
if (new_filename) {
2569+
newFileName = std::string(new_filename);
2570+
}
25812571
releaseSpinLock();
25822572
return ret;
25832573
}
25842574

25852575
void FileMgr::setCompactionState(FileMgr *old_file, FileMgr *new_file,
25862576
file_status_t status) {
2587-
spin_lock(&old_file->fMgrLock);
2588-
old_file->newFile = new_file;
2589-
old_file->fMgrStatus = status;
2590-
spin_unlock(&old_file->fMgrLock);
2577+
if (old_file) {
2578+
spin_lock(&old_file->fMgrLock);
2579+
if (new_file) {
2580+
old_file->newFileName = std::string(new_file->getFileName());
2581+
} else {
2582+
old_file->newFileName.clear();
2583+
}
2584+
old_file->fMgrStatus = status;
2585+
spin_unlock(&old_file->fMgrLock);
25912586

2592-
if (new_file) {
2593-
spin_lock(&new_file->fMgrLock);
2594-
new_file->prevFile = old_file;
2595-
spin_unlock(&new_file->fMgrLock);
2587+
if (new_file) {
2588+
spin_lock(&new_file->fMgrLock);
2589+
new_file->oldFileName = std::string(old_file->getFileName());
2590+
spin_unlock(&new_file->fMgrLock);
2591+
}
25962592
}
25972593
}
25982594

@@ -2628,7 +2624,7 @@ static void *_filemgr_check_stale_link(FileMgr *file, void *ctx) {
26282624
FileMgr *cur_file = reinterpret_cast<FileMgr *>(ctx);
26292625
file->acquireSpinLock();
26302626
if (file->getFileStatus() == FILE_REMOVED_PENDING &&
2631-
file->getNewFile() == cur_file) {
2627+
file->getNewFileName().compare(std::string(cur_file->getFileName())) == 0) {
26322628
// Incrementing reference counter below is the same as Filemgr::open()
26332629
// We need to do this to ensure that the pointer returned does not
26342630
// get freed outside the filemgr_open lock
@@ -2652,27 +2648,34 @@ FileMgr* FileMgr::searchStaleLinks() {
26522648
char* FileMgr::redirectOldFile(FileMgr *very_old_file,
26532649
FileMgr *new_file,
26542650
filemgr_redirect_hdr_func redirect_header_func) {
2651+
if (!very_old_file || !new_file) {
2652+
return NULL;
2653+
}
2654+
26552655
size_t old_header_len, new_header_len;
26562656
char *past_filename;
26572657
spin_lock(&very_old_file->fMgrLock);
26582658

2659-
if (very_old_file->accessHeader()->size == 0 || very_old_file->newFile == NULL) {
2659+
FileMgr *newFile = FileMgrMap::get()->fetchEntry(very_old_file->newFileName);
2660+
2661+
if (very_old_file->accessHeader()->size == 0 || !newFile ) {
26602662
spin_unlock(&very_old_file->fMgrLock);
26612663
return NULL;
26622664
}
26632665

26642666
old_header_len = very_old_file->accessHeader()->size;
26652667
// Find out the new DB header length with new_file's filename
26662668
new_header_len = old_header_len -
2667-
very_old_file->newFile->getFileNameLen() + new_file->getFileNameLen();
2669+
newFile->getFileNameLen() + new_file->getFileNameLen();
26682670
// As we are going to change the new_filename field in the DB header of the
26692671
// very_old_file, maybe reallocate DB header buf to accomodate bigger value
26702672
if (new_header_len > old_header_len) {
26712673
very_old_file->accessHeader()->data = realloc(very_old_file->accessHeader()->data,
2672-
new_file->getBlockSize());
2674+
new_file->getBlockSize());
26732675
}
2674-
very_old_file->newFile = new_file; // Re-direct very_old_file to new_file
2675-
// Note that the prev_file pointer of the new_file is not updated, this
2676+
// Re-direct very_old_file to new_file
2677+
very_old_file->newFileName = std::string(new_file->getFileName());
2678+
// Note that the oldFileName of the new_file is not updated, this
26762679
// is so that every file in the history is reachable from the current file.
26772680

26782681
past_filename = redirect_header_func(very_old_file,
@@ -2688,14 +2691,14 @@ char* FileMgr::redirectOldFile(FileMgr *very_old_file,
26882691
void FileMgr::removePending(FileMgr *old_file,
26892692
FileMgr *new_file,
26902693
ErrLogCallback *log_callback) {
2691-
if (new_file == NULL) {
2694+
if (old_file == NULL || new_file == NULL) {
26922695
return;
26932696
}
26942697

26952698
spin_lock(&old_file->fMgrLock);
26962699
if (old_file->refCount.load() > 0) {
26972700
// delay removing
2698-
old_file->newFile = new_file;
2701+
old_file->newFileName = std::string(new_file->getFileName());
26992702
old_file->fMgrStatus.store(FILE_REMOVED_PENDING);
27002703

27012704
#if !(defined(WIN32) || defined(_WIN32))
@@ -2713,17 +2716,19 @@ void FileMgr::removePending(FileMgr *old_file,
27132716

27142717
spin_unlock(&old_file->fMgrLock);
27152718

2716-
// Update new_file's prevFile link
2719+
// Update new_file's oldFileName
27172720
spin_lock(&new_file->fMgrLock);
2718-
new_file->prevFile = old_file;
2721+
new_file->oldFileName = std::string(old_file->getFileName());
27192722
spin_unlock(&new_file->fMgrLock);
27202723
} else {
27212724
// immediatly remove
27222725
// LCOV_EXCL_START
27232726
spin_unlock(&old_file->fMgrLock);
27242727

2728+
FileMgr *new_file = FileMgrMap::get()->fetchEntry(old_file->newFileName);
2729+
27252730
if (!lazyFileDeletionEnabled ||
2726-
(old_file->newFile && old_file->newFile->inPlaceCompaction)) {
2731+
(new_file && new_file->inPlaceCompaction)) {
27272732
remove(old_file->fileName);
27282733
}
27292734
FileMgr::removeFile(old_file, log_callback);

src/filemgr.h

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -628,26 +628,14 @@ class FileMgr {
628628
return fileConfig;
629629
}
630630

631-
void setNewFile(FileMgr *to) {
632-
newFile = to;
633-
}
634-
635-
FileMgr* getNewFile() {
636-
return newFile;
637-
}
638-
639-
void setPrevFile(FileMgr *to) {
640-
prevFile = to;
641-
}
642-
643-
FileMgr* getPrevFile() {
644-
return prevFile;
645-
}
646-
647631
const std::string& getOldFileName() {
648632
return oldFileName;
649633
}
650634

635+
const std::string& getNewFileName() {
636+
return newFileName;
637+
}
638+
651639
void setBCache(FileBlockCache *to) {
652640
bCache.store(to, std::memory_order_relaxed);
653641
}
@@ -794,7 +782,15 @@ class FileMgr {
794782

795783
fdb_status sync_FileMgr(bool sync_option, ErrLogCallback *log_callback);
796784

797-
int updateFileStatus(file_status_t status, const char *old_filename);
785+
void updateFileStatus(file_status_t status);
786+
787+
/**
788+
* Updates the oldFileName and newFileName of the current instance,
789+
* with the arguments (non-null) provided.
790+
*
791+
* Returns false if oldFileName has already been set.
792+
*/
793+
bool updateFileLinkage(const char *old_filename, const char *new_filename);
798794

799795
bool isRollbackOn();
800796

@@ -1126,11 +1122,6 @@ class FileMgr {
11261122

11271123
private:
11281124

1129-
/**
1130-
* Update the previous / next file pointers for a given file
1131-
*/
1132-
void updateFilePointers();
1133-
11341125
/**
11351126
* Remove a given dirty node from the dirty block tree
11361127
*/
@@ -1220,9 +1211,8 @@ class FileMgr {
12201211
struct filemgr_ops *fMgrOps;
12211212
std::atomic<uint8_t> fMgrStatus;
12221213
FileMgrConfig *fileConfig;
1223-
FileMgr *newFile; // Pointer to new file upon compaction
1224-
FileMgr *prevFile; // Pointer to prev file upon compaction
12251214
std::string oldFileName; // Old file name before compaction
1215+
std::string newFileName; // Latest filename after compaction
12261216
std::atomic<FileBlockCache *> bCache;
12271217
fdb_txn globalTxn;
12281218
bool inPlaceCompaction;

0 commit comments

Comments
 (0)