size_regulator: make the DB access more efficient

The query to get counts of unsent results for various size classes
did a sequential scan, which isn't practical for large projects.
All we care about is the count up to a certain (low) limit,
so I replaced it with an enumeration with a limit, and count the results.
This commit is contained in:
David Anderson 2015-06-03 00:30:18 -07:00
parent 63be0272e0
commit bc9747789e
4 changed files with 38 additions and 4 deletions

View File

@ -494,6 +494,7 @@ CSimpleTaskPanel::CSimpleTaskPanel( wxWindow* parent ) :
wxBoxSizer* bSizer3;
bSizer3 = new wxBoxSizer( wxHORIZONTAL );
// what project the task is from, e.g. "From: SETI@home"
m_TaskProjectLabel = new CTransparentStaticText( this, wxID_ANY, _("From:"), wxDefaultPosition, wxDefaultSize, 0 );
m_TaskProjectLabel->Wrap( -1 );
bSizer3->Add( m_TaskProjectLabel, 0, wxRIGHT, ADJUSTFORXDPI(5) );

View File

@ -1138,6 +1138,38 @@ void DB_RESULT::db_parse(MYSQL_ROW &r) {
peak_disk_usage = atof(r[i++]);
}
// faster version.
// return unsent count up to a max of "count_max"
//
int DB_RESULT::get_unsent_counts(APP& app, int* unsent_count, int count_max) {
char query[1024];
int retval;
MYSQL_RES *rp;
for (int i=0; i<app.n_size_classes; i++) {
sprintf(query,
"select id from result where appid=%d and server_state=%d and size_class=%d limit %d",
app.id, RESULT_SERVER_STATE_UNSENT, i, count_max
);
retval = db->do_query(query);
if (retval) return mysql_errno(db->mysql);
rp = mysql_store_result(db->mysql);
if (!rp) return mysql_errno(db->mysql);
int count = 0;
while (1) {
MYSQL_ROW row = mysql_fetch_row(rp);
if (!row) break;
count++;
}
mysql_free_result(rp);
unsent_count[i] = count;
}
return 0;
}
#if 0
// the following is too slow if result table is large.
//
int DB_RESULT::get_unsent_counts(APP& app, int* unsent_count) {
char query[1024];
MYSQL_RES *rp;
@ -1169,6 +1201,7 @@ int DB_RESULT::get_unsent_counts(APP& app, int* unsent_count) {
mysql_free_result(rp);
return retval;
}
#endif
int DB_RESULT::make_unsent(
APP& app, int size_class, int n, const char* order_clause, int& nchanged

View File

@ -184,7 +184,7 @@ public:
void db_print_values(char*);
void db_parse(MYSQL_ROW &row);
void operator=(RESULT& r) {RESULT::operator=(r);}
int get_unsent_counts(APP&, int* unsent);
int get_unsent_counts(APP&, int* unsent, int count_max);
int make_unsent(
APP&, int size_class, int n, const char* order_clause, int& nchanged
);

View File

@ -15,8 +15,8 @@
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
// daemon to regulate the transition of jobs from INACTIVE to UNSENT,
// to maintain a buffer of UNSENT jobs of each size class.
// daemon to regulate the transition of results from INACTIVE to UNSENT,
// to maintain a buffer of UNSENT results of each size class.
#include <stdio.h>
@ -43,7 +43,7 @@ void usage(){
int do_pass(bool& action) {
DB_RESULT result;
int unsent[100];
int retval = result.get_unsent_counts(app, unsent);
int retval = result.get_unsent_counts(app, unsent, hi);
if (retval) return retval;
action = false;
for (int i=0; i<app.n_size_classes; i++) {