refactor: s1_vdata sometimes didn't get cached

#313
This commit is contained in:
Martin Ambrus
2017-11-20 14:11:45 +01:00
parent 4a7ab1f81a
commit a4ce48ca38
3 changed files with 147 additions and 14 deletions
+52 -6
View File
@@ -249,8 +249,7 @@ class Automation {
fclose($ourFileHandle);
global $database;
$array = array();
$q = "SELECT wref, loyalty, lastupdate2 FROM ".TB_PREFIX."vdata WHERE loyalty < 100";
$array = $database->query_return($q);
$array = $database->getProfileVillages(0, 6);
if(!empty($array)) {
foreach($array as $loyalty) {
if (($t25_level = $this->getTypeLevel(25, $loyalty['wref'])) >= 1) {
@@ -613,7 +612,14 @@ class Automation {
timestamp < $time and master = 0"
);
// complete each of them
// preload village data
$vilIDs = [];
foreach($res as $indi) {
$vilIDs[$indi['wid']] = true;
}
$database->getProfileVillages(array_keys($vilIDs), 5);
// complete buildings
foreach($res as $indi) {
// store village ID for later for statistical updates
$villageData = $database->getVillageFields($indi['wid'],'owner, maxcrop, maxstore, starv, pop');
@@ -1207,6 +1213,15 @@ class Automation {
$data_num = 0;
if ($dataarray && count($dataarray)) {
// preload village data
$vilIDs = [];
foreach($dataarray as $data) {
$vilIDs[$data['from']] = true;
$vilIDs[$data['to']] = true;
}
$database->getProfileVillages(array_keys($vilIDs), 5);
// calculate battles
foreach($dataarray as $data) {
//set base things
$isoasis = $data['oasistype'];
@@ -3355,9 +3370,16 @@ class Automation {
$dataarray = $database->query_return($q);
if ($dataarray && count($dataarray)) {
// preload village data
$vilIDs = [];
foreach($dataarray as $data) {
$vilIDs[$data['from']] = true;
$vilIDs[$data['to']] = true;
}
$database->getProfileVillages(array_keys($vilIDs), 5);
// calculate reinforcements data
$movementProcIDs = [];
foreach($dataarray as $data) {
$isoasis = $database->isVillageOases($data['to']);
if($isoasis == 0){
@@ -3536,6 +3558,14 @@ class Automation {
if ($dataarray && count($dataarray)) {
// preload village data
$vilIDs = [];
foreach($dataarray as $data) {
$vilIDs[$data['from']] = true;
$vilIDs[$data['to']] = true;
}
$database->getProfileVillages(array_keys($vilIDs), 5);
$movementProcIDs = [];
foreach($dataarray as $data) {
if (!isset($wavesData[$data['from'].$data['to'].$data['starttime'].$data['endtime']])) {
@@ -3656,6 +3686,14 @@ class Automation {
$times = [];
$endtimes = [];
// preload village data
$vilIDs = [];
foreach($dataarray as $data) {
$vilIDs[$data['from']] = true;
$vilIDs[$data['to']] = true;
}
$database->getProfileVillages(array_keys($vilIDs), 5);
foreach($dataarray as $data) {
$ownerID = $database->getUserField($database->getVillageField($data['from'],"owner"),"id",0);
if ($session->uid==$ownerID) $reload=true;
@@ -4217,6 +4255,14 @@ class Automation {
fclose($ourFileHandle);
$trainlist = $database->getTrainingList();
if(count($trainlist) > 0){
// preload village data
$vilIDs = [];
foreach($trainlist as $train){
$vilIDs[$train['vref']] = true;
}
$database->getProfileVillages(array_keys($vilIDs), 5);
// calculate training updates
foreach($trainlist as $train){
$timepast = $train['timestamp2'] - $time;
$pop = $train['pop'];
@@ -4240,9 +4286,9 @@ class Automation {
if($train['amt'] == 0){
$database->trainUnit($train['id'],0,0,0,0,1,1);
}
$crop = $database->getCropProdstarv($train['vref'], false);
$crop = $database->getCropProdstarv($train['vref']);
$unitarrays = $this->getAllUnits($train['vref'], false);
$village = $database->getVillage($train['vref'], 0, false);
$village = $database->getVillage($train['vref'], 0);
$upkeep = $village['pop'] + $this->getUpkeep($unitarrays, 0);
$starv = $database->getVillageField($train['vref'],"starv");
if ($crop < $upkeep){
+69 -3
View File
@@ -680,7 +680,7 @@ class MYSQLi_DB implements IDbConnection {
* to be displayed in the front-end.
*/
public static function clearVillageCache() {
self::$villageFieldsCache = [];
self::$villageFieldsCache = [];
self::$villageFieldsCacheByWorldID = [];
}
@@ -1688,7 +1688,7 @@ class MYSQLi_DB implements IDbConnection {
function getVillage($vid, $mode = 0, $use_cache = true) {
// first of all, check if we should be using cache and whether the field
// required is already cached
if ($use_cache && ($cachedValue = self::returnCachedContent(self::$villageFieldsCache, $vid.$mode)) && !is_null($cachedValue)) {
if ($use_cache && ($cachedValue = self::returnCachedContent(self::$villageFieldsCache, ((int) $vid).$mode)) && !is_null($cachedValue)) {
return $cachedValue;
}
@@ -1749,6 +1749,17 @@ class MYSQLi_DB implements IDbConnection {
return $cachedValue;
}
// if we've given a number of villages to preload, remove those that already are
if ($use_cache && $arrayPassed) {
$newIDs = [];
foreach ($uid as $id) {
if (!isset(self::$userVillagesCache[$id])) {
$newIDs[] = $id;
}
}
$uid = $newIDs;
}
switch ($mode) {
// by owner ID
case 0: $q = "SELECT * FROM " . TB_PREFIX . "vdata WHERE owner IN(".implode(', ', $uid).") ORDER BY capital DESC,pop DESC";
@@ -1769,6 +1780,14 @@ class MYSQLi_DB implements IDbConnection {
// villages in need of celebration data update
case 4: $q = "SELECT * FROM " . TB_PREFIX . "vdata WHERE celebration < ".$uid[0]." AND celebration != 0";
break;
// by vref ID
case 5: $q = "SELECT * FROM " . TB_PREFIX . "vdata WHERE wref IN(".implode(', ', $uid).")";
break;
// by loyalty updates required
case 6: $q = "SELECT * FROM " . TB_PREFIX . "vdata WHERE loyalty < 100";
break;
}
$result = mysqli_query($this->dblink,$q);
@@ -1776,15 +1795,23 @@ class MYSQLi_DB implements IDbConnection {
if (!$arrayPassed) {
$result = $this->mysqli_fetch_all($result);
self::$userVillagesCache[ $uid[0] ] = $result;
// cache each village individually into the fields cache as well
foreach ($result as $v) {
$amode = 0;
self::$villageFieldsCache[((int) $v['wref']).$amode] = $v;
}
} else {
// we're preloading, cache all the data individually
if (mysqli_num_rows($result)) {
$amode = 0;
while ( $row = mysqli_fetch_array( $result, MYSQLI_ASSOC ) ) {
if ( ! isset( self::$userVillagesCache[ $row['owner'] ] ) ) {
self::$userVillagesCache[ $row['owner'] ] = [];
}
self::$userVillagesCache[ $row['owner'] ][] = $row;
self::$villageFieldsCache[((int) $row['wref']).$amode] = $row;
}
// just return the full cache if we've given an array of IDs to load villages for
@@ -1795,6 +1822,39 @@ class MYSQLi_DB implements IDbConnection {
return $result;
}
function cacheVillageByWorldIDs($uid, $mode = 0) {
if (!is_array($uid)) {
$uid = [(int) $uid];
} else {
foreach ($uid as $index => $uidValue) {
$uid[$index] = (int) $uidValue;
}
}
$result = mysqli_query($this->dblink, "
SELECT
*
FROM
" . TB_PREFIX . "wdata as wdata
LEFT JOIN " . TB_PREFIX . "vdata as vdata ON wdata.id = vdata.wref
WHERE vdata.owner IN(".implode('', $uid).")"
);
if (mysqli_num_rows($result)) {
$result = $this->mysqli_fetch_all($result);
$amode = 0;
foreach ($result as $row) {
self::$villageFieldsCacheByWorldID[$row['id']] = $row;
// cache village fields by wref as well, for future use
if (!isset(self::$villageFieldsCache[((int) $row['wref']).$amode])) {
self::$villageFieldsCache[ ( (int) $row['wref'] ) . $amode ] = $row;
}
}
}
}
function getVillageByWorldID($vid, $use_cache = true) {
$vid = (int) $vid;
@@ -2313,6 +2373,12 @@ class MYSQLi_DB implements IDbConnection {
function checkVilExist($wref) {
list($wref) = $this->escape_input((int) $wref);
// first of all, check if this exists in our cache already - and if so, we don't need an extra query
$mode = 0;
if (isset(self::$villageFieldsCache[((int) $wref).$mode])) {
return true;
}
$q = "SELECT Count(*) as Total FROM " . TB_PREFIX . "vdata where wref = '$wref'";
$result = mysqli_fetch_array(mysqli_query($this->dblink,$q), MYSQLI_ASSOC);
if ($result['Total']) {
@@ -5961,7 +6027,7 @@ References: User ID/Message ID, Mode
$vinfo = $this->getVillage($id);
$vtribe = $this->getUserField($vinfo['owner'], "tribe", 0);
$movingunits = array();
$movingunits = array();
$outgoingarray = $this->getMovement(3, $id, 0);
if(!empty($outgoingarray)) {
foreach($outgoingarray as $out) {
+26 -5
View File
@@ -35,6 +35,9 @@ class Village {
else {
$this->wid = $session->villages[0];
}
$this->preloadVillagesData();
//add new line code
//check exist village if from village destroy to avoid error msg.
if ( !$database->checkVilExist($this->wid) ) {
@@ -48,6 +51,16 @@ class Village {
$this->ActionControl();
}
private function preloadVillagesData() {
global $database, $session;
// preload villages for this user account
$database->getProfileVillages($session->uid, 5);
// preload villages world data records
$database->cacheVillageByWorldIDs($session->uid);
}
public function getProd($type) {
return $this->production[$type];
}
@@ -57,7 +70,7 @@ class Village {
return $technology->getUnits($database->getUnit($vid),$database->getEnforceVillage($vid,0));
}
private function LoadTown() {
private function LoadTown($second_run = false) {
global $database,$session,$logging,$technology;
$this->infoarray = $database->getVillage($this->wid);
if($this->infoarray['owner'] != $session->uid && !$session->isAdmin) {
@@ -102,16 +115,24 @@ class Village {
if($this->airon>$this->maxstore){ $this->airon=$this->maxstore; $resourceUpdates['iron'] = $this->maxstore; }
if($this->acrop>$this->maxcrop){ $this->acrop=$this->maxcrop; $resourceUpdates['crop'] = $this->maxcrop; }
// update DB values
if (count($resourceUpdates)) {
call_user_func(get_class($database).'::clearVillageCache');
if (count($resourceUpdates)) {
$database->updateResource( $this->wid, array_keys( $resourceUpdates ), array_values($resourceUpdates) );
// reload cache if we've updated resources and the like
if ($second_run) {
// update DB cache
call_user_func(get_class($database).'::clearVillageCache');
$this->preloadVillagesData();
}
} else if ($second_run) {
$this->preloadVillagesData();
}
}
private function calculateProduction() {
global $technology,$database,$session;
// clear cache, since we're updating village data
call_user_func(get_class($database).'::clearVillageCache');
$normalA = $database->getOwnArtefactInfoByType($_SESSION['wid'],4);
$largeA = $database->getOwnUniqueArtefactInfo($session->uid,4,2);
@@ -145,7 +166,7 @@ class Village {
$database->modifyResource($this->wid,$nwood,$nclay,$niron,$ncrop,1);
$database->updateVillage($this->wid);
$this->LoadTown();
$this->LoadTown(true);
}
private function getWoodProd() {