mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-03 16:03:52 +00:00
Optimize update-object field mask parsing
This commit is contained in:
parent
3a9bd0d4e5
commit
37888c666d
1 changed files with 23 additions and 15 deletions
|
|
@ -1088,8 +1088,9 @@ bool UpdateObjectParser::parseUpdateFields(network::Packet& packet, UpdateBlock&
|
||||||
LOG_DEBUG(" maskBlockCount = ", (int)blockCount);
|
LOG_DEBUG(" maskBlockCount = ", (int)blockCount);
|
||||||
LOG_DEBUG(" fieldsCapacity (blocks * 32) = ", fieldsCapacity);
|
LOG_DEBUG(" fieldsCapacity (blocks * 32) = ", fieldsCapacity);
|
||||||
|
|
||||||
// Read update mask
|
// Read update mask into a reused scratch buffer to avoid per-block allocations.
|
||||||
std::vector<uint32_t> updateMask(blockCount);
|
static thread_local std::vector<uint32_t> updateMask;
|
||||||
|
updateMask.resize(blockCount);
|
||||||
for (int i = 0; i < blockCount; ++i) {
|
for (int i = 0; i < blockCount; ++i) {
|
||||||
updateMask[i] = packet.readUInt32();
|
updateMask[i] = packet.readUInt32();
|
||||||
}
|
}
|
||||||
|
|
@ -1098,13 +1099,20 @@ bool UpdateObjectParser::parseUpdateFields(network::Packet& packet, UpdateBlock&
|
||||||
uint16_t highestSetBit = 0;
|
uint16_t highestSetBit = 0;
|
||||||
uint32_t valuesReadCount = 0;
|
uint32_t valuesReadCount = 0;
|
||||||
|
|
||||||
// Read field values for each bit set in mask
|
// Read only set bits in each mask block (faster than scanning all 32 bits).
|
||||||
for (int blockIdx = 0; blockIdx < blockCount; ++blockIdx) {
|
for (int blockIdx = 0; blockIdx < blockCount; ++blockIdx) {
|
||||||
uint32_t mask = updateMask[blockIdx];
|
uint32_t mask = updateMask[blockIdx];
|
||||||
|
while (mask != 0) {
|
||||||
for (int bit = 0; bit < 32; ++bit) {
|
const uint16_t fieldIndex =
|
||||||
if (mask & (1 << bit)) {
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
uint16_t fieldIndex = blockIdx * 32 + bit;
|
static_cast<uint16_t>(blockIdx * 32 + __builtin_ctz(mask));
|
||||||
|
#else
|
||||||
|
static_cast<uint16_t>(blockIdx * 32 + [] (uint32_t v) -> uint16_t {
|
||||||
|
uint16_t b = 0;
|
||||||
|
while ((v & 1u) == 0u) { v >>= 1u; ++b; }
|
||||||
|
return b;
|
||||||
|
}(mask));
|
||||||
|
#endif
|
||||||
if (fieldIndex > highestSetBit) {
|
if (fieldIndex > highestSetBit) {
|
||||||
highestSetBit = fieldIndex;
|
highestSetBit = fieldIndex;
|
||||||
}
|
}
|
||||||
|
|
@ -1113,7 +1121,7 @@ bool UpdateObjectParser::parseUpdateFields(network::Packet& packet, UpdateBlock&
|
||||||
valuesReadCount++;
|
valuesReadCount++;
|
||||||
|
|
||||||
LOG_DEBUG(" Field[", fieldIndex, "] = 0x", std::hex, value, std::dec);
|
LOG_DEBUG(" Field[", fieldIndex, "] = 0x", std::hex, value, std::dec);
|
||||||
}
|
mask &= (mask - 1u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue