int SSDBImpl::qslice(const Bytes &name, int64_t begin, int64_t end, std::vector<std::string> *list) { int ret; uint64_t seq_begin, seq_end; if(begin >= 0 && end >= 0){ uint64_t tmp_seq; ret = qget_uint64(this->db, name, QFRONT_SEQ, &tmp_seq); if(ret != 1){ return ret; } seq_begin = tmp_seq + begin; seq_end = tmp_seq + end; }else if(begin < 0 && end < 0){ uint64_t tmp_seq; ret = qget_uint64(this->db, name, QBACK_SEQ, &tmp_seq); if(ret != 1){ return ret; } seq_begin = tmp_seq + begin + 1; seq_end = tmp_seq + end + 1; }else{ uint64_t f_seq, b_seq; ret = qget_uint64(this->db, name, QFRONT_SEQ, &f_seq); if(ret != 1){ return ret; } ret = qget_uint64(this->db, name, QBACK_SEQ, &b_seq); if(ret != 1){ return ret; } if(begin >= 0){ seq_begin = f_seq + begin; }else{ seq_begin = b_seq + begin + 1; } if(end >= 0){ seq_end = f_seq + end; }else{ seq_end = b_seq + end + 1; } } for(; seq_begin <= seq_end; seq_begin++){ std::string item; ret = qget_by_seq(this->db, name, seq_begin, &item); if(ret == -1){ return -1; } if(ret == 0){ return 0; } list->push_back(item); } return 0; }
int SSDBImpl::qset_by_seq(const Bytes &name, uint64_t seq, const Bytes &item, char log_type){ Transaction trans(binlogs); uint64_t min_seq, max_seq; int ret; int64_t size = this->qsize(name); if(size == -1){ return -1; } ret = qget_uint64(this->ldb, name, QFRONT_SEQ, &min_seq); if(ret == -1){ return -1; } max_seq = min_seq + size; if(seq < min_seq || seq > max_seq){ return 0; } ret = qset_one(this, name, seq, item); if(ret == -1){ return -1; } std::string buf = encode_qitem_key(name, seq); binlogs->add_log(log_type, BinlogCommand::QSET, buf); leveldb::Status s = binlogs->commit(); if(!s.ok()){ log_error("Write error!"); return -1; } return 1; }
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: index out of range, -1: error, 1: ok int SSDBImpl::qset(const Bytes &name, int64_t index, const Bytes &item, char log_type){ Transaction trans(binlogs); int64_t size = this->qsize(name); if(size == -1){ return -1; } if(index >= size || index < -size){ return 0; } int ret; uint64_t seq; if(index >= 0){ ret = qget_uint64(this->ldb, name, QFRONT_SEQ, &seq); seq += index; }else{ ret = qget_uint64(this->ldb, name, QBACK_SEQ, &seq); seq += index + 1; } if(ret == -1){ return -1; } if(ret == 0){ return 0; } ret = qset_one(this, name, seq, item); if(ret == -1){ return -1; } //log_info("qset %s %" PRIu64 "", hexmem(name.data(), name.size()).c_str(), seq); std::string buf = encode_qitem_key(name, seq); binlogs->add_log(log_type, BinlogCommand::QSET, buf); leveldb::Status s = binlogs->commit(); if(!s.ok()){ log_error("Write error!"); return -1; } return 1; }
int SSDBImpl::qget(const Bytes &name, int64_t index, std::string *item){ int ret; uint64_t seq; if(index >= 0){ ret = qget_uint64(this->ldb, name, QFRONT_SEQ, &seq); seq += index; }else{ ret = qget_uint64(this->ldb, name, QBACK_SEQ, &seq); seq += index + 1; } if(ret == -1){ return -1; } if(ret == 0){ return 0; } ret = qget_by_seq(this->ldb, name, seq, item); return ret; }
// @return 0: empty queue, 1: item peeked, -1: error int SSDB::qfront(const Bytes &name, std::string *item){ int ret = 0; uint64_t seq; ret = qget_uint64(this->db, name, QFRONT_SEQ, &seq); if(ret == -1){ return -1; } if(ret == 0){ return 0; } ret = qget(this->db, name, seq, item); return ret; }
// @return 0: empty queue, 1: item peeked, -1: error int SSDBImpl::qback(const Bytes &name, std::string *item){ int ret = 0; uint64_t seq; ret = qget_uint64(this->ldb, name, QBACK_SEQ, &seq); if(ret == -1){ return -1; } if(ret == 0){ return 0; } ret = qget_by_seq(this->ldb, name, seq, item); return ret; }
// @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; }