mirror of https://github.com/gnosygnu/xowa
parent
8a5d58a973
commit
097e6c7f80
@ -0,0 +1,44 @@
|
||||
/*
|
||||
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.core.brys; import gplx.*; import gplx.core.*;
|
||||
public class Bry_bfr_mkr {
|
||||
private final Bry_bfr_mkr_mgr mkr_b128 = new Bry_bfr_mkr_mgr(Tid_b128, 128);
|
||||
public Bry_bfr Get_b128() {return mkr_b128.Get();}
|
||||
public Bry_bfr Get_b512() {return mkr_b512.Get();} private final Bry_bfr_mkr_mgr mkr_b512 = new Bry_bfr_mkr_mgr(Tid_b512, 512);
|
||||
public Bry_bfr Get_k004() {return mkr_k004.Get();} private final Bry_bfr_mkr_mgr mkr_k004 = new Bry_bfr_mkr_mgr(Tid_k004, 4 * Io_mgr.Len_kb);
|
||||
public Bry_bfr Get_m001() {return mkr_m001.Get();} private final Bry_bfr_mkr_mgr mkr_m001 = new Bry_bfr_mkr_mgr(Tid_m001, 1 * Io_mgr.Len_mb);
|
||||
public void Rls(Bry_bfr v) {v.Mkr_rls();}
|
||||
public void Clear() {
|
||||
for (byte i = Tid_b128; i <= Tid_m001; i++)
|
||||
mkr(i).Clear();
|
||||
}
|
||||
public void Clear_fail_check() {
|
||||
for (byte i = Tid_b128; i <= Tid_m001; i++)
|
||||
mkr(i).Clear_fail_check();
|
||||
}
|
||||
private Bry_bfr_mkr_mgr mkr(byte tid) {
|
||||
switch (tid) {
|
||||
case Tid_b128: return mkr_b128;
|
||||
case Tid_b512: return mkr_b512;
|
||||
case Tid_k004: return mkr_k004;
|
||||
case Tid_m001: return mkr_m001;
|
||||
default: throw Err_.new_unhandled(tid);
|
||||
}
|
||||
}
|
||||
public static final byte Tid_b128 = 0, Tid_b512 = 1, Tid_k004 = 2, Tid_m001 = 3;
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
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.core.brys; import gplx.*; import gplx.core.*;
|
||||
public class Bry_bfr_mkr_mgr {
|
||||
private final Object thread_lock = new Object();
|
||||
private Bry_bfr[] used = Bry_bfr_.Ary_empty; private int used_len = 0, used_max = 0;
|
||||
private int[] free; private int free_len; private int reset;
|
||||
public Bry_bfr_mkr_mgr(byte mgr_id, int reset) {// NOTE: random IndexOutOfBounds errors in Get around free[--free_len] with free_len being -1; put member variable initialization within thread_lock to try to avoid; DATE:2014-09-21
|
||||
this.mgr_id = mgr_id;
|
||||
this.reset = reset;
|
||||
this.free = Int_.Ary_empty;
|
||||
this.free_len = 0;
|
||||
}
|
||||
public byte Mgr_id() {return mgr_id;} private byte mgr_id;
|
||||
public Bry_bfr Get() {
|
||||
synchronized (thread_lock) {
|
||||
Bry_bfr rv = null; int rv_idx = -1;
|
||||
if (free_len > 0) {
|
||||
try {rv_idx = free[--free_len];} catch (Exception e) {throw Err_.new_exc(e, "core", "failed to get free", "idx", free_len, "free_len", free.length);}
|
||||
try {rv = used[rv_idx];} catch (Exception e) {throw Err_.new_exc(e, "core", "failed to get used", "idx", rv_idx, "used_len", used.length);}
|
||||
}
|
||||
else {
|
||||
if (used_len == used_max) Expand();
|
||||
rv_idx = used_len++;
|
||||
rv = used[rv_idx];
|
||||
if (rv == null) {
|
||||
rv = Bry_bfr.reset_(reset);
|
||||
used[rv_idx] = rv;
|
||||
}
|
||||
}
|
||||
rv.Mkr_init(this, rv_idx);
|
||||
return rv.Clear(); // NOTE: ALWAYS call Clear when doing Get. caller may forget to call Clear, and reused bfr may have leftover bytes. unit tests will not catch, and difficult to spot in app
|
||||
}
|
||||
}
|
||||
public void Rls(int idx) {
|
||||
synchronized (thread_lock) {
|
||||
if (idx == -1) throw Err_.new_wo_type("rls called on bfr that was not created by factory");
|
||||
int new_used_len = used_len - 1;
|
||||
if (idx == new_used_len)
|
||||
used_len = new_used_len;
|
||||
else
|
||||
free[free_len++] = idx;
|
||||
}
|
||||
}
|
||||
public void Clear_fail_check() {
|
||||
synchronized (thread_lock) {
|
||||
for (int i = 0; i < used_max; i++) {
|
||||
Bry_bfr itm = used[i];
|
||||
if (itm != null) {
|
||||
if (!itm.Mkr_idx_is_null()) throw Err_.new_wo_type("failed to clear bfr", "idx", Int_.To_str(i));
|
||||
itm.Clear();
|
||||
}
|
||||
used[i] = null;
|
||||
}
|
||||
used = Bry_bfr_.Ary_empty;
|
||||
free = Int_.Ary_empty;
|
||||
free_len = used_len = used_max = 0;
|
||||
}
|
||||
}
|
||||
public void Clear() {
|
||||
synchronized (thread_lock) {
|
||||
for (int i = 0; i < used_max; i++) {
|
||||
Bry_bfr itm = used[i];
|
||||
if (itm != null) itm.Clear();
|
||||
used[i] = null;
|
||||
}
|
||||
used = Bry_bfr_.Ary_empty;
|
||||
free = Int_.Ary_empty;
|
||||
free_len = 0;
|
||||
used_len = used_max = 0;
|
||||
}
|
||||
}
|
||||
@gplx.Internal protected Bry_bfr[] Used() {return used;}
|
||||
@gplx.Internal protected int Used_len() {return used_len;}
|
||||
private void Expand() {
|
||||
int new_max = used_max == 0 ? 2 : used_max * 2;
|
||||
Bry_bfr[] new_ary = new Bry_bfr[new_max];
|
||||
Array_.Copy_to(used, 0, new_ary, 0, used_max);
|
||||
used = new_ary;
|
||||
used_max = new_max;
|
||||
int[] new_free = new int[used_max];
|
||||
Array_.Copy_to(free, 0, new_free, 0, free_len);
|
||||
free = new_free;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
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.core.brys; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*;
|
||||
public class Bry_bfr_mkr_tst {
|
||||
private final Bry_bfr_mkr_fxt fxt = new Bry_bfr_mkr_fxt();
|
||||
@Before public void setup() {fxt.Clear();}
|
||||
@Test public void Get_1() {fxt.Clear().Get().Test__used(0);}
|
||||
@Test public void Get_2() {fxt.Clear().Get().Get().Test__used(0, 1);}
|
||||
@Test public void Get_3() {fxt.Clear().Get().Get().Get().Test__used(0, 1, 2);}
|
||||
@Test public void Rls() {fxt.Clear().Get().Rls(0).Test__used();}
|
||||
@Test public void Rls_skip_1() {
|
||||
fxt.Clear().Get().Get().Rls(0).Test__used(-1, 1);
|
||||
fxt.Get().Test__used(0, 1);
|
||||
}
|
||||
@Test public void Rls_skip_2_1() {
|
||||
fxt.Clear().Get().Get().Get().Rls(1).Rls(0).Test__used(-1, -1, 2);
|
||||
fxt.Get().Test__used(0, -1, 2);
|
||||
fxt.Get().Test__used(0, 1, 2);
|
||||
fxt.Get().Test__used(0, 1, 2, 3);
|
||||
}
|
||||
@Test public void Get_rls_get() { // PURPOSE: defect in which last rls failed b/c was not doing ++ if rv existed
|
||||
fxt.Clear().Get().Rls(0).Get().Get().Rls(1).Rls(0).Test__used();
|
||||
}
|
||||
}
|
||||
class Bry_bfr_mkr_fxt {
|
||||
private final Bry_bfr_mkr_mgr mkr = new Bry_bfr_mkr_mgr(Byte_.Zero, 32);
|
||||
public Bry_bfr_mkr_fxt Clear() {mkr.Clear(); return this;}
|
||||
public Bry_bfr_mkr_fxt Get() {mkr.Get(); return this;}
|
||||
public Bry_bfr_mkr_fxt Rls(int i) {mkr.Used()[i].Mkr_rls(); return this;}
|
||||
public Bry_bfr_mkr_fxt Test__used(int... expd) {
|
||||
int actl_len = mkr.Used_len();
|
||||
int[] actl = new int[actl_len];
|
||||
for (int i = 0; i < actl_len; i++) {
|
||||
Bry_bfr bfr = mkr.Used()[i];
|
||||
int actl_val = bfr == null ? -2 : bfr.Mkr_idx();
|
||||
actl[i] = actl_val;
|
||||
}
|
||||
Tfds.Eq_ary(expd, actl);
|
||||
return this;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue