void Indexer_commit(Indexer *self) { // Safety check. if ( !self->write_lock ) { THROW(ERR, "Can't call commit() more than once"); } if (!self->prepared) { Indexer_Prepare_Commit(self); } if (self->needs_commit) { bool_t success; // Rename temp snapshot file. CharBuf *temp_snapfile = CB_Clone(self->snapfile); CB_Chop(self->snapfile, sizeof(".temp") - 1); Snapshot_Set_Path(self->snapshot, self->snapfile); success = Folder_Rename(self->folder, temp_snapfile, self->snapfile); DECREF(temp_snapfile); if (!success) { RETHROW(INCREF(Err_get_error())); } // Purge obsolete files. FilePurger_Purge(self->file_purger); } // Release locks, invalidating the Indexer. S_release_merge_lock(self); S_release_write_lock(self); }
void BGMerger_Commit_IMP(BackgroundMerger *self) { BackgroundMergerIVARS *const ivars = BGMerger_IVARS(self); // Safety check. if (!ivars->merge_lock) { THROW(ERR, "Can't call commit() more than once"); } if (!ivars->prepared) { BGMerger_Prepare_Commit(self); } if (ivars->needs_commit) { bool success = false; String *temp_snapfile = ivars->snapfile; // Rename temp snapshot file. size_t ext_len = sizeof(".temp") - 1; size_t snapfile_len = Str_Length(temp_snapfile); if (snapfile_len <= ext_len) { THROW(ERR, "Invalid snapfile name: %o", temp_snapfile); } ivars->snapfile = Str_SubString(temp_snapfile, 0, snapfile_len - ext_len); success = Folder_Hard_Link(ivars->folder, temp_snapfile, ivars->snapfile); Snapshot_Set_Path(ivars->snapshot, ivars->snapfile); if (!success) { String *mess = Str_newf("Can't create hard link from %o to %o", temp_snapfile, ivars->snapfile); DECREF(temp_snapfile); Err_throw_mess(ERR, mess); } if (!Folder_Delete(ivars->folder, temp_snapfile)) { String *mess = Str_newf("Can't delete %o", temp_snapfile); DECREF(temp_snapfile); Err_throw_mess(ERR, mess); } DECREF(temp_snapfile); } // Release the merge lock and remove the merge data file. S_release_merge_lock(self); IxManager_Remove_Merge_Data(ivars->manager); if (ivars->needs_commit) { // Purge obsolete files. FilePurger_Purge(ivars->file_purger); } // Release the write lock. S_release_write_lock(self); }
void Indexer_Commit_IMP(Indexer *self) { IndexerIVARS *const ivars = Indexer_IVARS(self); // Safety check. if (!ivars->write_lock) { THROW(ERR, "Can't call commit() more than once"); } if (!ivars->prepared) { Indexer_Prepare_Commit(self); } if (ivars->needs_commit) { bool success; // Rename temp snapshot file. String *temp_snapfile = ivars->snapfile; size_t ext_len = sizeof(".temp") - 1; size_t snapfile_len = Str_Length(temp_snapfile); if (snapfile_len <= ext_len) { THROW(ERR, "Invalid snapfile name: %o", temp_snapfile); } ivars->snapfile = Str_SubString(temp_snapfile, 0, snapfile_len - ext_len); Snapshot_Set_Path(ivars->snapshot, ivars->snapfile); success = Folder_Rename(ivars->folder, temp_snapfile, ivars->snapfile); DECREF(temp_snapfile); if (!success) { RETHROW(INCREF(Err_get_error())); } // Purge obsolete files. FilePurger_Purge(ivars->file_purger); } // Release locks, invalidating the Indexer. S_release_merge_lock(self); S_release_write_lock(self); }
static void test_path_handling(TestBatchRunner *runner) { Snapshot *snapshot = Snapshot_new(); Folder *folder = (Folder*)RAMFolder_new(NULL); String *snap = (String*)SSTR_WRAP_UTF8("snap", 4); String *crackle = (String*)SSTR_WRAP_UTF8("crackle", 7); Snapshot_Write_File(snapshot, folder, snap); TEST_TRUE(runner, Str_Equals(snap, (Obj*)Snapshot_Get_Path(snapshot)), "Write_File() sets path as a side effect"); Folder_Rename(folder, snap, crackle); Snapshot_Read_File(snapshot, folder, crackle); TEST_TRUE(runner, Str_Equals(crackle, (Obj*)Snapshot_Get_Path(snapshot)), "Read_File() sets path as a side effect"); Snapshot_Set_Path(snapshot, snap); TEST_TRUE(runner, Str_Equals(snap, (Obj*)Snapshot_Get_Path(snapshot)), "Set_Path()"); DECREF(folder); DECREF(snapshot); }