bool LogManager::Truncate(uint64_t index,uint64_t term){ abb::Mutex::Locker l(mtx_); LOG(TRACE) << "log.truncate: " << index; if(index < this->commit_index_){ LOG(DEBUG) << "log.truncate.before"; return false; } if(index > (log_entry_arr_.size() + start_index_)){ LOG(DEBUG) << "log.truncate.after" << index << ":"<< log_entry_arr_.size() << "+" << start_index_ << "commit_index:" << commit_index_; return false; } if(index == this->start_index_){ lseek(fd_,0, SEEK_SET); ftruncate(fd_,0); for(unsigned st=0;st < this->log_entry_arr_.size() ;st++){ LogEntry* entry = log_entry_arr_[st]; if(entry->ev_){ if(entry->ev_){ entry->ev_->Notify(NULL,"command failed to be committed due to node failure"); entry->ev_->UnRef(); entry->ev_ = NULL; } entry->UnRef(); } } this->log_entry_arr_.clear(); }else{ if(index < (this->start_index_+this->log_entry_arr_.size()) ){ int st = index - this->start_index_ -1; LogEntry* entry = this->log_entry_arr_[st]; if (this->log_entry_arr_.size()> 0 && entry->term_ != term ){ LOG(DEBUG) << "log.truncate.termMismatch"; return false; }else{ int start = index - this->start_index_; LogEntry* entry = this->log_entry_arr_[start]; ftruncate(fd_,entry->position); lseek(fd_,entry->position, SEEK_SET); for(int i=start;i < (int)this->log_entry_arr_.size();i++){ LogEntry* inentry = this->log_entry_arr_[i]; if(inentry){ if(inentry->ev_){ inentry->ev_->Notify(NULL,"command failed to be committed due to node failure"); inentry->ev_->UnRef(); inentry->ev_ = NULL; } inentry->UnRef(); } } this->log_entry_arr_.erase(this->log_entry_arr_.begin()+start,this->log_entry_arr_.end()); LOG(DEBUG) << "log.truncate.success" << this->start_index_ << "/" << this->log_entry_arr_.size(); } } } return true; }
bool LogManager::Open(const std::string& path){ path_ = path; abb::Mutex::Locker l(mtx_); fd_ = open(path.c_str(),O_RDWR,0600); if(fd_ < 0){ LOG(WARN)<< "raft.open.file.failed:"<<path<< " err:" <<errno<<" errstr:" << strerror(errno); fd_ = open(path.c_str(),O_RDWR|O_CREAT,0600); if(fd_ < 0){ LOG(WARN)<< "raft.create.file.failed:"<<path<< " err:" <<errno<<" errstr:" << strerror(errno); return false; } LOG(DEBUG)<< "log.open.create " << path; return true; } fcntl(fd_, F_SETFD, FD_CLOEXEC); LOG(DEBUG)<< "log.open.exist " << path; lseek(fd_,0,SEEK_SET); abb::Buffer buf; while( buf.WriteFromeReader(StaticReader,this) > 0){ ; } int position = 0; int size = buf.ReadSize(); while(size > 0){ LogEntry* entry = new LogEntry(); if( ! entry->Decode(buf) ) { entry->UnRef(); return false; } entry->position = position; if(entry->index_ > this->start_index_){ entry->Ref(); this->log_entry_arr_.push_back(entry); if(entry->index_ <= this->commit_index_){ entry->cmd_->Apply(this->svr_,NULL,NULL); } } position += size - buf.ReadSize(); entry->UnRef(); size = buf.ReadSize(); } if(this->log_entry_arr_.size() > 0){ LOG(DEBUG) << "open.log.append log index " << this->log_entry_arr_.front()->index_ << ":" <<this->log_entry_arr_.back()->index_ << " " << this->commit_index_; } return true; }
bool LogManager::CommitToIndex(uint64_t index){ LogEntryArray arr; { LOG(TRACE) << "CommitToIndex" << index; abb::Mutex::Locker l(mtx_); if(index > (log_entry_arr_.size() + start_index_)){ LOG(DEBUG) << "raft.Log: Commit index" << index << "set back to " << ( log_entry_arr_.size() + start_index_); index = log_entry_arr_.size() + start_index_; } if (index < commit_index_) { LOG(DEBUG) << "raft.Log: Commit index earily :" << index << "commit_index_:" << commit_index_; return true; } for(unsigned i= this->commit_index_+1;i<=index;i++){ int e_index = i - 1 - this->start_index_; LogEntry* entry = log_entry_arr_[e_index]; this->commit_index_ = entry->index_; entry->Ref(); arr.push_back(entry); } } for(unsigned i = 0;i< arr.size();i++){ LogEntry* entry = arr[i]; if(entry->ev_){ IMessage* msg = NULL; std::string error ; entry->cmd_->Apply(this->svr_,&error,&msg); entry->ev_->Notify(msg,error); entry->ev_->UnRef(); entry->ev_ = NULL; }else{ entry->cmd_->Apply(this->svr_,NULL,NULL); } entry->UnRef(); } return true; }