// ********************************************************** // Delete a record from a page. Returns OK if everything went okay. // Compacts remaining records but leaves a hole in the slot array. // Use memmove() rather than memcpy() as space may overlap. Status HFPage::deleteRecord(const RID& rid) { // fill in the body //--- deal with errors ---- if(rid.pageNo < 0 || rid.slotNo < 0) return MINIBASE_FIRST_ERROR(HEAPFILE, INVALID_SLOTNO); //return FAIL; if(rid.slotNo >= this->slotCnt) return MINIBASE_FIRST_ERROR(HEAPFILE, INVALID_SLOTNO); //return FAIL; //--- deal with empty page case --- if(empty()) return MINIBASE_FIRST_ERROR(HEAPFILE, NO_RECORDS); //return FAIL; //--- get record offset --- int offset = getRecordOffset(rid); //--- clean corresponding slot & get record length--- int len = cleanSlot(rid); //--- deal with already deleted case --- if(offset == INVALID_SLOT || len == EMPTY_SLOT) return MINIBASE_FIRST_ERROR(HEAPFILE, ALREADY_DELETED); //return FAIL; //-- shrink slot directory --- shrinkSlotDir(); //--- delete record & relocate behind records & slot dir --- //--- & update usedPtr, freeSpace ----- deleteRec(offset, len); return OK; }
// Pre-condition: front points to the head of a linked list structure. // Post-condition: The first node that contains the value num will be // removed from the list. A pointer to the front of the // list will be returned. If no such value is stored, // the list will remain unchanged. struct ll* deleteRec(struct ll *front, int num) { // No item in list, no delete to do. if (front == NULL) return NULL; // Deleting the first item. if (front->data == num) { // This is the list to return. struct ll* retval = front->next; // Need to free the deleted node. free(front); return retval; } // We can try to delete num from the rest of the list. struct ll* rest = deleteRec(front->next, num); // Attach the rest of the list to what is returned from the recursive call. front->next = rest; return front; // This is unchanged. }
// delete all records checked in the list bool Collectiondb::deleteRecs ( HttpRequest *r ) { for ( long i = 0 ; i < r->getNumFields() ; i++ ) { char *f = r->getField ( i ); if ( strncmp ( f , "del" , 3 ) != 0 ) continue; char *coll = f + 3; //if ( ! is_digit ( f[3] ) ) continue; //long h = atol ( f + 3 ); deleteRec ( coll ); } return true; }
// ********************************************************** // Delete a record from a page. Returns OK if everything went okay. // Compacts remaining records but leaves a hole in the slot array. // Use memmove() rather than memcpy() as space may overlap. Status HFPage::deleteRecord(const RID& rid) { // fill in the body //---?? 注意未处理delete不存在record得特殊情况---- //--- get record offset --- int offset = getRecordOffset(rid); //--- clean corresponding slot & get record length--- int len = cleanSlot(rid); //-- shrink slot directory --- shrinkSlotDir(); //--- delete record & relocate behind records & slot dir --- //--- & update usedPtr, freeSpace ----- deleteRec(offset, len); return OK; }
// . reset a collection // . returns false if failed bool Collectiondb::resetColl ( char *coll , bool resetTurkdb ) { // ensure it's not NULL if ( ! coll ) { log(LOG_LOGIC,"admin: Collection name to delete is NULL."); return false; } // now must be "test" only for now if ( strcmp(coll,"test") ) { char *xx=NULL;*xx=0; } // no spiders can be out. they may be referencing the CollectionRec // in XmlDoc.cpp... quite likely. if ( g_conf.m_spideringEnabled || g_spiderLoop.m_numSpidersOut > 0 ) { log("admin: Can not delete collection while " "spiders are enabled or active."); return false; } // do not allow this if in repair mode if ( g_repairMode > 0 ) { log("admin: Can not delete collection while in repair mode."); return false; } // get the CollectionRec for "test" CollectionRec *cr = getRec ( "test" ); // must be there. if not, we create test i guess if ( ! cr ) { log("db: could not get test coll rec"); char *xx=NULL;*xx=0; } // make sure an update not in progress if ( cr->m_inProgress ) { char *xx=NULL;*xx=0; } CollectionRec tmp; // copy it to "tmp" long size = (char *)&(cr->m_END_COPY) - (char *)cr; // do not copy the hashtable crap since you will have to re-init it! memcpy ( &tmp , cr , size ); // sizeof(CollectionRec) ); // delete the test coll now if ( ! deleteRec ( "test" , resetTurkdb ) ) return log("admin: reset coll failed"); // make a collection called "test2" so that we copy "test"'s parms bool status = addRec ( "test" , NULL , 0 , true , // bool isNew , (collnum_t) -1 , // not a dump false , // do not save it! false ); // bail on error if ( ! status ) return log("admin: failed to add new coll for reset"); // get its rec CollectionRec *nr = getRec ( "test" ); // must be there if ( ! nr ) { char *xx=NULL;*xx=0; } // save this though, this might have changed! collnum_t cn = nr->m_collnum; // overwrite its rec memcpy ( nr , &tmp , size ) ; // sizeof(CollectionRec) ); // put that collnum back nr->m_collnum = cn; // set the flag m_needsSave = true; // save it again after copy nr->save(); // and clear the robots.txt cache in case we recently spidered a // robots.txt, we don't want to use it, we want to use the one we // have in the test-parser subdir so we are consistent RdbCache *robots = Msg13::getHttpCacheRobots(); RdbCache *others = Msg13::getHttpCacheOthers(); robots->clear ( cn ); others->clear ( cn ); //g_templateTable.reset(); //g_templateTable.save( g_hostdb.m_dir , "turkedtemplates.dat" ); // repopulate CollectionRec::m_sortByDateTable. should be empty // since we are resetting here. //initSortByDateTable ( coll ); // done return true; }