Check in code for new random number generator

This commit is contained in:
2022-03-31 17:15:15 -04:00
parent 7fc6263e37
commit c48e02642a
9 changed files with 291 additions and 8 deletions

View File

@@ -37,11 +37,21 @@
//
// THE NUMERIC RANGES
//
// * 0x0000+ : reserved for manually-created tangible IDs.
// The largest integer that can be stored losslessly in a lua_Number is:
//
// * 0x0020000000000000
//
// In other words, any 53-bit number can be stored. We subdivide the range as
// follows:
//
// * 0x0000+ : manually created IDs.
// * 0x0001+ : used by master model's IdGlobalPool to create batches.
// * 0x0010+ : used by master model's IdGlobalPool to create individual IDs.
// * 0x001E+ : used by sync model's IdGlobalPool to create individual IDs.
//
// If you exhaust the Master Model's invididual pool at a rate of 10,000,000 IDs
// per second, the individual pool will last for 12 years.
//
// BATCH REPRESENTATION
//
// A batch is represented as a 64-bit integer. The batch contains all IDs
@@ -60,6 +70,22 @@
//
// As a special case, the number 0 is used to indicate "invalid batch".
//
// SEQUENCE NUMBERS
//
// If you allocate IDs from a player pool rapidly, you will exhaust the fifo in
// the player pool. As a result, ID allocation will fall back to the global
// pool, which will cause prediction failures.
//
// Depending on your requirements, you may be able to use sequence numbers
// instead of IDs. The player pool contains a monotonically increasing counter
// for generating sequence numbers. These can be allocated extremely fast
// and they'll never run out. These are highly predictable as long as the
// only person fetching sequence numbers is the player himself. The downside
// is that sequence numbers are not globally unique - they're only locally
// unique for a single player. That may be enough for your requirements.
//
// Currently, sequence numbers are used by the random number generator.
//
///////////////////////////////////////////////////////////////////
#ifndef IDALLOC_HPP
@@ -105,6 +131,10 @@ public:
// zero, or the batch contains fewer than 128 IDs.
void salvage(int64_t batch);
// Get a global sequence number. These are not the same as IDs.
// Sequence numbers are unlikely to be predicted correctly.
int64_t get_seqno() { return next_seqno_++; }
// Serialize to or deserialize from a streambuffer.
void serialize(StreamBuffer *sb) const;
void deserialize(StreamBuffer *sb);
@@ -116,6 +146,7 @@ private:
eng::vector<int64_t> salvaged_;
int64_t next_batch_;
int64_t next_id_;
int64_t next_seqno_;
friend int unittests_idalloc(lua_State *L);
};
@@ -143,6 +174,10 @@ public:
// Get a single ID from the fifo. Also refills the fifo.
int64_t get_one();
// Get a player sequence number. This is not the same as an ID: player
// sequence numbers are unique per player, but not globally.
int64_t get_seqno() { return next_seqno_++; }
// Return the size of the queue.
int size() { return ranges_.size(); }
@@ -177,6 +212,7 @@ public:
private:
IdGlobalPool *global_;
int fifo_capacity_;
int64_t next_seqno_;
eng::deque<int64_t> ranges_;
friend int lfn_unittests_idalloc(lua_State *L);
};