mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
'v3.7.1.1'
This commit is contained in:
@@ -542,6 +542,11 @@ public class Bry_bfr {
|
||||
if (reset > 0) Reset_if_gt(reset);
|
||||
return rv;
|
||||
}
|
||||
public byte[] To_bry_and_clear_and_rls() {
|
||||
byte[] rv = To_bry_and_clear();
|
||||
this.Mkr_rls();
|
||||
return rv;
|
||||
}
|
||||
public String To_str() {return String_.new_u8(To_bry());}
|
||||
public String To_str_by_pos(int bgn, int end) {return String_.new_u8(To_bry(), bgn, end);}
|
||||
public String To_str_and_clear() {return String_.new_u8(To_bry_and_clear());}
|
||||
|
||||
@@ -30,6 +30,7 @@ public class Gfo_log_ {
|
||||
}
|
||||
public static Gfo_log New_file(Io_url dir) {
|
||||
Io_url url = dir.GenSubFil(DateAdp_.Now().XtoStr_fmt(File__fmt) + File__ext);
|
||||
Gfo_log__file.Delete_old_files(dir, Gfo_log_.Instance);
|
||||
return new Gfo_log__file(url, new Gfo_log_itm_wtr__csv());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,16 @@ public class Int_ implements Gfo_invk {
|
||||
for (int i = 0; i < src_len; ++i)
|
||||
trg[i] = src[i];
|
||||
}
|
||||
public static String Ary_concat(String spr, int... ary) {
|
||||
Bry_bfr bfr = Bry_bfr_.New();
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (i != 0) bfr.Add_str_u8(spr);
|
||||
int itm = ary[i];
|
||||
bfr.Add_int_variable(itm);
|
||||
}
|
||||
return bfr.To_str_and_clear();
|
||||
}
|
||||
public static int[] AryRng(int bgn, int end) {
|
||||
int len = end - bgn + 1;
|
||||
int[] rv = new int[len];
|
||||
|
||||
31
100_core/src/gplx/core/btries/Btrie_rv.java
Normal file
31
100_core/src/gplx/core/btries/Btrie_rv.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
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.btries; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.threads.poolables.*;
|
||||
public class Btrie_rv implements Gfo_poolable_itm {
|
||||
public Object Obj() {return obj;} private Object obj;
|
||||
public int Pos() {return pos;} private int pos;
|
||||
public Btrie_rv Init(int pos, Object obj) {
|
||||
this.obj = obj;
|
||||
this.pos = pos;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Pool__rls () {pool_mgr.Rls_fast(pool_idx);} private Gfo_poolable_mgr pool_mgr; private int pool_idx;
|
||||
public Gfo_poolable_itm Pool__make (Gfo_poolable_mgr mgr, int idx, Object[] args) {Btrie_rv rv = new Btrie_rv(); rv.pool_mgr = mgr; rv.pool_idx = idx; return rv;}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ public class Btrie_slim_itm {
|
||||
}
|
||||
if (found) --ary_len;
|
||||
}
|
||||
public static final Btrie_slim_itm[] Ary_empty = new Btrie_slim_itm[0]; int ary_len = 0, ary_max = 0;
|
||||
public static final Btrie_slim_itm[] Ary_empty = new Btrie_slim_itm[0]; int ary_len = 0, ary_max = 0;
|
||||
}
|
||||
class ByteHashItm_sorter {// quicksort
|
||||
Btrie_slim_itm[] ary; int ary_len;
|
||||
@@ -126,5 +126,5 @@ class ByteHashItm_sorter {// quicksort
|
||||
if (lo < j) Sort_recurse(lo, j);
|
||||
if (i < hi) Sort_recurse(i, hi);
|
||||
}
|
||||
public static final ByteHashItm_sorter Instance = new ByteHashItm_sorter(); ByteHashItm_sorter() {}
|
||||
public static final ByteHashItm_sorter Instance = new ByteHashItm_sorter(); ByteHashItm_sorter() {}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,35 @@ 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.btries; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.primitives.*;
|
||||
import gplx.core.primitives.*; import gplx.core.threads.poolables.*;
|
||||
public class Btrie_slim_mgr implements Btrie_mgr {
|
||||
private static Gfo_poolable_mgr pool_rv = Gfo_poolable_mgr.New_rlsable(new Btrie_rv(), Object_.Ary_empty, 0, 1024);
|
||||
Btrie_slim_mgr(boolean case_match) {root = new Btrie_slim_itm(Byte_.Zero, null, !case_match);} private Btrie_slim_itm root;
|
||||
public int Count() {return count;} private int count;
|
||||
public int Match_pos() {return match_pos;} private int match_pos;
|
||||
|
||||
public Btrie_rv Match_at(byte[] src, int bgn, int end) {return bgn < end ? Match_at_w_b0(src[bgn], src, bgn, end) : null;} // handle out of bounds gracefully; EX: Match_bgn("abc", 3, 3) should return null not fail
|
||||
public Btrie_rv Match_at_w_b0(byte b, byte[] src, int bgn_pos, int src_end) {
|
||||
Object rv_obj = null;
|
||||
int rv_pos = bgn_pos;
|
||||
int cur_pos = bgn_pos;
|
||||
Btrie_slim_itm cur = root;
|
||||
while (true) {
|
||||
Btrie_slim_itm nxt = cur.Ary_find(b);
|
||||
if (nxt == null)
|
||||
return ((Btrie_rv)pool_rv.Get_safe()).Init(cur_pos, rv_obj); // nxt does not hav b; return rv_obj;
|
||||
++cur_pos;
|
||||
if (nxt.Ary_is_empty()) {
|
||||
return ((Btrie_rv)pool_rv.Get_safe()).Init(cur_pos, nxt.Val()); // nxt is leaf; return nxt.Val() (which should be non-null)
|
||||
}
|
||||
Object nxt_val = nxt.Val();
|
||||
if (nxt_val != null) {rv_pos = cur_pos; rv_obj = nxt_val;} // nxt is node; cache rv_obj (in case of false match)
|
||||
if (cur_pos == src_end)
|
||||
return ((Btrie_rv)pool_rv.Get_safe()).Init(rv_pos, rv_obj); // increment cur_pos and exit if src_end
|
||||
b = src[cur_pos];
|
||||
cur = nxt;
|
||||
}
|
||||
}
|
||||
public Object Match_exact(byte[] src) {return src == null ? null : Match_exact(src, 0, src.length);}
|
||||
public Object Match_exact(byte[] src, int bgn_pos, int end_pos) {
|
||||
if (bgn_pos == end_pos) return null; // NOTE:handle empty String; DATE:2016-04-21
|
||||
|
||||
@@ -98,7 +98,7 @@ public class IoEngine_system extends IoEngine_base {
|
||||
}
|
||||
return Load_from_stream_as_str(stream, url_str);
|
||||
}
|
||||
@SuppressWarnings("resource") public static String Load_from_stream_as_str(InputStream stream, String url_str) {
|
||||
public static String Load_from_stream_as_str(InputStream stream, String url_str) {
|
||||
InputStreamReader reader = null;
|
||||
try {reader = new InputStreamReader(stream, IoEngineArgs.Instance.LoadFilStr_Encoding);}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
@@ -131,7 +131,7 @@ public class IoEngine_system extends IoEngine_base {
|
||||
Closeable_close(reader, url_str, false);
|
||||
return sw.toString();
|
||||
}
|
||||
@SuppressWarnings("resource") public static byte[] Load_from_stream_as_bry(InputStream stream, String url_str) {
|
||||
public static byte[] Load_from_stream_as_bry(InputStream stream, String url_str) {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
byte[] data = new byte[4096];
|
||||
int read = 0;
|
||||
@@ -239,7 +239,6 @@ public class IoEngine_system extends IoEngine_base {
|
||||
if (!ExistsFil_api(url)) SaveFilText_api(IoEngine_xrg_saveFilStr.new_(url, ""));
|
||||
return IoStream_base.new_(url, args.Mode());
|
||||
}
|
||||
@SuppressWarnings("resource")
|
||||
@Override public void CopyFil(IoEngine_xrg_xferFil args) {
|
||||
// TODO:JAVA6 hidden property ignored; 1.6 does not allow OS-independent way of setting isHidden (wnt only possible through jni)
|
||||
boolean overwrite = args.Overwrite();
|
||||
|
||||
@@ -77,7 +77,7 @@ abstract class Io_stream_wtr_base implements Io_stream_wtr {
|
||||
public Io_url Url() {return url;} public Io_stream_wtr Url_(Io_url v) {url = v; trg_bfr = null; return this;} Io_url url;
|
||||
public void Trg_bfr_(Bry_bfr v) {trg_bfr = v;} Bry_bfr trg_bfr; java.io.ByteArrayOutputStream mem_stream;
|
||||
public byte[] To_ary_and_clear() {return trg_bfr.To_bry_and_clear();}
|
||||
@SuppressWarnings("resource") public Io_stream_wtr Open() {
|
||||
public Io_stream_wtr Open() {
|
||||
java.io.OutputStream bry_stream = null;
|
||||
if (trg_bfr == null) {
|
||||
if (!Io_mgr.Instance.ExistsFil(url)) Io_mgr.Instance.SaveFilStr(url, "");
|
||||
@@ -130,7 +130,7 @@ class Io_stream_wtr_zip implements Io_stream_wtr {
|
||||
@Override public byte Tid() {return Io_stream_.Tid_zip;}
|
||||
public Io_url Url() {return url;} public Io_stream_wtr Url_(Io_url v) {url = v; trg_bfr = null; return this;} private Io_url url = Io_url_.Empty;
|
||||
public void Trg_bfr_(Bry_bfr v) {trg_bfr = v;} private Bry_bfr trg_bfr; private java.io.ByteArrayOutputStream mem_stream;
|
||||
@SuppressWarnings("resource") // rely on zip_stream to close bry_stream
|
||||
// rely on zip_stream to close bry_stream
|
||||
public Io_stream_wtr Open() {
|
||||
java.io.OutputStream bry_stream;
|
||||
if (trg_bfr == null) {
|
||||
|
||||
@@ -41,13 +41,22 @@ public class Io_zip_compress_cmd__jre {
|
||||
while (true) { // loop over bytes
|
||||
int read_in_raw = -1;
|
||||
try {read_in_raw = src_stream.read(buffer);}
|
||||
catch (Exception e) {throw Err_.new_exc(e, "io", "src read failed", "url", src_url.Raw());}
|
||||
catch (Exception e) {
|
||||
try {src_stream.close();}
|
||||
catch (IOException e1) {}
|
||||
throw Err_.new_exc(e, "io", "src read failed", "url", src_url.Raw());
|
||||
}
|
||||
if (read_in_raw < 1) break;
|
||||
try {trg_stream.write(buffer, 0, read_in_raw);}
|
||||
catch (Exception e) {throw Err_.new_exc(e, "io", "trg write failed", "url", trg_url.Raw());}
|
||||
catch (Exception e) {
|
||||
try {src_stream.close();}
|
||||
catch (IOException e1) {}
|
||||
throw Err_.new_exc(e, "io", "trg write failed", "url", trg_url.Raw());
|
||||
}
|
||||
}
|
||||
try {
|
||||
trg_stream.closeEntry();
|
||||
trg_stream.close();
|
||||
src_stream.close();
|
||||
}
|
||||
catch (Exception e) {throw Err_.new_exc(e, "io", "trg close entry failed", "url", src_url.Raw());}
|
||||
|
||||
@@ -48,4 +48,16 @@ public class Gfo_log__file extends Gfo_log__base {
|
||||
Io_mgr.Instance.AppendFilByt(url, bry);
|
||||
itms.Clear();
|
||||
}
|
||||
public static void Delete_old_files(Io_url dir, Gfo_log log) {
|
||||
Io_url[] fils = Io_mgr.Instance.QueryDir_fils(dir);
|
||||
int fils_len = fils.length;
|
||||
if (fils_len < 9) return; // exit if less than 8 files
|
||||
int cutoff = fils_len - 8;
|
||||
Array_.Sort(fils); // sort by path
|
||||
for (int i = 0; i < cutoff; ++i) {
|
||||
Io_url fil = fils[i];
|
||||
log.Info("deleting old log file", "file", fil.Raw());
|
||||
Io_mgr.Instance.DeleteFil(fil);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
21
100_core/src/gplx/core/memorys/Gfo_memory_itm.java
Normal file
21
100_core/src/gplx/core/memorys/Gfo_memory_itm.java
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
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.memorys; import gplx.*; import gplx.core.*;
|
||||
public interface Gfo_memory_itm {
|
||||
void Rls_mem();
|
||||
}
|
||||
33
100_core/src/gplx/core/memorys/Gfo_memory_mgr.java
Normal file
33
100_core/src/gplx/core/memorys/Gfo_memory_mgr.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
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.memorys; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_memory_mgr {
|
||||
private final List_adp list = List_adp_.New();
|
||||
public void Reg_safe(Gfo_memory_itm itm) {synchronized (list) {Reg_fast(itm);}}
|
||||
public void Reg_fast(Gfo_memory_itm itm) {list.Add(itm);}
|
||||
public void Rls_safe() {synchronized (list) {Rls_fast();}}
|
||||
public void Rls_fast() {
|
||||
int len = list.Len();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Gfo_memory_itm itm = (Gfo_memory_itm)list.Get_at(i);
|
||||
itm.Rls_mem();
|
||||
}
|
||||
list.Clear();
|
||||
}
|
||||
public static final Gfo_memory_mgr Instance = new Gfo_memory_mgr(); Gfo_memory_mgr() {}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ public class Gfo_prog_ui_ {
|
||||
, Status__done = 4
|
||||
, Status__fail = 8
|
||||
, Status__suspended = 16
|
||||
, Status__runnable = Status__init | Status__suspended
|
||||
, Status__runnable = Status__init | Status__suspended | Status__fail
|
||||
;
|
||||
}
|
||||
class Gfo_prog_ui__noop implements Gfo_prog_ui {
|
||||
|
||||
@@ -19,8 +19,9 @@ package gplx.core.tests; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.brys.*;
|
||||
public class Gftest {
|
||||
private static final Bry_bfr bfr = Bry_bfr_.New();
|
||||
public static void Eq__ary(long[] expd, long[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__long, expd, actl, msg_fmt, msg_args);}
|
||||
public static void Eq__ary__lines(String expd, String actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__bry, Bry_split_.Split_lines(Bry_.new_u8(expd)), Bry_split_.Split_lines(Bry_.new_u8(actl)), msg_fmt, msg_args);}
|
||||
public static void Eq__ary(int[] expd, int[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__int, expd, actl, msg_fmt, msg_args);}
|
||||
public static void Eq__ary(long[] expd, long[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__long, expd, actl, msg_fmt, msg_args);}
|
||||
public static void Eq__ary__lines(String expd, String actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__bry, Bry_split_.Split_lines(Bry_.new_u8(expd)), Bry_split_.Split_lines(Bry_.new_u8(actl)), msg_fmt, msg_args);}
|
||||
public static void Eq__ary(String[] expd, String[] actl) {Eq__array(Type_adp_.Tid__bry, Bry_.Ary(expd), Bry_.Ary(actl), "no_msg");}
|
||||
public static void Eq__ary(String[] expd, String[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__bry, Bry_.Ary(expd), Bry_.Ary(actl), msg_fmt, msg_args);}
|
||||
public static void Eq__ary(String[] expd, byte[][] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__bry, Bry_.Ary(expd), actl, msg_fmt, msg_args);}
|
||||
@@ -37,6 +38,20 @@ public class Gftest {
|
||||
throw Err_.new_wo_type(bfr.To_str_and_clear());
|
||||
}
|
||||
}
|
||||
public static void Eq__null(boolean expd, Object actl) {Eq__null(expd, actl, null);}
|
||||
public static void Eq__null(boolean expd, Object actl, String msg_fmt, Object... msg_args) {
|
||||
if ( expd && actl == null
|
||||
|| !expd && actl != null
|
||||
) return;
|
||||
Write_fail_head(bfr, msg_fmt, msg_args);
|
||||
String expd_str = expd ? "null" : "not null";
|
||||
String actl_str = actl == null ? "null" : "not null";
|
||||
bfr.Add_str_a7("expd: ").Add_str_a7(expd_str).Add_byte_nl();
|
||||
bfr.Add_str_a7("actl: ").Add_str_a7(actl_str).Add_byte_nl();
|
||||
bfr.Add(Bry__line_end);
|
||||
throw Err_.new_wo_type(bfr.To_str_and_clear());
|
||||
}
|
||||
public static void Eq__str(String expd, byte[] actl, String msg_fmt, Object... msg_args) {Eq__str(expd, String_.new_u8(actl), msg_fmt, msg_args);}
|
||||
public static void Eq__str(String expd, byte[] actl) {Eq__str(expd, String_.new_u8(actl), null);}
|
||||
public static void Eq__str(String expd, String actl) {Eq__str(expd, actl, null);}
|
||||
public static void Eq__str(String expd, String actl, String msg_fmt, Object... msg_args) {
|
||||
@@ -65,6 +80,24 @@ public class Gftest {
|
||||
bfr.Add(Bry__line_end);
|
||||
throw Err_.new_wo_type(bfr.To_str_and_clear());
|
||||
}
|
||||
public static void Eq__byte(byte expd, byte actl) {Eq__byte(expd, actl, null);}
|
||||
public static void Eq__byte(byte expd, byte actl, String msg_fmt, Object... msg_args) {
|
||||
if (expd == actl) return;
|
||||
Write_fail_head(bfr, msg_fmt, msg_args);
|
||||
bfr.Add_str_a7("expd: ").Add_byte_as_a7(expd).Add_byte_nl();
|
||||
bfr.Add_str_a7("actl: ").Add_byte_as_a7(actl).Add_byte_nl();
|
||||
bfr.Add(Bry__line_end);
|
||||
throw Err_.new_wo_type(bfr.To_str_and_clear());
|
||||
}
|
||||
public static void Eq__int(int expd, int actl) {Eq__int(expd, actl, null);}
|
||||
public static void Eq__int(int expd, int actl, String msg_fmt, Object... msg_args) {
|
||||
if (expd == actl) return;
|
||||
Write_fail_head(bfr, msg_fmt, msg_args);
|
||||
bfr.Add_str_a7("expd: ").Add_int_variable(expd).Add_byte_nl();
|
||||
bfr.Add_str_a7("actl: ").Add_int_variable(actl).Add_byte_nl();
|
||||
bfr.Add(Bry__line_end);
|
||||
throw Err_.new_wo_type(bfr.To_str_and_clear());
|
||||
}
|
||||
public static void Eq__bool_y(boolean actl) {Eq__bool(Bool_.Y, actl, null);}
|
||||
public static void Eq__bool(boolean expd, boolean actl) {Eq__bool(expd, actl, null);}
|
||||
public static void Eq__bool(boolean expd, boolean actl, String msg_fmt, Object... msg_args) {
|
||||
@@ -112,6 +145,7 @@ public class Gftest {
|
||||
switch (type_id) {
|
||||
case Type_adp_.Tid__bry: bfr.Add((byte[])Array_.Get_at(ary, idx)); break;
|
||||
case Type_adp_.Tid__long: bfr.Add_long_variable(Long_.cast(Array_.Get_at(ary, idx))); break;
|
||||
case Type_adp_.Tid__int: bfr.Add_int_variable(Int_.cast(Array_.Get_at(ary, idx))); break;
|
||||
default: throw Err_.new_unhandled_default(type_id);
|
||||
}
|
||||
}
|
||||
@@ -134,6 +168,7 @@ public class Gftest {
|
||||
switch (tid) {
|
||||
case Type_adp_.Tid__bry: eq = Bry_.Eq((byte[])expd_obj, (byte[])actl_obj); break;
|
||||
case Type_adp_.Tid__long: eq = Long_.cast(expd_obj) == Long_.cast(actl_obj); break;
|
||||
case Type_adp_.Tid__int: eq = Int_.cast(expd_obj) == Int_.cast(actl_obj); break;
|
||||
}
|
||||
}
|
||||
if (!eq) {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
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.threads.poolables; import gplx.*; import gplx.core.*; import gplx.core.threads.*;
|
||||
public interface Gfo_poolable_itm {
|
||||
Gfo_poolable_itm Pool__make (Gfo_poolable_mgr mgr, int idx, Object[] args);
|
||||
void Pool__rls();
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
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.threads.poolables; import gplx.*; import gplx.core.*; import gplx.core.threads.*;
|
||||
import gplx.core.memorys.*;
|
||||
public class Gfo_poolable_mgr implements Gfo_memory_itm {
|
||||
private final Object thread_lock = new Object();
|
||||
private final Gfo_poolable_itm prototype; private final Object[] make_args;
|
||||
private Gfo_poolable_itm[] pool; private int pool_nxt, pool_len;
|
||||
public Gfo_poolable_mgr(Gfo_poolable_itm prototype, Object[] make_args, int init_pool_len, int pool_max) {// NOTE: random IndexOutOfBounds errors in Get around free_ary[--free_len] with free_len being -1; put member variable initialization within thread_lock to try to avoid; DATE:2014-09-21
|
||||
this.prototype = prototype; this.make_args = make_args;
|
||||
this.pool_len = init_pool_len;
|
||||
this.Clear_fast();
|
||||
}
|
||||
public void Rls_mem() {Clear_safe();}
|
||||
public void Clear_safe() {synchronized (thread_lock) {Clear_fast();}}
|
||||
public void Clear_fast() {
|
||||
this.pool = new Gfo_poolable_itm[pool_len];
|
||||
for (int i = 0; i < pool_len; ++i)
|
||||
pool[i] = prototype.Pool__make(this, i, make_args);
|
||||
this.free_ary = new int[pool_len];
|
||||
pool_nxt = free_len = 0;
|
||||
}
|
||||
public Gfo_poolable_itm Get_safe() {synchronized (thread_lock) {return Get_fast();}}
|
||||
public Gfo_poolable_itm Get_fast() {
|
||||
Gfo_poolable_itm rv = null;
|
||||
int pool_idx = -1;
|
||||
if (free_len > 0) { // free_itms in pool; use it
|
||||
pool_idx = free_ary[--free_len];
|
||||
rv = pool[pool_idx];
|
||||
}
|
||||
else { // nothing in pool; take next
|
||||
if (pool_nxt == pool_len)
|
||||
Expand_pool();
|
||||
pool_idx = pool_nxt++;
|
||||
rv = pool[pool_idx];
|
||||
if (rv == null) {
|
||||
rv = prototype.Pool__make(this, pool_idx, make_args);
|
||||
pool[pool_idx] = rv;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public void Rls_safe(int idx) {synchronized (thread_lock) {Rls_safe(idx);}}
|
||||
public void Rls_fast(int idx) {
|
||||
if (idx == -1) throw Err_.new_wo_type("rls called on poolable that was not created by pool_mgr");
|
||||
int pool_idx = pool_nxt - 1;
|
||||
if (idx == pool_idx) // in-sequence; decrement count
|
||||
if (free_len == 0)
|
||||
this.pool_nxt = pool_idx;
|
||||
else { // idx == pool_idx; assume entire pool released, but out of order
|
||||
for (int i = 0; i < free_len; ++i)
|
||||
free_ary[i] = 0;
|
||||
free_len = 0;
|
||||
}
|
||||
else { // out-of-sequence
|
||||
free_ary[free_len] = idx;
|
||||
++free_len;
|
||||
}
|
||||
}
|
||||
private void Expand_pool() {
|
||||
// expand pool
|
||||
int new_pool_len = pool_len == 0 ? 2 : pool_len * 2;
|
||||
Gfo_poolable_itm[] new_pool = new Gfo_poolable_itm[new_pool_len];
|
||||
Array_.Copy_to(pool, 0, new_pool, 0, pool_len);
|
||||
this.pool = new_pool;
|
||||
this.pool_len = new_pool_len;
|
||||
|
||||
// expand free_ary to same len
|
||||
int[] new_free = new int[pool_len];
|
||||
Array_.Copy_to(free_ary, 0, new_free, 0, free_len);
|
||||
this.free_ary = new_free;
|
||||
}
|
||||
@gplx.Internal protected int[] Free_ary() {return free_ary;} private int[] free_ary; private int free_len;
|
||||
@gplx.Internal protected int Free_len() {return free_len;}
|
||||
@gplx.Internal protected int Pool_len() {return pool_len;}
|
||||
@gplx.Internal protected int Pool_nxt() {return pool_nxt;}
|
||||
|
||||
public static Gfo_poolable_mgr New_rlsable(Gfo_poolable_itm prototype, Object[] make_args, int init_pool_len, int pool_max) {
|
||||
Gfo_poolable_mgr rv = new Gfo_poolable_mgr(prototype, make_args, init_pool_len, pool_max);
|
||||
Gfo_memory_mgr.Instance.Reg_safe(rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
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.threads.poolables; import gplx.*; import gplx.core.*; import gplx.core.threads.*;
|
||||
public class Gfo_poolable_mgr_ {
|
||||
public static Gfo_poolable_mgr New(int len, int max, Gfo_poolable_itm prototype) {return new Gfo_poolable_mgr(prototype, Object_.Ary_empty, len, max);}
|
||||
public static Gfo_poolable_mgr New(int len, int max, Gfo_poolable_itm prototype, Object[] make_args) {return new Gfo_poolable_mgr(prototype, make_args, len, max);}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
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.threads.poolables; import gplx.*; import gplx.core.*; import gplx.core.threads.*;
|
||||
import org.junit.*;
|
||||
public class Gfo_poolable_mgr_tst {
|
||||
private final Gfo_poolable_mgr_tstr tstr = new Gfo_poolable_mgr_tstr();
|
||||
@Before public void init() {tstr.Clear();}
|
||||
@Test public void Get__one() {
|
||||
tstr.Test__get(0);
|
||||
tstr.Test__free__len(0);
|
||||
tstr.Test__pool__len(2);
|
||||
}
|
||||
@Test public void Get__many__expand() {
|
||||
tstr.Test__get(0);
|
||||
tstr.Test__get(1);
|
||||
tstr.Test__get(2);
|
||||
tstr.Test__free__len(0);
|
||||
tstr.Test__pool__len(4);
|
||||
}
|
||||
@Test public void Rls__lifo() {
|
||||
tstr.Test__get(0);
|
||||
tstr.Test__get(1);
|
||||
tstr.Test__get(2);
|
||||
tstr.Exec__rls(2);
|
||||
tstr.Exec__rls(1);
|
||||
tstr.Exec__rls(0);
|
||||
tstr.Test__pool__nxt(0);
|
||||
tstr.Test__free__len(0);
|
||||
}
|
||||
@Test public void Rls__fifo() {
|
||||
tstr.Test__get(0);
|
||||
tstr.Test__get(1);
|
||||
tstr.Test__get(2);
|
||||
tstr.Exec__rls(0);
|
||||
tstr.Exec__rls(1);
|
||||
tstr.Test__pool__nxt(3);
|
||||
tstr.Test__free__len(2); // 2 items in free_ary
|
||||
tstr.Test__free__ary(0, 1, 0, 0);
|
||||
|
||||
tstr.Test__get(1);
|
||||
tstr.Exec__rls(1);
|
||||
|
||||
tstr.Exec__rls(2);
|
||||
tstr.Test__free__len(0); // 0 items in free_ary
|
||||
tstr.Test__free__ary(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
class Gfo_poolable_mgr_tstr {
|
||||
private final Gfo_poolable_mgr mgr = new Gfo_poolable_mgr(new Sample_poolable_itm(null, -1, Object_.Ary_empty), Object_.Ary("make"), 2, 8);
|
||||
public void Clear() {mgr.Clear_fast();}
|
||||
public void Test__get(int expd_idx) {
|
||||
Sample_poolable_itm actl_itm = (Sample_poolable_itm)mgr.Get_fast();
|
||||
Tfds.Eq(expd_idx, actl_itm.Pool__idx(), "pool_idx");
|
||||
}
|
||||
public void Test__free__ary(int... expd) {Tfds.Eq_ary(expd, mgr.Free_ary(), "mgr.Free_ary()");}
|
||||
public void Test__free__len(int expd) {Tfds.Eq(expd, mgr.Free_len(), "mgr.Free_len()");}
|
||||
public void Test__pool__len(int expd) {Tfds.Eq(expd, mgr.Pool_len(), "mgr.Pool_len()");}
|
||||
public void Test__pool__nxt(int expd) {Tfds.Eq(expd, mgr.Pool_nxt(), "mgr.Pool_nxt()");}
|
||||
public void Exec__rls(int idx) {mgr.Rls_fast(idx);}
|
||||
}
|
||||
class Sample_poolable_itm implements Gfo_poolable_itm {
|
||||
private Gfo_poolable_mgr pool_mgr;
|
||||
public Sample_poolable_itm(Gfo_poolable_mgr pool_mgr, int pool_idx, Object[] make_args) {this.pool_mgr = pool_mgr; this.pool_idx = pool_idx; this.pool__make_args = make_args;}
|
||||
public int Pool__idx() {return pool_idx;} private final int pool_idx;
|
||||
public Object[] Pool__make_args() {return pool__make_args;} private final Object[] pool__make_args;
|
||||
public void Pool__rls() {pool_mgr.Rls_safe(pool_idx);}
|
||||
public Gfo_poolable_itm Pool__make (Gfo_poolable_mgr mgr, int idx, Object[] args) {return new Sample_poolable_itm(pool_mgr, idx, args);}
|
||||
}
|
||||
Reference in New Issue
Block a user