From 879ef3a7d0a54d6fffba645485d84970889f0957 Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Thu, 23 Mar 2017 08:18:31 -0400 Subject: [PATCH] Full-text search: Clear cache if more than 8 entries --- 400_xowa/src/gplx/core/lists/Queue_adp.java | 53 +++++++++++++++++ .../src/gplx/core/lists/Queue_adp_tst.java | 59 +++++++++++++++++++ 400_xowa/src/gplx/core/lists/StatRng.java | 4 +- .../specials/Xofulltext_searcher_html.java | 4 +- .../svcs/Xofulltext_searcher_svc.java | 32 +++++++++- 5 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 400_xowa/src/gplx/core/lists/Queue_adp.java create mode 100644 400_xowa/src/gplx/core/lists/Queue_adp_tst.java diff --git a/400_xowa/src/gplx/core/lists/Queue_adp.java b/400_xowa/src/gplx/core/lists/Queue_adp.java new file mode 100644 index 000000000..94db92ebd --- /dev/null +++ b/400_xowa/src/gplx/core/lists/Queue_adp.java @@ -0,0 +1,53 @@ +/* +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; import gplx.*; import gplx.core.*; +public class Queue_adp { + private int count; + private Queue_itm head; + private Queue_itm tail; + public int Count() {return count;} + public boolean Is_empty() {return count == 0;} + public void Enqueue(Object data) { + Queue_itm item = new Queue_itm(data); + if (head == null) { + head = item; + } + if (tail != null) { + tail.next = item; + } + tail = item; + count++; + } + public Object Dequeue() { + Object rv = Peek(); + head = head.next; + count--; + return rv; + } + public Object Peek() { + if (head == null) throw Err_.new_wo_type("queue is empty"); + Queue_itm rv = head; + return rv.Data(); + } +} +class Queue_itm { + private final Object data; + public Queue_itm next; + public Queue_itm(Object data) { + this.data = data; + } + public Object Data() {return data;} +} diff --git a/400_xowa/src/gplx/core/lists/Queue_adp_tst.java b/400_xowa/src/gplx/core/lists/Queue_adp_tst.java new file mode 100644 index 000000000..7ddcea028 --- /dev/null +++ b/400_xowa/src/gplx/core/lists/Queue_adp_tst.java @@ -0,0 +1,59 @@ +/* +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; import gplx.*; import gplx.core.*; +import org.junit.*; import gplx.core.tests.*; +public class Queue_adp_tst { + private final Queue_adp_fxt fxt = new Queue_adp_fxt(); + @Test public void Empty() { + boolean pass = true; + try { + fxt.Test__dequeue(null, -1); + pass = false; + } catch (Exception e) { + Err_.Noop(e); + return; + } + if (pass) throw Err_.new_wo_type("empty should have failed"); + } + @Test public void Add_1() { + fxt.Exec__enqueue("a"); + fxt.Test__dequeue("a", 0); + } + @Test public void Add_n() { + fxt.Exec__enqueue("a"); + fxt.Exec__enqueue("b"); + fxt.Exec__enqueue("c"); + fxt.Test__dequeue("a", 2); + fxt.Test__dequeue("b", 1); + fxt.Test__dequeue("c", 0); + } + @Test public void Mix() { + fxt.Exec__enqueue("a"); + fxt.Exec__enqueue("b"); + fxt.Test__dequeue("a", 1); + fxt.Exec__enqueue("c"); + fxt.Test__dequeue("b", 1); + fxt.Test__dequeue("c", 0); + } +} +class Queue_adp_fxt { + private final Queue_adp queue = new Queue_adp(); + public void Exec__enqueue(String s) {queue.Enqueue(s);} + public void Test__dequeue(String expd_data, int expd_len) { + Gftest.Eq__str(expd_data, (String)queue.Dequeue()); + Gftest.Eq__int(expd_len , queue.Count()); + } +} diff --git a/400_xowa/src/gplx/core/lists/StatRng.java b/400_xowa/src/gplx/core/lists/StatRng.java index eabc66c9b..e0fe5b792 100644 --- a/400_xowa/src/gplx/core/lists/StatRng.java +++ b/400_xowa/src/gplx/core/lists/StatRng.java @@ -61,10 +61,10 @@ class StatRng { public long Sum = 0; public int Count = 0; public float Avg() {return Sum / Count;} - public final StatItm[] Lo_ary; + public final StatItm[] Lo_ary; public int Lo_ary_bound; public int Lo_ary_len; - public final StatItm[] Hi_ary; + public final StatItm[] Hi_ary; public int Hi_ary_bound; public int Hi_ary_len; public StatRng[] Slot_ary; diff --git a/400_xowa/src/gplx/xowa/addons/wikis/fulltexts/searchers/specials/Xofulltext_searcher_html.java b/400_xowa/src/gplx/xowa/addons/wikis/fulltexts/searchers/specials/Xofulltext_searcher_html.java index e6f5ad112..5d4cedb78 100644 --- a/400_xowa/src/gplx/xowa/addons/wikis/fulltexts/searchers/specials/Xofulltext_searcher_html.java +++ b/400_xowa/src/gplx/xowa/addons/wikis/fulltexts/searchers/specials/Xofulltext_searcher_html.java @@ -22,9 +22,11 @@ class Xofulltext_searcher_html extends Xow_special_wtr__base implements Mustache private final boolean case_match, auto_wildcard_bgn, auto_wildcard_end, expand_matches_section, show_all_matches; private final Hash_adp props = Hash_adp_.New(); public Xofulltext_searcher_html(Xocfg_mgr cfg_mgr, Gfo_qarg_mgr url_args, Xow_wiki wiki, Guid_adp page_guid) { + String search_text = url_args.Read_str_or("search", ""); + search_text = String_.Replace(search_text, "_", " "); // xofulltext_searcher.js chains multiple words with "_"; convert back to space + props.Add("search", search_text); props.Add("page_guid", page_guid.To_str()); props.Add("cur_wiki", wiki.Domain_str()); - props.Add("search", url_args.Read_str_or("search", "")); props_Add(cfg_mgr, url_args, "wikis" , wiki.Domain_str()); props_Add(cfg_mgr, url_args, "ns_ids", "0"); props_Add(cfg_mgr, url_args, "limits", "100"); diff --git a/400_xowa/src/gplx/xowa/addons/wikis/fulltexts/searchers/svcs/Xofulltext_searcher_svc.java b/400_xowa/src/gplx/xowa/addons/wikis/fulltexts/searchers/svcs/Xofulltext_searcher_svc.java index 6264fff73..5f1d67548 100644 --- a/400_xowa/src/gplx/xowa/addons/wikis/fulltexts/searchers/svcs/Xofulltext_searcher_svc.java +++ b/400_xowa/src/gplx/xowa/addons/wikis/fulltexts/searchers/svcs/Xofulltext_searcher_svc.java @@ -29,7 +29,7 @@ import gplx.xowa.addons.wikis.fulltexts.searchers.mgrs.gflucenes.*; import gplx.xowa.addons.wikis.fulltexts.searchers.mgrs.brutes.*; class Xofulltext_searcher_svc implements Gfo_invk { private final Xoa_app app; - private final Hash_adp wkr_hash = Hash_adp_.New(); + private final Ordered_hash wkr_hash = Ordered_hash_.New(); public Xofulltext_searcher_svc(Xoa_app app) { this.app = app; } @@ -38,6 +38,31 @@ class Xofulltext_searcher_svc implements Gfo_invk { Xofulltext_args_qry prv_args = (Xofulltext_args_qry)wkr_hash.Get_by(page_guid); if (prv_args != null) { prv_args.Cancel(); + synchronized (wkr_hash) { + wkr_hash.Del(page_guid); + } + } + } + private static void Compress(Ordered_hash wkr_hash) { + int max = 2; + int len = wkr_hash.Len(); + if (len > max) { + synchronized (wkr_hash) { + // create list for deleted items; in general, this list will never be more than 1 + List_adp deleted = List_adp_.New(); + + int bgn = len - max; + for (int i = 0; i < bgn; i++) { + Xofulltext_args_qry args = (Xofulltext_args_qry)wkr_hash.Get_at(i); + deleted.Add(args); + } + + len = deleted.Len(); + for (int i = 0; i < len; i++) { + Xofulltext_args_qry args = (Xofulltext_args_qry)deleted.Get_at(i); + wkr_hash.Del(args.page_guid); + } + } } } public void Search(Json_nde args) { @@ -47,7 +72,10 @@ class Xofulltext_searcher_svc implements Gfo_invk { // cancel any existing searches this.Cancel(search_args.page_guid); - wkr_hash.Add(search_args.page_guid, search_args); + Compress(wkr_hash); + synchronized (wkr_hash) { + wkr_hash.Add(search_args.page_guid, search_args); + } // autosave any changes if enabled Xocfg_mgr cfg_mgr = app.Cfg();