From 0d66bdd27002f85f7ea9b34240b63eae37be1a58 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 00:48:43 +1100 Subject: [PATCH] batch land sql queries to 1 per ward instead of 60 --- src/common/Database/ZoneDbConnection.cpp | 4 ++ src/common/Database/ZoneDbConnection.h | 1 + src/world/Territory/HousingZone.cpp | 56 +++++++++++++++++------- src/world/Territory/HousingZone.h | 11 +++++ src/world/Territory/Land.cpp | 30 ++++--------- src/world/Territory/Land.h | 2 +- 6 files changed, 66 insertions(+), 38 deletions(-) diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index 7e3b4e4f..b35ecf79 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -208,6 +208,10 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements() "SELECT LandIdent, ContainerId, ItemId, SlotId FROM houseiteminventory WHERE LandIdent = ?", CONNECTION_SYNC ); + prepareStatement( LANDSET_SEL, + "SELECT * FROM land WHERE LandSetId = ?;", + CONNECTION_SYNC ); + /*prepareStatement( LAND_INS, "INSERT INTO land ( LandSetId ) VALUES ( ? );", CONNECTION_BOTH ); diff --git a/src/common/Database/ZoneDbConnection.h b/src/common/Database/ZoneDbConnection.h index 6f404167..2cbfac6e 100644 --- a/src/common/Database/ZoneDbConnection.h +++ b/src/common/Database/ZoneDbConnection.h @@ -81,6 +81,7 @@ namespace Sapphire::Db LAND_INS, LAND_SEL, LAND_UP, + LANDSET_SEL, HOUSING_HOUSE_INS, HOUSING_HOUSE_UP, HOUSING_HOUSE_DEL, diff --git a/src/world/Territory/HousingZone.cpp b/src/world/Territory/HousingZone.cpp index 5f47d22f..17fdfd3b 100644 --- a/src/world/Territory/HousingZone.cpp +++ b/src/world/Territory/HousingZone.cpp @@ -42,12 +42,15 @@ bool Sapphire::HousingZone::init() { auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); - auto res = pDb->query( "SELECT * FROM landset WHERE landsetid = " + std::to_string( m_landSetId ) ); - if( !res->next() ) { - pDb->directExecute( "INSERT INTO landset ( landsetid ) VALUES ( " + std::to_string( m_landSetId ) + " );" ); + auto res = pDb->query( "SELECT * FROM landset WHERE landsetid = " + std::to_string( m_landSetId ) ); + if( !res->next() ) + { + pDb->directExecute( "INSERT INTO landset ( landsetid ) VALUES ( " + std::to_string( m_landSetId ) + " );" ); + } } + int housingIndex; if( m_territoryTypeId == 339 ) housingIndex = 0; @@ -61,25 +64,46 @@ bool Sapphire::HousingZone::init() auto pExdData = g_fw.get< Data::ExdDataGenerated >(); auto info = pExdData->get< Sapphire::Data::HousingLandSet >( housingIndex ); - uint32_t landId; - for( landId = 0; landId < 60; landId++ ) - { - auto pLand = make_Land( m_territoryTypeId, getWardNum(), landId, m_landSetId, info ); - m_landPtrMap[ landId ] = pLand; + auto stmt = pDb->getPreparedStatement( Db::LANDSET_SEL ); + stmt->setUInt64( 1, m_landSetId ); + auto res = pDb->query( stmt ); - if( auto house = pLand->getHouse() ) - { - registerHouseEntranceEObj( landId << 8 ); - } + std::vector< QueuedLandInit > landInit; + + while( res->next() ) + { + + QueuedLandInit init; + init.m_landId = res->getUInt64( "LandId" ); + init.m_type = static_cast< Common::LandType >( res->getUInt( "Type" ) ); + init.m_size = res->getUInt( "Size" ); + init.m_status = res->getUInt( "Status" ); + init.m_currentPrice = res->getUInt( "LandPrice" ); + init.m_ownerId = res->getUInt64( "OwnerId" ); + init.m_houseId = res->getUInt64( "HouseId" ); + + landInit.push_back( init ); + } + + // nuke current query connection so the queries still in land don't fail + res.reset(); + + // spawn land + for( auto& init : landInit ) + { + auto land = make_Land( m_territoryTypeId, getWardNum(), init.m_landId, m_landSetId, info ); + land->init( init.m_type, init.m_size, init.m_status, init.m_currentPrice, init.m_ownerId, init.m_houseId ); + + m_landPtrMap[ init.m_landId ] = land; + + if( init.m_houseId > 0 ) + registerHouseEntranceEObj( init.m_landId ); } return true; } -Sapphire::HousingZone::~HousingZone() -{ - -} +Sapphire::HousingZone::~HousingZone() = default; void Sapphire::HousingZone::onPlayerZoneIn( Entity::Player& player ) { diff --git a/src/world/Territory/HousingZone.h b/src/world/Territory/HousingZone.h index 3868f31a..63fcfb4b 100644 --- a/src/world/Territory/HousingZone.h +++ b/src/world/Territory/HousingZone.h @@ -53,6 +53,17 @@ namespace Sapphire Entity::EventObjectPtr registerHouseEntranceEObj( uint8_t plotId ); private: + struct QueuedLandInit + { + uint64_t m_landId; + Common::LandType m_type; + uint8_t m_size; + uint8_t m_status; + uint32_t m_currentPrice; + uint64_t m_ownerId; + uint64_t m_houseId; + }; + using LandPtrMap = std::unordered_map< uint8_t, Sapphire::LandPtr >; const uint32_t m_landSetMax = 18; LandPtrMap m_landPtrMap; diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index ce2eca89..a9e3781c 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -48,32 +48,20 @@ Sapphire::Land::Land( uint16_t territoryTypeId, uint8_t wardNum, uint8_t landId, m_landIdent.wardNum = wardNum; m_landIdent.worldId = 67; // todo: fix this - init(); + m_minPrice = m_landInfo->minPrice[ m_landIdent.landId ]; + m_maxPrice = m_landInfo->initialPrice[ m_landIdent.landId ]; } Sapphire::Land::~Land() = default; -void Sapphire::Land::init() +void Sapphire::Land::init( Common::LandType type, uint8_t size, uint8_t state, uint32_t currentPrice, uint64_t ownerId, uint64_t houseId ) { - // todo: move this loading logic outside of land and fetch all houses in 1 query - auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); - auto res = pDb->query( "SELECT * FROM land WHERE LandSetId = " + std::to_string( m_landSetId ) + " " - "AND LandId = " + std::to_string( m_landIdent.landId ) ); - // we're not going to be building the land table at runtime - assert( res->next() ); - - m_type = static_cast< Common::LandType >( res->getUInt( "Type" ) ); - m_size = res->getUInt( "Size" ); - m_state = res->getUInt( "Status" ); - m_currentPrice = res->getUInt( "LandPrice" ); - m_ownerId = res->getUInt64( "OwnerId" ); - m_minPrice = m_landInfo->minPrice[ m_landIdent.landId ]; - m_maxPrice = m_landInfo->initialPrice[ m_landIdent.landId ]; - - auto houseId = res->getUInt( "HouseId" ); - - res.reset(); + m_type = type; + m_size = size; + m_state = state; + m_currentPrice = currentPrice; + m_ownerId = ownerId; // fetch the house if we have one for this land if( houseId > 0 ) @@ -123,7 +111,7 @@ void Sapphire::Land::init() setupContainer( InventoryType::HousingInteriorPlacedItems1, m_maxPlacedInternalItems ); setupContainer( InventoryType::HousingInteriorStoreroom1, m_maxPlacedInternalItems ); - loadItemContainerContents(); +// loadItemContainerContents(); } void Sapphire::Land::loadItemContainerContents() diff --git a/src/world/Territory/Land.h b/src/world/Territory/Land.h index 3e5b7ae0..bf8a834c 100644 --- a/src/world/Territory/Land.h +++ b/src/world/Territory/Land.h @@ -17,6 +17,7 @@ namespace Sapphire Land( uint16_t zoneId, uint8_t wardNum, uint8_t landId, uint32_t landSetId, Sapphire::Data::HousingLandSetPtr info ); virtual ~Land(); + void init( Common::LandType type, uint8_t size, uint8_t state, uint32_t currentPrice, uint64_t ownerId, uint64_t houseId ); using LandInventoryMap = std::unordered_map< uint16_t, ItemContainerPtr >; @@ -64,7 +65,6 @@ namespace Sapphire private: uint32_t convertItemIdToHousingItemId( uint32_t itemId ); - void init(); uint32_t getNextHouseId(); Common::LandIdent m_landIdent;