int SSDB::qfix(const Bytes &name){ Transaction trans(binlogs); std::string key_s = encode_qitem_key(name, QITEM_MIN_SEQ - 1); std::string key_e = encode_qitem_key(name, QITEM_MAX_SEQ); bool error = false; uint64_t seq_min = 0; uint64_t seq_max = 0; uint64_t count = 0; Iterator *it = this->iterator(key_s, key_e, QITEM_MAX_SEQ); while(it->next()){ //dump(it->key().data(), it->key().size()); if(seq_min == 0){ if(decode_qitem_key(it->key(), NULL, &seq_min) == -1){ // or just delete it? error = true; break; } } if(decode_qitem_key(it->key(), NULL, &seq_max) == -1){ error = true; break; } count ++; } delete it; if(error){ return -1; } if(count == 0){ this->binlogs->Delete(encode_qsize_key(name)); qdel_one(this, name, QFRONT_SEQ); qdel_one(this, name, QBACK_SEQ); }else{ this->binlogs->Put(encode_qsize_key(name), leveldb::Slice((char *)&count, sizeof(count))); qset_one(this, name, QFRONT_SEQ, Bytes(&seq_min, sizeof(seq_min))); qset_one(this, name, QBACK_SEQ, Bytes(&seq_max, sizeof(seq_max))); } leveldb::Status s = binlogs->commit(); if(!s.ok()){ log_error("Write error!"); return -1; } return 0; }
int Slave::proc_sync(const Binlog &log, const std::vector<Bytes> &req){ switch(log.cmd()){ case BinlogCommand::KSET: { if(req.size() != 2){ break; } std::string key; if(decode_kv_key(log.key(), &key) == -1){ break; } log_trace("set %s", hexmem(key.data(), key.size()).c_str()); if(ssdb->set(key, req[1], log_type) == -1){ return -1; } } break; case BinlogCommand::KDEL: { std::string key; if(decode_kv_key(log.key(), &key) == -1){ break; } log_trace("del %s", hexmem(key.data(), key.size()).c_str()); if(ssdb->del(key, log_type) == -1){ return -1; } } break; case BinlogCommand::HSET: { if(req.size() != 2){ break; } std::string name, key; if(decode_hash_key(log.key(), &name, &key) == -1){ break; } log_trace("hset %s %s", hexmem(name.data(), name.size()).c_str(), hexmem(key.data(), key.size()).c_str()); if(ssdb->hset(name, key, req[1], log_type) == -1){ return -1; } } break; case BinlogCommand::HDEL: { std::string name, key; if(decode_hash_key(log.key(), &name, &key) == -1){ break; } log_trace("hdel %s %s", hexmem(name.data(), name.size()).c_str(), hexmem(key.data(), key.size()).c_str()); if(ssdb->hdel(name, key, log_type) == -1){ return -1; } } break; case BinlogCommand::ZSET: { if(req.size() != 2){ break; } std::string name, key; if(decode_zset_key(log.key(), &name, &key) == -1){ break; } log_trace("zset %s %s", hexmem(name.data(), name.size()).c_str(), hexmem(key.data(), key.size()).c_str()); if(ssdb->zset(name, key, req[1], log_type) == -1){ return -1; } } break; case BinlogCommand::ZDEL: { std::string name, key; if(decode_zset_key(log.key(), &name, &key) == -1){ break; } log_trace("zdel %s %s", hexmem(name.data(), name.size()).c_str(), hexmem(key.data(), key.size()).c_str()); if(ssdb->zdel(name, key, log_type) == -1){ return -1; } } break; case BinlogCommand::QSET: case BinlogCommand::QPUSH_BACK: case BinlogCommand::QPUSH_FRONT: { if(req.size() != 2){ break; } std::string name; uint64_t seq; if(decode_qitem_key(log.key(), &name, &seq) == -1){ break; } if(seq < QITEM_MIN_SEQ || seq > QITEM_MAX_SEQ){ break; } int ret; if(log.cmd() == BinlogCommand::QSET){ log_trace("qset %s %" PRIu64 "", hexmem(name.data(), name.size()).c_str(), seq); ret = ssdb->qset_by_seq(name, seq, req[1], log_type); }else if(log.cmd() == BinlogCommand::QPUSH_BACK){ log_trace("qpush_back %s", hexmem(name.data(), name.size()).c_str()); ret = ssdb->qpush_back(name, req[1], log_type); }else{ log_trace("qpush_front %s", hexmem(name.data(), name.size()).c_str()); ret = ssdb->qpush_front(name, req[1], log_type); } if(ret == -1){ return -1; } } break; case BinlogCommand::QPOP_BACK: case BinlogCommand::QPOP_FRONT: { int ret; const Bytes name = log.key(); std::string tmp; if(log.cmd() == BinlogCommand::QPOP_BACK){ log_trace("qpop_back %s", hexmem(name.data(), name.size()).c_str()); ret = ssdb->qpop_back(name, &tmp, log_type); }else{ log_trace("qpop_front %s", hexmem(name.data(), name.size()).c_str()); ret = ssdb->qpop_front(name, &tmp, log_type); } if(ret == -1){ return -1; } } break; default: log_error("unknown binlog, type=%d, cmd=%d", log.type(), log.cmd()); break; } this->last_seq = log.seq(); if(log.type() == BinlogType::COPY){ this->last_key = log.key().String(); } this->save_status(); return 0; }