1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

Sqlite: Add option for read-only detection [#509]

This commit is contained in:
gnosygnu
2019-07-19 07:14:24 -04:00
parent 7f76d8128d
commit 989ccde83a
28 changed files with 669 additions and 168 deletions

View File

@@ -20,11 +20,11 @@ public class Gfo_cache_mgr_base {
public int Compress_to() {return compress_to;} public void Compress_to_(int v) {compress_to = v;} private int compress_to = 8;
protected Object Base_get_or_null(byte[] key) {
Object rv_obj = hash.Get_by(key);
return rv_obj == null ? null : ((Gfo_cache_itm)rv_obj).Val();
return rv_obj == null ? null : ((Gfo_cache_itm_bry)rv_obj).Val();
}
protected void Base_add(byte[] key, Object val) {
if (hash.Count() >= compress_max) Compress();
Gfo_cache_itm itm = new Gfo_cache_itm(key, val);
Gfo_cache_itm_bry itm = new Gfo_cache_itm_bry(key, val);
hash.Add(key, itm);
}
protected void Base_del(byte[] key) {
@@ -35,11 +35,11 @@ public class Gfo_cache_mgr_base {
int del_len = hash.Count() - compress_to;
List_adp del_list = List_adp_.New();
for (int i = 0; i < del_len; i++) {
Gfo_cache_itm itm = (Gfo_cache_itm)hash.Get_at(i);
Gfo_cache_itm_bry itm = (Gfo_cache_itm_bry)hash.Get_at(i);
del_list.Add(itm);
}
for (int i = 0; i < del_len; i++) {
Gfo_cache_itm itm = (Gfo_cache_itm)del_list.Get_at(i);
Gfo_cache_itm_bry itm = (Gfo_cache_itm_bry)del_list.Get_at(i);
hash.Del(itm.Key());
}
}

View File

@@ -20,17 +20,17 @@ public class Gfo_cache_mgr_bry extends Gfo_cache_mgr_base {
public void Add(byte[] key, Object val) {Base_add(key, val);}
public void Del(byte[] key) {Base_del(key);}
}
class Gfo_cache_itm {
public Gfo_cache_itm(Object key, Object val) {this.key = key; this.val = val; this.Touched_update();}
class Gfo_cache_itm_bry {
public Gfo_cache_itm_bry(Object key, Object val) {this.key = key; this.val = val; this.Touched_update();}
public Object Key() {return key;} private Object key;
public Object Val() {return val;} private Object val;
public long Touched() {return touched;} private long touched;
public Gfo_cache_itm Touched_update() {touched = System_.Ticks(); return this;}
public Gfo_cache_itm_bry Touched_update() {touched = System_.Ticks(); return this;}
}
class Gfo_cache_itm_comparer implements gplx.core.lists.ComparerAble {
public int compare(Object lhsObj, Object rhsObj) {
Gfo_cache_itm lhs = (Gfo_cache_itm)lhsObj;
Gfo_cache_itm rhs = (Gfo_cache_itm)rhsObj;
Gfo_cache_itm_bry lhs = (Gfo_cache_itm_bry)lhsObj;
Gfo_cache_itm_bry rhs = (Gfo_cache_itm_bry)rhsObj;
return Long_.Compare(lhs.Touched(), rhs.Touched());
}
public static final Gfo_cache_itm_comparer Touched_asc = new Gfo_cache_itm_comparer(); // TS.static

View File

@@ -1,117 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 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.lists.caches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
public class Lru_cache {
private final Hash_adp map = Hash_adp_.New();
private long max;
private long cur = 0;
private Lru_node head;
private Lru_node tail;
private long evicts;
public void Max_(long max) {
this.max = max;
}
public long Evicts() {return evicts;}
public long Cur() {return cur;}
public Object Get_or_null(Object key) {
Lru_node nde = (Lru_node)map.Get_by(key);
if (nde == null) {
return null;
}
Del_node_from_linked_list(nde);
Add_to_tail(nde);
return nde.Val();
}
public void Set(Object key, Object val, long size) {
Lru_node nde = (Lru_node)map.Get_by(key);
if (nde != null) {
nde.Val_(val);
Del_node_from_linked_list(nde);
Add_to_tail(nde);
}
else {
while (cur + size > max) {
Del_node_from_this(head);
evicts++;
}
nde = new Lru_node(key, val, size);
Add_to_tail(nde);
map.Add(key, nde);
cur += size;
}
}
public void Del(Object key) {
Lru_node nde = (Lru_node)map.Get_by(key);
if (nde != null) {
Del_node_from_this(nde);
}
}
public void Clear() {
map.Clear();
head = null;
tail = null;
cur = 0;
}
private void Del_node_from_this(Lru_node nde) {
map.Del(nde.Key());
cur -= nde.Size();
Del_node_from_linked_list(nde);
}
private void Del_node_from_linked_list(Lru_node nde) {
if (nde.Prv() == null)
head = nde.Nxt();
else
nde.Prv().Nxt_(nde.Nxt());
if (nde.Nxt() == null)
tail = nde.Prv();
else
nde.Nxt().Prv_(nde.Prv());
}
private void Add_to_tail(Lru_node nde) {
if (tail != null)
tail.Nxt_(nde);
nde.Prv_(tail);
nde.Nxt_(null);
tail = nde;
if (head == null)
head = tail;
}
}
class Lru_node {
private final Object key;
private Object val;
private final long size;
private Lru_node prv;
private Lru_node nxt;
public Lru_node(Object key, Object val, long size) {
this.key = key;
this.val = val;
this.size = size;
}
public Object Key() {return key;}
public Object Val() {return val;} public void Val_(Object v) {this.val = v;}
public long Size() {return size;}
public Lru_node Prv() {return prv;} public void Prv_(Lru_node v) {this.prv = v;}
public Lru_node Nxt() {return nxt;} public void Nxt_(Lru_node v) {this.nxt = v;}
}

View File

@@ -1,116 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 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.lists.caches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
import org.junit.*; import gplx.core.tests.*;
import gplx.xowa.wikis.data.tbls.*; import gplx.xowa.wikis.nss.*;
public class Lru_cache_tst {
private final Lru_cache_fxt fxt = new Lru_cache_fxt();
@Test public void Get_one() {
fxt.Init__max(10);
fxt.Exec__set("a", 5);
fxt.Test__get_y("a");
}
@Test public void Pop_one() {
fxt.Init__max(10);
fxt.Exec__set("a", 10);
fxt.Exec__set("b", 10);
fxt.Test__get_n("a");
fxt.Test__get_y("b");
}
@Test public void Add_many() {
fxt.Init__max(10);
fxt.Exec__set("a", 4);
fxt.Exec__set("b", 3);
fxt.Exec__set("c", 2);
fxt.Exec__set("d", 1);
fxt.Test__get_y("a", "b", "c", "d");
}
@Test public void Pop_many() {
fxt.Init__max(10);
fxt.Exec__set("a", 4);
fxt.Exec__set("b", 3);
fxt.Exec__set("c", 2);
fxt.Exec__set("d", 1);
fxt.Exec__set("e", 6);
fxt.Test__get_y("c", "d", "e");
fxt.Test__get_n("a", "b");
}
@Test public void Set_repeatedly() {
fxt.Init__max(10);
fxt.Exec__set("a", "a1", 10);
fxt.Exec__set("a", "a2", 10);
fxt.Exec__set("a", "a3", 10);
fxt.Test__get_val("a", "a3");
}
@Test public void Set_bumps_priority() {
fxt.Init__max(10);
fxt.Exec__set("a", 2);
fxt.Exec__set("b", 3);
fxt.Exec__set("c", 2);
fxt.Exec__set("a", 2);
fxt.Exec__set("d", 7);
fxt.Test__get_y("a", "d");
fxt.Test__get_n("b", "c");
}
@Test public void Del() {
fxt.Init__max(10);
fxt.Exec__set("a", 2);
fxt.Exec__set("b", 2);
fxt.Exec__del("b");
fxt.Test__get_y("a");
fxt.Test__get_n("b");
}
@Test public void Clear() {
fxt.Init__max(10);
fxt.Exec__set("a", 2);
fxt.Exec__set("b", 2);
fxt.Exec__clear();
fxt.Test__get_n("a", "b");
}
}
class Lru_cache_fxt {
private final Lru_cache cache = new Lru_cache();
public void Init__max(long max) {
cache.Max_(max);
}
public void Exec__set(String key, long size) {
cache.Set(key, key, size);
}
public void Exec__set(String key, String val, long size) {
cache.Set(key, val, size);
}
public void Exec__del(String key) {
cache.Del(key);
}
public void Exec__clear() {
cache.Clear();
}
public void Test__get_y(String... keys) {
for (String key : keys)
Test__get(key, key);
}
public void Test__get_n(String... keys) {
for (String key : keys)
Test__get(key, null);
}
public void Test__get_val(String key, String val) {
Test__get(key, val);
}
private void Test__get(String key, String expd) {
Object actl = cache.Get_or_null(key);
Gftest.Eq__obj_or_null(expd, actl);
}
}