[IMPROVED] Cronbased global Hash-/Sharerate cache

* [ADDED] New statistic method to fetch all user mining stats
* [ADDED] New global cache to getUserHash/Sharerate calls
* [ADDED] New memcache key for new global cache

Addresses #1471 and may fix it already if no other changes are required.
This commit is contained in:
Sebastian Grewe 2014-01-19 17:05:27 +01:00
parent 10e3fcab7e
commit cf49db4535
3 changed files with 76 additions and 1 deletions

View File

@ -27,10 +27,16 @@ require_once('shared.inc.php');
// Per user share statistics based on all shares submitted
$start = microtime(true);
if ( ! $aAllUserShares = $statistics->getAllUserShares() )
if ( ! $statistics->getAllUserShares() )
$log->logError('getAllUserShares update failed');
$log->logInfo("getAllUserShares " . number_format(microtime(true) - $start, 2) . " seconds");
// Get all user hashrate statistics for caching
$start = microtime(true);
if ( ! $statistics->getAllUserMiningStats() )
$log->logError('getAllUserMiningStats update failed');
$log->logInfo("getAllUserMiningStats " . number_format(microtime(true) - $start, 2) . " seconds");
$start = microtime(true);
if (!$statistics->getTopContributors('hashes'))
$log->logError("getTopContributors hashes update failed");

View File

@ -448,6 +448,53 @@ class Statistics extends Base {
return $this->sqlError();
}
/**
* Fetch all user hashrates based on shares and archived shares
* @return data integer Current Hashrate in khash/s
**/
public function getAllUserMiningStats($interval=600) {
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("
SELECT
a.id AS id,
a.username AS account,
IFNULL(ROUND(SUM(t1.difficulty) * POW(2, 16) / ? / 1000, 2), 0) AS hashrate,
ROUND(COUNT(t1.id) / ?, 2) AS sharerate,
IFNULL(AVG(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS avgsharediff
FROM (
SELECT
id,
IFNULL(IF(difficulty=0, pow(2, (20 - 16)), difficulty), 0) AS difficulty,
username
FROM shares
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND) AND our_result = 'Y'
UNION
SELECT
share_id,
IFNULL(IF(difficulty=0, pow(2, (20 - 16)), difficulty), 0) AS difficulty,
username
FROM shares_archive
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND) AND our_result = 'Y'
) AS t1
LEFT JOIN " . $this->user->getTableName() . " AS a
ON SUBSTRING_INDEX( t1.username, '.', 1 ) = a.username
WHERE a.id IS NOT NULL
GROUP BY account
ORDER BY hashrate DESC
");
if ($this->checkStmt($stmt) && $stmt->bind_param("iiii", $interval, $interval, $interval, $interval) && $stmt->execute() && $result = $stmt->get_result() ) {
$aData = array();
while ($row = $result->fetch_assoc()) {
$aData['data'][$row['id']] = $row;
}
var_dump($aData);
return $this->memcache->setCache(STATISTICS_ALL_USER_HASHRATES, $aData);
} else {
echo $this->mysqli->error;
return $this->sqlError();
}
}
/**
* Fetch total user hashrate based on shares and archived shares
* @param account_id integer User ID
@ -455,6 +502,13 @@ class Statistics extends Base {
**/
public function getUserHashrate($account_id, $interval=600) {
$this->debug->append("STA " . __METHOD__, 4);
// Dual-caching, try statistics cron first, then fallback to local, then fallbock to SQL
if ($data = $this->memcache->get(STATISTICS_ALL_USER_HASHRATES)) {
if (array_key_exists($account_id, $data['data']))
return $data['data'][$account_id]['hashrate'];
// We have no cached value, we return defaults
return 0;
}
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
$stmt = $this->mysqli->prepare("
SELECT
@ -510,6 +564,13 @@ class Statistics extends Base {
**/
public function getUserShareDifficulty($account_id, $interval=600) {
$this->debug->append("STA " . __METHOD__, 4);
// Dual-caching, try statistics cron first, then fallback to local, then fallbock to SQL
if ($data = $this->memcache->get(STATISTICS_ALL_USER_HASHRATES)) {
if (array_key_exists($account_id, $data['data']))
return $data['data'][$account_id]['avgsharediff'];
// We have no cached value, we return defaults
return 0;
}
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
$stmt = $this->mysqli->prepare("
SELECT
@ -532,6 +593,13 @@ class Statistics extends Base {
**/
public function getUserSharerate($account_id, $interval=600) {
$this->debug->append("STA " . __METHOD__, 4);
// Dual-caching, try statistics cron first, then fallback to local, then fallbock to SQL
if ($data = $this->memcache->get(STATISTICS_ALL_USER_HASHRATES)) {
if (array_key_exists($account_id, $data['data']))
return $data['data'][$account_id]['sharerate'];
// We have no cached value, we return defaults
return 0;
}
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
$stmt = $this->mysqli->prepare("
SELECT

View File

@ -4,5 +4,6 @@
if (!defined('SECURITY')) die('Hacking attempt');
define('STATISTICS_ALL_USER_SHARES', 'STATISTICS_ALL_USER_SHARES');
define('STATISTICS_ALL_USER_HASHRATES', 'STATISTICS_ALL_USER_HASHRATES');
define('STATISTICS_ROUND_SHARES', 'STATISTICS_ROUND_SHARES');
?>