Spooky hash, smarter animqueue diffs
This commit is contained in:
@@ -19,24 +19,21 @@ IdGlobalPool::IdGlobalPool() {
|
||||
salvaged_.clear();
|
||||
next_batch_ = 0;
|
||||
next_id_ = 0;
|
||||
queue_fill_ = 10;
|
||||
}
|
||||
|
||||
IdGlobalPool::~IdGlobalPool() {
|
||||
}
|
||||
|
||||
void IdGlobalPool::init_master(int qf) {
|
||||
void IdGlobalPool::init_master() {
|
||||
salvaged_.clear();
|
||||
next_batch_ = 0x0001000000000000;
|
||||
next_id_ = 0x0010000000000000;
|
||||
queue_fill_ = qf;
|
||||
}
|
||||
|
||||
void IdGlobalPool::init_synch(int qf) {
|
||||
void IdGlobalPool::init_synch() {
|
||||
salvaged_.clear();
|
||||
next_batch_ = 0;
|
||||
next_id_ = 0x001E000000000000;
|
||||
queue_fill_ = qf;
|
||||
}
|
||||
|
||||
int64_t IdGlobalPool::get_one() {
|
||||
@@ -87,7 +84,6 @@ int64_t IdGlobalPool::alloc_id_for_thread(lua_State *L) {
|
||||
void IdGlobalPool::serialize(StreamBuffer *sb) {
|
||||
sb->write_int64(next_batch_);
|
||||
sb->write_int64(next_id_);
|
||||
sb->write_int32(queue_fill_);
|
||||
sb->write_size(salvaged_.size());
|
||||
for (int64_t batch : salvaged_) {
|
||||
sb->write_int64(batch);
|
||||
@@ -97,7 +93,6 @@ void IdGlobalPool::serialize(StreamBuffer *sb) {
|
||||
void IdGlobalPool::deserialize(StreamBuffer *sb) {
|
||||
next_batch_ = sb->read_int64();
|
||||
next_id_ = sb->read_int64();
|
||||
queue_fill_ = sb->read_int32();
|
||||
size_t salvaged_size = sb->read_size();
|
||||
salvaged_.resize(salvaged_size);
|
||||
for (int i=0; i < int(salvaged_size); i++) {
|
||||
@@ -107,19 +102,27 @@ void IdGlobalPool::deserialize(StreamBuffer *sb) {
|
||||
|
||||
IdPlayerPool::IdPlayerPool(IdGlobalPool *g) {
|
||||
global_ = g;
|
||||
fifo_enabled_ = false;
|
||||
fifo_capacity_ = 0;
|
||||
}
|
||||
|
||||
IdPlayerPool::~IdPlayerPool() {
|
||||
}
|
||||
|
||||
void IdPlayerPool::enable_fifo() {
|
||||
fifo_enabled_ = true;
|
||||
void IdPlayerPool::set_fifo_capacity(int n) {
|
||||
assert((n >= 0) && (n <= 250));
|
||||
fifo_capacity_ = n;
|
||||
while (int(ranges_.size()) > n) {
|
||||
global_->salvage(ranges_.back());
|
||||
ranges_.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void IdPlayerPool::disable_fifo() {
|
||||
unqueue();
|
||||
fifo_enabled_ = false;
|
||||
void IdPlayerPool::refill() {
|
||||
while (int(ranges_.size()) < fifo_capacity_) {
|
||||
int64_t batch = global_->get_batch();
|
||||
if (batch == 0) break;
|
||||
ranges_.push_back(batch);
|
||||
}
|
||||
}
|
||||
|
||||
void IdPlayerPool::test_push_back(int64_t range) {
|
||||
@@ -134,26 +137,8 @@ void IdPlayerPool::test_clear_ranges() {
|
||||
ranges_.clear();
|
||||
}
|
||||
|
||||
void IdPlayerPool::refill() {
|
||||
if (fifo_enabled_) {
|
||||
while (int(ranges_.size()) < global_->queue_fill()) {
|
||||
int64_t batch = global_->get_batch();
|
||||
if (batch == 0) break;
|
||||
ranges_.push_back(batch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IdPlayerPool::unqueue() {
|
||||
while (!ranges_.empty()) {
|
||||
global_->salvage(ranges_.front());
|
||||
ranges_.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
int64_t IdPlayerPool::get_batch() {
|
||||
int fill = fifo_enabled_ ? global_->queue_fill() : 0;
|
||||
while (int(ranges_.size()) < fill + 1) {
|
||||
while (int(ranges_.size()) < fifo_capacity_ + 1) {
|
||||
int64_t batch = global_->get_batch();
|
||||
if (batch == 0) break;
|
||||
ranges_.push_back(batch);
|
||||
@@ -177,24 +162,24 @@ void IdPlayerPool::prepare_thread(lua_State *L) {
|
||||
}
|
||||
|
||||
void IdPlayerPool::serialize(StreamBuffer *sb) {
|
||||
sb->write_bool(fifo_enabled_);
|
||||
sb->write_size(ranges_.size());
|
||||
sb->write_uint8(fifo_capacity_);
|
||||
sb->write_uint8(ranges_.size());
|
||||
for (int64_t batch : ranges_) {
|
||||
sb->write_int64(batch);
|
||||
}
|
||||
}
|
||||
|
||||
void IdPlayerPool::deserialize(StreamBuffer *sb) {
|
||||
fifo_enabled_ = sb->read_bool();
|
||||
size_t ranges_size = sb->read_size();
|
||||
fifo_capacity_ = sb->read_uint8();
|
||||
int ranges_size = sb->read_uint8();
|
||||
ranges_.resize(ranges_size);
|
||||
for (int i=0; i < int(ranges_size); i++) {
|
||||
for (int i=0; i < ranges_size; i++) {
|
||||
ranges_[i] = sb->read_int64();
|
||||
}
|
||||
}
|
||||
|
||||
bool IdPlayerPool::exactly_equal(const IdPlayerPool &other) const {
|
||||
if (fifo_enabled_ != other.fifo_enabled_) return false;
|
||||
if (fifo_capacity_ != other.fifo_capacity_) return false;
|
||||
if (ranges_.size() != other.ranges_.size()) return false;
|
||||
for (int i = 0; i < int(ranges_.size()); i++) {
|
||||
if (ranges_[i] != other.ranges_[i]) {
|
||||
@@ -205,32 +190,25 @@ bool IdPlayerPool::exactly_equal(const IdPlayerPool &other) const {
|
||||
}
|
||||
|
||||
bool IdPlayerPool::valid() const {
|
||||
if ((!fifo_enabled_) && (ranges_.size() > 0)) return false;
|
||||
if (ranges_.size() > 250) return false;
|
||||
if ((fifo_capacity_ < 0) || (fifo_capacity_ > 250)) return false;
|
||||
if (int(ranges_.size()) > fifo_capacity_) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IdPlayerPool::make_patch(const IdPlayerPool &auth, StreamBuffer *sb) const {
|
||||
assert(valid());
|
||||
assert(auth.valid());
|
||||
assert(global_->queue_fill() == auth.global_->queue_fill());
|
||||
|
||||
// The first byte.
|
||||
// 0 no differences
|
||||
// 1 fifo disabled and ranges empty
|
||||
// 2+ fifo enabled and N-2 ranges.
|
||||
//
|
||||
// The fifo capacity cannot be 255, so we use this as special
|
||||
// to indicate that no changes are present.
|
||||
if (exactly_equal(auth)) {
|
||||
sb->write_uint8(0);
|
||||
sb->write_uint8(255);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!auth.fifo_enabled_) {
|
||||
sb->write_uint8(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
sb->write_uint8(auth.ranges_.size() + 2);
|
||||
// Write the fifo capacity and nranges
|
||||
sb->write_uint8(auth.fifo_capacity_);
|
||||
sb->write_uint8(auth.ranges_.size());
|
||||
|
||||
// Build up an index of the known IDs.
|
||||
std::map<int64_t, int> index;
|
||||
@@ -238,7 +216,6 @@ bool IdPlayerPool::make_patch(const IdPlayerPool &auth, StreamBuffer *sb) const
|
||||
index[ranges_[i]] = i;
|
||||
}
|
||||
|
||||
|
||||
// Write the ranges, but encode known IDs in one byte.
|
||||
for (int i = 0; i < int(auth.ranges_.size()); i++) {
|
||||
int64_t n = auth.ranges_[i];
|
||||
@@ -256,20 +233,12 @@ bool IdPlayerPool::make_patch(const IdPlayerPool &auth, StreamBuffer *sb) const
|
||||
|
||||
void IdPlayerPool::apply_patch(StreamBuffer *sb) {
|
||||
// read the header byte
|
||||
int fifo_cap = sb->read_uint8();
|
||||
if (fifo_cap == 255) {
|
||||
return;
|
||||
}
|
||||
fifo_capacity_ = fifo_cap;
|
||||
int nranges = sb->read_uint8();
|
||||
if (nranges == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nranges == 1) {
|
||||
fifo_enabled_ = false;
|
||||
ranges_.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
fifo_enabled_ = true;
|
||||
nranges -= 2;
|
||||
|
||||
std::deque<int64_t> old = std::move(ranges_);
|
||||
ranges_.clear();
|
||||
for (int i = 0; i < nranges; i++) {
|
||||
@@ -291,26 +260,26 @@ LuaDefine(unittests_idalloc, "c") {
|
||||
StreamBuffer sb;
|
||||
|
||||
// Synchronous pools produce IDs starting at 0x001E000000000000
|
||||
gp.init_synch(3);
|
||||
gp.init_synch();
|
||||
LuaAssert(L, gp.get_one() == 0x001E000000000000);
|
||||
LuaAssert(L, gp.get_one() == 0x001E000000000001);
|
||||
LuaAssert(L, gp.get_one() == 0x001E000000000002);
|
||||
|
||||
// Master pools produce IDs starting at 0x0010000000000000
|
||||
gp.init_master(3);
|
||||
gp.init_master();
|
||||
LuaAssert(L, gp.get_one() == 0x0010000000000000);
|
||||
LuaAssert(L, gp.get_one() == 0x0010000000000001);
|
||||
LuaAssert(L, gp.get_one() == 0x0010000000000002);
|
||||
|
||||
// Synchronous pools produce only null batches.
|
||||
gp.init_synch(3);
|
||||
gp.init_synch();
|
||||
LuaAssert(L, gp.get_batch() == 0);
|
||||
LuaAssert(L, gp.get_batch() == 0);
|
||||
gp.salvage(nthbatch(5));
|
||||
LuaAssert(L, gp.get_batch() == 0);
|
||||
|
||||
// Simple fetch batches with a few salvages.
|
||||
gp.init_master(3);
|
||||
gp.init_master();
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(0));
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(1));
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(2));
|
||||
@@ -321,14 +290,14 @@ LuaDefine(unittests_idalloc, "c") {
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(3));
|
||||
|
||||
// Salvage of a zero-batch does nothing.
|
||||
gp.init_master(3);
|
||||
gp.init_master();
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(0));
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(1));
|
||||
gp.salvage(0);
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(2));
|
||||
|
||||
// Salvage of a partial batch.
|
||||
gp.init_master(3);
|
||||
gp.init_master();
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(0));
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(1));
|
||||
gp.salvage(nthbatch(142) + 10);
|
||||
@@ -336,7 +305,7 @@ LuaDefine(unittests_idalloc, "c") {
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(2));
|
||||
|
||||
// Salvage of a half-empty batch does nothing.
|
||||
gp.init_master(3);
|
||||
gp.init_master();
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(0));
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(1));
|
||||
gp.salvage(nthbatch(142) + 145);
|
||||
@@ -344,8 +313,8 @@ LuaDefine(unittests_idalloc, "c") {
|
||||
|
||||
// In the synchronous model, refill should do nothing.
|
||||
pp.test_clear_ranges();
|
||||
pp.enable_fifo();
|
||||
gp.init_synch(3);
|
||||
gp.init_synch();
|
||||
pp.set_fifo_capacity(3);
|
||||
pp.refill();
|
||||
LuaAssert(L, pp.size() == 0);
|
||||
LuaAssert(L, pp.get_batch() == 0);
|
||||
@@ -354,9 +323,9 @@ LuaDefine(unittests_idalloc, "c") {
|
||||
|
||||
// In the master model, with fifo disabled. Fifo should remain
|
||||
// empty, but batches should be returned.
|
||||
gp.init_master();
|
||||
pp.test_clear_ranges();
|
||||
pp.disable_fifo();
|
||||
gp.init_master(3);
|
||||
pp.set_fifo_capacity(0);
|
||||
pp.refill();
|
||||
LuaAssert(L, pp.size() == 0);
|
||||
LuaAssert(L, pp.get_batch() == nthbatch(0));
|
||||
@@ -364,9 +333,9 @@ LuaDefine(unittests_idalloc, "c") {
|
||||
LuaAssert(L, pp.get_batch() == nthbatch(1));
|
||||
|
||||
// Test refill from master (with enabled fifo).
|
||||
gp.init_master();
|
||||
pp.test_clear_ranges();
|
||||
pp.enable_fifo();
|
||||
gp.init_master(3);
|
||||
pp.set_fifo_capacity(3);
|
||||
pp.refill();
|
||||
LuaAssert(L, ranges_equal(pp.ranges_, nthbatch(0), nthbatch(1), nthbatch(2)));
|
||||
|
||||
@@ -377,16 +346,16 @@ LuaDefine(unittests_idalloc, "c") {
|
||||
// Test unqueueing the batches.
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(4));
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(5));
|
||||
pp.unqueue();
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(3));
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(2));
|
||||
pp.set_fifo_capacity(0);
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(1));
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(2));
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(3));
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(6));
|
||||
|
||||
// Try preparing a thread and salvaging a thread.
|
||||
gp.init_master();
|
||||
pp.test_clear_ranges();
|
||||
pp.enable_fifo();
|
||||
gp.init_master(3);
|
||||
pp.set_fifo_capacity(3);
|
||||
lua_setnextid(L, 0);
|
||||
pp.prepare_thread(L);
|
||||
LuaAssert(L, lua_getnextid(L) == nthbatch(0));
|
||||
@@ -400,8 +369,8 @@ LuaDefine(unittests_idalloc, "c") {
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(1));
|
||||
|
||||
// Allocate IDs from inside a thread.
|
||||
gp.init_master();
|
||||
lua_setnextid(L, 0xFD);
|
||||
gp.init_master(3);
|
||||
LuaAssert(L, gp.alloc_id_for_thread(L) == 0xFD);
|
||||
LuaAssert(L, gp.alloc_id_for_thread(L) == 0xFE);
|
||||
LuaAssert(L, gp.alloc_id_for_thread(L) == 0xFF);
|
||||
@@ -409,45 +378,42 @@ LuaDefine(unittests_idalloc, "c") {
|
||||
LuaAssert(L, lua_getnextid(L) == 0);
|
||||
|
||||
// Serialize and deserialize a global pool.
|
||||
gp.init_master(3);
|
||||
gpds.init_master(10);
|
||||
gp.init_master();
|
||||
gpds.init_master();
|
||||
LuaAssert(L, gp.get_one() == 0x0010000000000000);
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(0));
|
||||
gp.salvage(nthbatch(182));
|
||||
gp.salvage(nthbatch(183));
|
||||
gp.serialize(&sb);
|
||||
gpds.deserialize(&sb);
|
||||
LuaAssert(L, gpds.queue_fill() == 3);
|
||||
LuaAssert(L, gpds.get_one() == 0x0010000000000001);
|
||||
LuaAssert(L, gpds.get_batch() == nthbatch(183));
|
||||
LuaAssert(L, gpds.get_batch() == nthbatch(182));
|
||||
LuaAssert(L, gpds.get_batch() == nthbatch(1));
|
||||
|
||||
// Serialize and deserialize a player pool.
|
||||
gp.init_master(3);
|
||||
gpds.init_synch(5);
|
||||
gp.init_master();
|
||||
gpds.init_synch();
|
||||
LuaAssert(L, gp.get_batch() == nthbatch(0));
|
||||
pp.test_clear_ranges();
|
||||
pp.enable_fifo();
|
||||
pp.set_fifo_capacity(3);
|
||||
pp.refill();
|
||||
LuaAssert(L, pp.fifo_enabled());
|
||||
LuaAssert(L, pp.size() == 3);
|
||||
ppds.test_clear_ranges();
|
||||
pp.serialize(&sb);
|
||||
ppds.deserialize(&sb);
|
||||
LuaAssert(L, ppds.fifo_enabled());
|
||||
LuaAssert(L, ppds.get_fifo_capacity()==3);
|
||||
LuaAssert(L, ppds.size() == 3);
|
||||
LuaAssert(L, ppds.get_batch() == nthbatch(1));
|
||||
LuaAssert(L, ppds.get_batch() == nthbatch(2));
|
||||
LuaAssert(L, ppds.get_batch() == nthbatch(3));
|
||||
|
||||
// Difference transmit compare two empty pools.
|
||||
gp.init_master(3);
|
||||
gpds.init_master(3);
|
||||
gp.init_master();
|
||||
gpds.init_master();
|
||||
pp.test_clear_ranges();
|
||||
ppds.test_clear_ranges();
|
||||
pp.enable_fifo();
|
||||
ppds.enable_fifo();
|
||||
pp.set_fifo_capacity(3);
|
||||
ppds.set_fifo_capacity(3);
|
||||
|
||||
// Check case: no differences.
|
||||
sb.clear();
|
||||
|
||||
Reference in New Issue
Block a user