mirror of https://github.com/gnosygnu/xowa
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
4.7 KiB
132 lines
4.7 KiB
/*
|
|
XOWA: the XOWA Offline Wiki Application
|
|
Copyright (C) 2012-2021 gnosygnu@gmail.com
|
|
|
|
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
|
or alternatively under the terms of the Apache License Version 2.0.
|
|
|
|
You may use XOWA according to either of these licenses as is most appropriate
|
|
for your project on a case-by-case basis.
|
|
|
|
The terms of each license can be found in the source code repository:
|
|
|
|
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
|
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
|
*/
|
|
package gplx.core.btries;
|
|
import gplx.types.basics.utls.ArrayUtl;
|
|
public class Btrie_slim_itm {
|
|
private Btrie_slim_itm[] ary = Btrie_slim_itm.Ary_empty;
|
|
public Btrie_slim_itm(byte key_byte, Object val, boolean case_any) {this.key_byte = key_byte; this.val = val; this.case_any = case_any;}
|
|
public byte Key_byte() {return key_byte;} private byte key_byte;
|
|
public Object Val() {return val;} public void Val_set(Object val) {this.val = val;} private Object val;
|
|
public boolean Case_any() {return case_any;} private boolean case_any;
|
|
public boolean Ary_is_empty() {return ary == Btrie_slim_itm.Ary_empty;}
|
|
public void Clear() {
|
|
val = null;
|
|
for (int i = 0; i < ary_len; i++)
|
|
ary[i].Clear();
|
|
ary = Btrie_slim_itm.Ary_empty;
|
|
ary_len = ary_max = 0;
|
|
}
|
|
public Btrie_slim_itm Ary_find(byte b) {
|
|
int find_val = (case_any && (b > 64 && b < 91) ? b + 32 : b) & 0xff;// PATCH.JAVA:need to convert to unsigned byte
|
|
int key_val = 0;
|
|
switch (ary_len) {
|
|
case 0: return null;
|
|
case 1:
|
|
Btrie_slim_itm rv = ary[0];
|
|
key_val = rv.Key_byte() & 0xff;// PATCH.JAVA:need to convert to unsigned byte;
|
|
key_val = (case_any && (key_val > 64 && key_val < 91) ? key_val + 32 : key_val);
|
|
return key_val == find_val ? rv : null;
|
|
default:
|
|
int adj = 1;
|
|
int prv_pos = 0;
|
|
int prv_len = ary_len;
|
|
int cur_len = 0;
|
|
int cur_idx = 0;
|
|
Btrie_slim_itm itm = null;
|
|
while (true) {
|
|
cur_len = prv_len / 2;
|
|
if (prv_len % 2 == 1) ++cur_len;
|
|
cur_idx = prv_pos + (cur_len * adj);
|
|
if (cur_idx < 0) cur_idx = 0;
|
|
else if (cur_idx >= ary_len) cur_idx = ary_len - 1;
|
|
itm = ary[cur_idx];
|
|
key_val = itm.Key_byte() & 0xff; // PATCH.JAVA:need to convert to unsigned byte;
|
|
key_val = (case_any && (key_val > 64 && key_val < 91) ? key_val + 32 : key_val);
|
|
if (find_val < key_val) adj = -1;
|
|
else if (find_val > key_val) adj = 1;
|
|
else /*(find_val == cur_val)*/ return itm;
|
|
if (cur_len == 1) {
|
|
cur_idx += adj;
|
|
if (cur_idx < 0 || cur_idx >= ary_len) return null;
|
|
itm = ary[cur_idx];
|
|
return (itm.Key_byte() & 0xff) == find_val ? itm : null; // PATCH.JAVA:need to convert to unsigned byte;
|
|
}
|
|
prv_len = cur_len;
|
|
prv_pos = cur_idx;
|
|
}
|
|
}
|
|
}
|
|
public Btrie_slim_itm Ary_add(byte b, Object val) {
|
|
int new_len = ary_len + 1;
|
|
if (new_len > ary_max) {
|
|
ary_max += 4;
|
|
ary = (Btrie_slim_itm[])ArrayUtl.Resize(ary, ary_max);
|
|
}
|
|
Btrie_slim_itm rv = new Btrie_slim_itm(b, val, case_any);
|
|
ary[ary_len] = rv;
|
|
ary_len = new_len;
|
|
synchronized (ByteHashItm_sorter.Instance) {// TS: DATE:2016-07-06
|
|
ByteHashItm_sorter.Instance.Sort(ary, ary_len);
|
|
}
|
|
return rv;
|
|
}
|
|
public void Ary_del(byte b) {
|
|
boolean found = false;
|
|
for (int i = 0; i < ary_len; i++) {
|
|
if (found) {
|
|
if (i < ary_len - 1)
|
|
ary[i] = ary[i + 1];
|
|
}
|
|
else {
|
|
if (b == ary[i].Key_byte()) found = true;
|
|
}
|
|
}
|
|
if (found) --ary_len;
|
|
}
|
|
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;
|
|
public void Sort(Btrie_slim_itm[] ary, int ary_len) {
|
|
if (ary == null || ary_len < 2) return;
|
|
this.ary = ary;
|
|
this.ary_len = ary_len;
|
|
Sort_recurse(0, ary_len - 1);
|
|
}
|
|
private void Sort_recurse(int lo, int hi) {
|
|
int i = lo, j = hi;
|
|
int mid = ary[lo + (hi-lo)/2].Key_byte()& 0xFF; // get mid itm
|
|
while (i <= j) { // divide into two lists
|
|
while ((ary[i].Key_byte() & 0xFF) < mid) // if lhs.cur < mid, then get next from lhs
|
|
i++;
|
|
while ((ary[j].Key_byte() & 0xFF) > mid) // if rhs.cur > mid, then get next from rhs
|
|
j--;
|
|
|
|
// lhs.cur > mid && rhs.cur < mid; switch lhs.cur and rhs.cur; increase i and j
|
|
if (i <= j) {
|
|
Btrie_slim_itm tmp = ary[i];
|
|
ary[i] = ary[j];
|
|
ary[j] = tmp;
|
|
i++;
|
|
j--;
|
|
}
|
|
}
|
|
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() {}
|
|
}
|