Example #1
0
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;
}
Example #2
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
// 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;
}
Example #6
0
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;
}
Example #7
0
File: t_queue.cpp Project: 29n/ssdb
// @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;
}
Example #8
0
// @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;
}
Example #9
0
File: t_queue.cpp Project: 29n/ssdb
// @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;
}
Example #10
0
File: t_queue.cpp Project: 29n/ssdb
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;
}