mirror of
https://github.com/neoStudiosLCE/neoLegacy.git
synced 2026-06-09 00:22:57 +00:00
attempt at making it faster
This commit is contained in:
parent
2830b973d4
commit
32a68ed3ae
|
|
@ -93,8 +93,8 @@ MultiPlayerChunkCache::MultiPlayerChunkCache(Level *level)
|
|||
|
||||
this->level = level;
|
||||
|
||||
//this->cache = new LevelChunk *[XZSIZE * XZSIZE];
|
||||
//memset(this->cache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk *));
|
||||
this->cache = new LevelChunk *[XZSIZE * XZSIZE];
|
||||
memset(this->cache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk *));
|
||||
InitializeCriticalSectionAndSpinCount(&m_csLoadCreate,4000);
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +102,7 @@ MultiPlayerChunkCache::~MultiPlayerChunkCache()
|
|||
{
|
||||
delete emptyChunk;
|
||||
delete waterChunk;
|
||||
dynamic_cache.clear(); //delete cache;
|
||||
delete cache;
|
||||
delete hasData;
|
||||
|
||||
for (auto& it : loadedChunkList)
|
||||
|
|
@ -130,10 +130,12 @@ bool MultiPlayerChunkCache::reallyHasChunk(int x, int z)
|
|||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return true;
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return true;
|
||||
int idx = ix * XZSIZE + iz;
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
|
||||
if (itor == dynamic_cache.end() || itor->second == nullptr) return false;
|
||||
|
||||
LevelChunk *chunk = cache[idx];
|
||||
if( chunk == nullptr )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return hasData[idx];
|
||||
}
|
||||
|
||||
|
|
@ -144,18 +146,19 @@ void MultiPlayerChunkCache::drop(const int x, const int z)
|
|||
if ((ix < 0) || (ix >= XZSIZE)) return;
|
||||
if ((iz < 0) || (iz >= XZSIZE)) return;
|
||||
const int idx = ix * XZSIZE + iz;
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
|
||||
if (itor == dynamic_cache.end() || itor->second == nullptr || itor->second->isEmpty()) return;
|
||||
LevelChunk* chunk = cache[idx];
|
||||
|
||||
// Drop entities in the chunks, especially for the case when a player is dead
|
||||
// as they will not get the RemoveEntity packet if an entity is removed.
|
||||
// Don't delete tile entities, as they won't get recreated unless they've got
|
||||
// update packets. Tile entities are created on the client by the chunk rebuild.
|
||||
itor->second->unload(false);
|
||||
if (chunk != nullptr && !chunk->isEmpty())
|
||||
{
|
||||
// Drop entities in the chunks, especially for the case when a player is dead
|
||||
// as they will not get the RemoveEntity packet if an entity is removed.
|
||||
// Don't delete tile entities, as they won't get recreated unless they've got
|
||||
// update packets. Tile entities are created on the client by the chunk rebuild.
|
||||
chunk->unload(false);
|
||||
|
||||
// Keep chunk in cache with structural data intact.
|
||||
itor->second->loaded = true;
|
||||
// Keep chunk in cache with structural data intact.
|
||||
chunk->loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
LevelChunk *MultiPlayerChunkCache::create(int x, int z)
|
||||
|
|
@ -166,16 +169,11 @@ LevelChunk *MultiPlayerChunkCache::create(int x, int z)
|
|||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
|
||||
int idx = ix * XZSIZE + iz;
|
||||
LevelChunk* chunk = nullptr;
|
||||
LevelChunk* lastChunk = nullptr;
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
LevelChunk *chunk = cache[idx];
|
||||
LevelChunk *lastChunk = chunk;
|
||||
|
||||
if (itor != dynamic_cache.end()) {
|
||||
chunk = itor->second;
|
||||
lastChunk = chunk;
|
||||
}
|
||||
|
||||
if (chunk == nullptr) {
|
||||
if( chunk == nullptr )
|
||||
{
|
||||
EnterCriticalSection(&m_csLoadCreate);
|
||||
|
||||
//LevelChunk *chunk;
|
||||
|
|
@ -212,9 +210,9 @@ LevelChunk *MultiPlayerChunkCache::create(int x, int z)
|
|||
LeaveCriticalSection(&m_csLoadCreate);
|
||||
|
||||
#if ( defined _WIN64 || defined __LP64__ )
|
||||
if( InterlockedCompareExchangeRelease64((LONG64 *)&dynamic_cache[idx],(LONG64)chunk,(LONG64)lastChunk) == (LONG64)lastChunk )
|
||||
if( InterlockedCompareExchangeRelease64((LONG64 *)&cache[idx],(LONG64)chunk,(LONG64)lastChunk) == (LONG64)lastChunk )
|
||||
#else
|
||||
if( InterlockedCompareExchangeRelease((LONG *)&dynamic_cache[idx],(LONG)chunk,(LONG)lastChunk) == (LONG)lastChunk )
|
||||
if( InterlockedCompareExchangeRelease((LONG *)&cache[idx],(LONG)chunk,(LONG)lastChunk) == (LONG)lastChunk )
|
||||
#endif // _DURANGO
|
||||
{
|
||||
// If we're sharing with the server, we'll need to calculate our heightmap now, which isn't shared. If we aren't sharing with the server,
|
||||
|
|
@ -234,11 +232,7 @@ LevelChunk *MultiPlayerChunkCache::create(int x, int z)
|
|||
// Something else must have updated the cache. Return that chunk and discard this one. This really shouldn't be happening
|
||||
// in multiplayer
|
||||
delete chunk;
|
||||
|
||||
itor = dynamic_cache.find(idx);
|
||||
if (itor == dynamic_cache.end()) return nullptr;
|
||||
|
||||
return itor->second;
|
||||
return cache[idx];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -258,11 +252,16 @@ LevelChunk *MultiPlayerChunkCache::getChunk(int x, int z)
|
|||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
|
||||
int idx = ix * XZSIZE + iz;
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
|
||||
if (itor == dynamic_cache.end() || itor->second == nullptr) return emptyChunk;
|
||||
|
||||
return itor->second;
|
||||
LevelChunk *chunk = cache[idx];
|
||||
if( chunk == nullptr )
|
||||
{
|
||||
return emptyChunk;
|
||||
}
|
||||
else
|
||||
{
|
||||
return chunk;
|
||||
}
|
||||
}
|
||||
|
||||
bool MultiPlayerChunkCache::save(bool force, ProgressListener *progressListener)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ private:
|
|||
|
||||
vector<LevelChunk *> loadedChunkList;
|
||||
|
||||
//LevelChunk **cache;
|
||||
LevelChunk **cache;
|
||||
// 4J - added for multithreaded support
|
||||
CRITICAL_SECTION m_csLoadCreate;
|
||||
// 4J - size of cache is defined by size of one side - must be even
|
||||
|
|
@ -44,5 +44,5 @@ public:
|
|||
virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ);
|
||||
virtual void dataReceived(int x, int z); // 4J added
|
||||
|
||||
virtual std::unordered_map<uint64_t, LevelChunk*>& getCache() { return dynamic_cache; } // 4J added
|
||||
virtual std::unordered_map<uint64_t, LevelChunk*, ChunkKeyHash>& getCache() { return dynamic_cache; } // 4J added
|
||||
};
|
||||
|
|
@ -33,7 +33,7 @@ MultiPlayerLevel::MultiPlayerLevel(ClientConnection *connection, LevelSettings *
|
|||
// 4J - this this used to be called in parent ctor via a virtual fn
|
||||
chunkSource = createChunkSource();
|
||||
// 4J - optimisation - keep direct reference of underlying cache here
|
||||
dynamic_chunkSourceCache = chunkSource->getCache();
|
||||
//dynamic_chunkSourceCache = chunkSource->getCache();
|
||||
chunkSourceXZSize = chunkSource->m_XZSize;
|
||||
|
||||
// This also used to be called in parent ctor, but can't be called until chunkSource is created. Call now if required.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ private:
|
|||
#ifdef _LARGE_WORLDS
|
||||
deque<LevelChunk *> m_toDrop;
|
||||
//LevelChunk **m_unloadedCache;
|
||||
std::unordered_map<uint64_t, LevelChunk*> dynamic_unloadedCache;
|
||||
std::unordered_map<uint64_t, LevelChunk*, ChunkKeyHash> dynamic_unloadedCache;
|
||||
#endif
|
||||
|
||||
// 4J - added for multithreaded support
|
||||
|
|
@ -53,7 +53,7 @@ public:
|
|||
void updateOverwriteHellChunk(LevelChunk* origChunk, LevelChunk* playerChunk, int xMin, int xMax, int zMin, int zMax);
|
||||
|
||||
#endif
|
||||
virtual std::unordered_map<uint64_t, LevelChunk*>& getCache() { return dynamic_cache; } // 4J added
|
||||
virtual std::unordered_map<uint64_t, LevelChunk*, ChunkKeyHash>& getCache() { return dynamic_cache; } // 4J added
|
||||
#ifdef MINECRAFT_SERVER_BUILD
|
||||
void regenerateChunk(int x, int z);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -48,6 +48,13 @@ class TilePos;
|
|||
#define END_LEVEL_MIN_WIDTH 18
|
||||
//#define END_LEVEL_MAX_WIDTH (LEVEL_MAX_WIDTH / END_LEVEL_SCALE)
|
||||
|
||||
class ChunkKeyHash {
|
||||
public:
|
||||
std::size_t operator()(const uint64_t& k) const noexcept {
|
||||
return (std::size_t)k;
|
||||
}
|
||||
};
|
||||
|
||||
class ChunkSource
|
||||
{
|
||||
public:
|
||||
|
|
@ -60,7 +67,7 @@ public:
|
|||
#endif
|
||||
|
||||
protected:
|
||||
std::unordered_map<uint64_t, LevelChunk*> dynamic_cache;
|
||||
std::unordered_map<uint64_t, LevelChunk*, ChunkKeyHash> dynamic_cache;
|
||||
|
||||
public:
|
||||
virtual ~ChunkSource() {}
|
||||
|
|
@ -76,7 +83,7 @@ public:
|
|||
virtual bool tick() = 0;
|
||||
virtual bool shouldSave() = 0;
|
||||
|
||||
virtual std::unordered_map<uint64_t, LevelChunk*>& getCache() { return dynamic_cache; } // 4J added
|
||||
virtual std::unordered_map<uint64_t, LevelChunk*, ChunkKeyHash>& getCache() { return dynamic_cache; } // 4J added
|
||||
virtual void dataReceived(int x, int z) {} // 4J added
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -524,7 +524,7 @@ public:
|
|||
int getAuxValueForMap(PlayerUID xuid, int dimension, int centreXC, int centreZC, int scale);
|
||||
|
||||
// 4J - optimisation - keep direct reference of underlying cache here
|
||||
std::unordered_map<uint64_t, LevelChunk*> dynamic_chunkSourceCache;
|
||||
std::unordered_map<uint64_t, LevelChunk*, ChunkKeyHash> dynamic_chunkSourceCache;
|
||||
int chunkSourceXZSize;
|
||||
|
||||
// 4J - added for implementation of finite limit to number of item entities, tnt and falling block entities
|
||||
|
|
|
|||
Loading…
Reference in a new issue