mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
88 lines
3.7 KiB
Java
88 lines
3.7 KiB
Java
|
|
/*
|
||
|
|
XOWA: the XOWA Offline Wiki Application
|
||
|
|
Copyright (C) 2012 gnosygnu@gmail.com
|
||
|
|
|
||
|
|
This program is free software: you can redistribute it and/or modify
|
||
|
|
it under the terms of the GNU Affero General Public License as
|
||
|
|
published by the Free Software Foundation, either version 3 of the
|
||
|
|
License, or (at your option) any later version.
|
||
|
|
|
||
|
|
This program is distributed in the hope that it will be useful,
|
||
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
|
GNU Affero General Public License for more details.
|
||
|
|
|
||
|
|
You should have received a copy of the GNU Affero General Public License
|
||
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
*/
|
||
|
|
package gplx.dbs.percentiles; import gplx.*; import gplx.dbs.*;
|
||
|
|
public class Percentile_rng {
|
||
|
|
private long total_max; private int total_needed;
|
||
|
|
private int score_max, score_len_max;
|
||
|
|
private long prv_time;
|
||
|
|
public int Score_bgn() {return score_bgn;} private int score_bgn;
|
||
|
|
public int Score_end() {return score_end;} private int score_end;
|
||
|
|
public int Score_len() {return score_len;} private int score_len;
|
||
|
|
public int Found_rdr() {return found_rdr;} private int found_rdr;
|
||
|
|
public int Found_all() {return found_all;} private int found_all;
|
||
|
|
public int Elapsed() {return elapsed;} private int elapsed;
|
||
|
|
public Percentile_rng Init(long total_max, int score_max) {
|
||
|
|
this.total_max = total_max;
|
||
|
|
this.score_max = score_max;
|
||
|
|
this.score_len_max = score_max / 20; // limit to 5%
|
||
|
|
return this;
|
||
|
|
}
|
||
|
|
public void Select_init(int total_needed, int prv_score_bgn, int prv_score_len, int score_len_adj) {
|
||
|
|
this.total_needed = total_needed;
|
||
|
|
this.found_all = 0;
|
||
|
|
this.prv_time = gplx.core.envs.Env_.TickCount();
|
||
|
|
int score_unit = Calc_score_unit(total_needed, total_max, score_max);
|
||
|
|
if (prv_score_bgn == Score_null) {
|
||
|
|
score_len = score_unit + (score_unit * score_len_adj);
|
||
|
|
score_bgn = score_max;
|
||
|
|
Rng_len_(Bool_.Y);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
score_len = prv_score_len;
|
||
|
|
score_bgn = prv_score_bgn;
|
||
|
|
score_end = score_bgn + score_len;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
public void Update(int found_rdr) {
|
||
|
|
this.found_rdr = found_rdr;
|
||
|
|
this.found_all += found_rdr;
|
||
|
|
|
||
|
|
// calc rng_multiplier based on found_rdr and total_needed; EX: 100=total_needed; 10=found_rdr; 40=found_all -> 6=rng_multiplier; (100 - 40 / 10)
|
||
|
|
int rng_multiplier = 1;
|
||
|
|
if (found_rdr == 0) {
|
||
|
|
rng_multiplier = 4;
|
||
|
|
} else {
|
||
|
|
int total_remaining = total_needed - found_all;
|
||
|
|
rng_multiplier = total_remaining == 0 ? 1 : Math_.Ceil_as_int(total_remaining / found_rdr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// calc new score_len
|
||
|
|
int new_score_len = score_len * rng_multiplier;
|
||
|
|
if (new_score_len < 1) new_score_len = score_len;
|
||
|
|
else if (new_score_len > score_len_max) new_score_len = score_len_max;
|
||
|
|
score_len = new_score_len;
|
||
|
|
Rng_len_(Bool_.N);
|
||
|
|
|
||
|
|
// update times
|
||
|
|
long new_time = gplx.core.envs.Env_.TickCount();
|
||
|
|
this.elapsed = Int_.Subtract_long(new_time, prv_time);
|
||
|
|
prv_time = new_time;
|
||
|
|
}
|
||
|
|
private void Rng_len_(boolean first) {
|
||
|
|
score_end = score_bgn + (first ? 1 : 0); // + 1 to include rows with scores at max; EX: > 999,998 AND < 1,000,001
|
||
|
|
score_bgn = score_end - score_len;
|
||
|
|
if (score_bgn < 0) score_bgn = 0; // make sure score is not negative
|
||
|
|
}
|
||
|
|
@gplx.Internal protected static int Calc_score_unit(int total_needed, long total_max, int score_max) {// TEST:
|
||
|
|
int rv = (int)Math_.Ceil(Math_.Div_safe_as_double(total_needed, Math_.Div_safe_as_double(total_max, score_max))); // EX: 100 needed / (16 M / 1 M) -> 7 units to fill 100
|
||
|
|
if (rv > score_max) rv = score_max; // never allow score_unit to be > score_max; occurs when total_needed > total_max; EX: 50 needed; 10 available
|
||
|
|
return rv;
|
||
|
|
}
|
||
|
|
public static final int Score_null = -1;
|
||
|
|
}
|