int SSDBImpl::_qpop(const Bytes &name, std::string *item, uint64_t front_or_back_seq, char log_type){ Transaction trans(binlogs); int ret; uint64_t seq; ret = qget_uint64(this->ldb, name, front_or_back_seq, &seq); if(ret == -1){ return -1; } if(ret == 0){ return 0; } ret = qget_by_seq(this->ldb, name, seq, item); if(ret == -1){ return -1; } if(ret == 0){ return 0; } // delete item ret = qdel_one(this, name, seq); if(ret == -1){ return -1; } if(front_or_back_seq == QFRONT_SEQ){ binlogs->add_log(log_type, BinlogCommand::QPOP_FRONT, name.String()); }else{ binlogs->add_log(log_type, BinlogCommand::QPOP_BACK, name.String()); } // update size int64_t size = incr_qsize(this, name, -1); if(size == -1){ return -1; } // update front if(size > 0){ seq += (front_or_back_seq == QFRONT_SEQ)? +1 : -1; //log_debug("seq: %" PRIu64 ", ret: %d", seq, ret); ret = qset_one(this, name, front_or_back_seq, Bytes(&seq, sizeof(seq))); if(ret == -1){ return -1; } } leveldb::Status s = binlogs->commit(); if(!s.ok()){ log_error("Write error! %s", s.ToString().c_str()); return -1; } return 1; }
int64_t SSDBImpl::_qpush(const Bytes &name, const Bytes &item, uint64_t front_or_back_seq, char log_type){ Transaction trans(binlogs); int ret; // generate seq uint64_t seq; ret = qget_uint64(this->ldb, name, front_or_back_seq, &seq); if(ret == -1){ return -1; } // update front and/or back if(ret == 0){ seq = QITEM_SEQ_INIT; ret = qset_one(this, name, QFRONT_SEQ, Bytes(&seq, sizeof(seq))); if(ret == -1){ return -1; } ret = qset_one(this, name, QBACK_SEQ, Bytes(&seq, sizeof(seq))); }else{ seq += (front_or_back_seq == QFRONT_SEQ)? -1 : +1; ret = qset_one(this, name, front_or_back_seq, Bytes(&seq, sizeof(seq))); } if(ret == -1){ return -1; } if(seq <= QITEM_MIN_SEQ || seq >= QITEM_MAX_SEQ){ log_info("queue is full, seq: %" PRIu64 " out of range", seq); return -1; } // prepend/append item ret = qset_one(this, name, seq, item); if(ret == -1){ return -1; } std::string buf = encode_qitem_key(name, seq); if(front_or_back_seq == QFRONT_SEQ){ binlogs->add_log(log_type, BinlogCommand::QPUSH_FRONT, buf); }else{ binlogs->add_log(log_type, BinlogCommand::QPUSH_BACK, buf); } // update size int64_t size = incr_qsize(this, name, +1); if(size == -1){ return -1; } leveldb::Status s = binlogs->commit(); if(!s.ok()){ log_error("Write error! %s", s.ToString().c_str()); return -1; } return size; }
// @return 0: empty queue, 1: item popped, -1: error int SSDB::qpop(const Bytes &name, std::string *item){ Transaction trans(binlogs); int ret; uint64_t seq; ret = qget_uint64(this->db, name, QFRONT_SEQ, &seq); if(ret == -1){ return -1; } if(ret == 0){ seq = QITEM_MIN_SEQ; } ret = qget(this->db, name, seq, item); if(ret == -1){ return -1; } if(ret == 0){ return 0; } // delete item ret = qdel_one(this, name, seq); if(ret == -1){ return -1; } // update size int64_t size = incr_qsize(this, name, -1); if(size == -1){ return -1; } // update front if(size > 0){ seq += 1; //log_debug("seq: %" PRIu64 ", ret: %d", seq, ret); ret = qset_one(this, name, QFRONT_SEQ, Bytes(&seq, sizeof(seq))); if(ret == -1){ return -1; } } leveldb::Status s = binlogs->commit(); if(!s.ok()){ log_error("Write error!"); return -1; } return 1; }
int SSDB::qpush(const Bytes &name, const Bytes &item){ Transaction trans(binlogs); int ret; // generate seq uint64_t seq; ret = qget_uint64(this->db, name, QBACK_SEQ, &seq); if(ret == -1){ return -1; } if(ret == 0){ seq = QITEM_MIN_SEQ; }else{ seq += 1; } // append item ret = qset_one(this, name, seq, item); if(ret == -1){ return -1; } // update size int64_t size = incr_qsize(this, name, +1); if(size == -1){ return -1; } // update back ret = qset_one(this, name, QBACK_SEQ, Bytes(&seq, sizeof(seq))); if(ret == -1){ return -1; } leveldb::Status s = binlogs->commit(); if(!s.ok()){ log_error("Write error!"); return -1; } return 1; }