From ef98466f666072746af72a45a40274110990f8bd Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Wed, 8 Apr 2020 14:27:39 +0200 Subject: [PATCH] fix library caching issues and change get-by-source, by-author.. into result-list --- .../nikiroo/fanfix/library/BasicLibrary.java | 53 +------- .../nikiroo/fanfix/library/CacheLibrary.java | 119 ++++++++++++------ .../nikiroo/fanfix/library/LocalLibrary.java | 4 +- .../nikiroo/fanfix/library/RemoteLibrary.java | 2 +- .../nikiroo/fanfix/reader/cli/CliReader.java | 2 +- .../reader/tui/TuiReaderMainWindow.java | 6 +- .../fanfix/reader/ui/GuiReaderBookInfo.java | 10 +- .../fanfix/reader/ui/GuiReaderMainPanel.java | 8 +- src/be/nikiroo/fanfix/test/LibraryTest.java | 36 +++--- 9 files changed, 122 insertions(+), 118 deletions(-) diff --git a/src/be/nikiroo/fanfix/library/BasicLibrary.java b/src/be/nikiroo/fanfix/library/BasicLibrary.java index c6ce22dd..c2ab12b7 100644 --- a/src/be/nikiroo/fanfix/library/BasicLibrary.java +++ b/src/be/nikiroo/fanfix/library/BasicLibrary.java @@ -149,7 +149,7 @@ abstract public class BasicLibrary { return custom; } - List metas = getListBySource(source); + List metas = getList().filter(source, null, null); if (metas.size() > 0) { return getCover(metas.get(0).getLuid()); } @@ -177,7 +177,7 @@ abstract public class BasicLibrary { return custom; } - List metas = getListByAuthor(author); + List metas = getList().filter(null, author, null); if (metas.size() > 0) { return getCover(metas.get(0).getLuid()); } @@ -338,7 +338,7 @@ abstract public class BasicLibrary { * @param pg * the optional progress reporter */ - public void refresh(Progress pg) { + public synchronized void refresh(Progress pg) { try { getMetas(pg); } catch (IOException e) { @@ -597,49 +597,8 @@ abstract public class BasicLibrary { * @throws IOException * in case of IOException */ - public synchronized List getList() throws IOException { - return getMetas(null); - } - - /** - * List all the stories of the given source type in the {@link BasicLibrary} , - * or all the stories if NULL is passed as a type. - *

- * Cover images not included. - * - * @param source the type of story to retrieve, or NULL for all - * - * @return the stories - * - * @throws IOException in case of IOException - * - * @deprecated use {@link BasicLibrary#getList(Progress)} and - * {@link MetaResultList#filter(String, String, String)} - */ - @Deprecated - public synchronized List getListBySource(String source) throws IOException { - return getList(null).filter(source, null, null); - } - - /** - * List all the stories of the given author in the {@link BasicLibrary}, or - * all the stories if NULL is passed as an author. - *

- * Cover images not included. - * - * @param author - * the author of the stories to retrieve, or NULL for all - * - * @return the stories - * - * @throws IOException - * in case of IOException - * - * @deprecated use {@link BasicLibrary#getList(Progress)} and - * {@link MetaResultList#filter(String, String, String)} - */ - public synchronized List getListByAuthor(String author) throws IOException { - return getList(null).filter(null, author, null); + public MetaResultList getList() throws IOException { + return getList(null); } /** @@ -1058,8 +1017,6 @@ abstract public class BasicLibrary { meta.setTitle(newTitle); meta.setAuthor(newAuthor); saveMeta(meta, pg); - - invalidateInfo(luid); } /** diff --git a/src/be/nikiroo/fanfix/library/CacheLibrary.java b/src/be/nikiroo/fanfix/library/CacheLibrary.java index 9c83e62f..694f9ec2 100644 --- a/src/be/nikiroo/fanfix/library/CacheLibrary.java +++ b/src/be/nikiroo/fanfix/library/CacheLibrary.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.List; +import java.util.TreeSet; import be.nikiroo.fanfix.Instance; import be.nikiroo.fanfix.bundles.UiConfig; @@ -21,7 +22,8 @@ import be.nikiroo.utils.Progress; * @author niki */ public class CacheLibrary extends BasicLibrary { - private List metas; + private List metasReal; + private List metasMixed; private BasicLibrary lib; private LocalLibrary cacheLib; @@ -54,32 +56,37 @@ public class CacheLibrary extends BasicLibrary { } @Override - protected List getMetas(Progress pg) throws IOException { + protected synchronized List getMetas(Progress pg) throws IOException { + // We make sure that cached metas have precedence + if (pg == null) { pg = new Progress(); } - if (metas == null) { - metas = lib.getMetas(pg); + if (metasMixed == null) { + if (metasReal == null) { + metasReal = lib.getMetas(pg); + } + + metasMixed = new ArrayList(); + TreeSet cachedLuids = new TreeSet(); + for (MetaData cachedMeta : cacheLib.getMetas(null)) { + metasMixed.add(cachedMeta); + cachedLuids.add(cachedMeta.getLuid()); + } + for (MetaData realMeta : metasReal) { + if (!cachedLuids.contains(realMeta.getLuid())) { + metasMixed.add(realMeta); + } + } } pg.done(); - return new ArrayList(metas); - } - - @Override - public synchronized MetaData getInfo(String luid) throws IOException { - MetaData info = cacheLib.getInfo(luid); - if (info == null) { - info = lib.getInfo(luid); - } - - return info; + return new ArrayList(metasMixed); } @Override - public synchronized Story getStory(String luid, MetaData meta, Progress pg) - throws IOException { + public synchronized Story getStory(String luid, MetaData meta, Progress pg) throws IOException { if (pg == null) { pg = new Progress(); } @@ -94,7 +101,7 @@ public class CacheLibrary extends BasicLibrary { if (!isCached(luid)) { try { cacheLib.imprt(lib, luid, pgImport); - updateInfo(cacheLib.getInfo(luid)); + updateMetaCache(metasMixed, cacheLib.getInfo(luid)); pgImport.done(); } catch (IOException e) { Instance.getInstance().getTraceHandler().error(e); @@ -112,8 +119,7 @@ public class CacheLibrary extends BasicLibrary { } @Override - public synchronized File getFile(final String luid, Progress pg) - throws IOException { + public synchronized File getFile(final String luid, Progress pg) throws IOException { if (pg == null) { pg = new Progress(); } @@ -215,8 +221,29 @@ public class CacheLibrary extends BasicLibrary { cacheLib.setAuthorCover(author, getCover(luid)); } + /** + * Invalidate the {@link Story} cache (when the content has changed, but we + * already have it) with the new given meta. + *

+ * Make sure to always use {@link MetaData} from the cached library + * in priority, here. + * + * @param meta + * the {@link Story} to clear from the cache + * + * @throws IOException + * in case of IOException + */ @Override + @Deprecated protected void updateInfo(MetaData meta) throws IOException { + throw new IOException( + "This method is not supported in a CacheLibrary, please use updateMetaCache"); + } + + // relplace the meta in Metas by Meta, add it if needed + // return TRUE = added + private boolean updateMetaCache(List metas, MetaData meta) { if (meta != null && metas != null) { boolean changed = false; for (int i = 0; i < metas.size(); i++) { @@ -228,32 +255,40 @@ public class CacheLibrary extends BasicLibrary { if (!changed) { metas.add(meta); + return true; } } - - cacheLib.updateInfo(meta); - lib.updateInfo(meta); + + return false; } @Override protected void invalidateInfo(String luid) { if (luid == null) { - metas = null; - } else if (metas != null) { + metasReal = null; + metasMixed = null; + } else { + invalidateInfo(metasReal, luid); + invalidateInfo(metasMixed, luid); + } + + cacheLib.invalidateInfo(luid); + lib.invalidateInfo(luid); + } + + // luid cannot be null + private void invalidateInfo(List metas, String luid) { + if (metas != null) { for (int i = 0; i < metas.size(); i++) { if (metas.get(i).getLuid().equals(luid)) { metas.remove(i--); } } } - - cacheLib.invalidateInfo(luid); - lib.invalidateInfo(luid); } @Override - public synchronized Story save(Story story, String luid, Progress pg) - throws IOException { + public synchronized Story save(Story story, String luid, Progress pg) throws IOException { Progress pgLib = new Progress(); Progress pgCacheLib = new Progress(); @@ -266,9 +301,10 @@ public class CacheLibrary extends BasicLibrary { pg.addProgress(pgCacheLib, 1); story = lib.save(story, luid, pgLib); + updateMetaCache(metasReal, story.getMeta()); + story = cacheLib.save(story, story.getMeta().getLuid(), pgCacheLib); - - updateInfo(story.getMeta()); + updateMetaCache(metasMixed, story.getMeta()); return story; } @@ -284,8 +320,8 @@ public class CacheLibrary extends BasicLibrary { } @Override - protected synchronized void changeSTA(String luid, String newSource, - String newTitle, String newAuthor, Progress pg) throws IOException { + protected synchronized void changeSTA(String luid, String newSource, String newTitle, String newAuthor, Progress pg) + throws IOException { if (pg == null) { pg = new Progress(); } @@ -314,7 +350,12 @@ public class CacheLibrary extends BasicLibrary { meta.setAuthor(newAuthor); pg.done(); - invalidateInfo(luid); + if (isCached(luid)) { + updateMetaCache(metasMixed, meta); + updateMetaCache(metasReal, lib.getInfo(luid)); + } else { + updateMetaCache(metasReal, meta); + } } @Override @@ -334,7 +375,7 @@ public class CacheLibrary extends BasicLibrary { } @Override - public MetaData imprt(URL url, Progress pg) throws IOException { + public synchronized MetaData imprt(URL url, Progress pg) throws IOException { if (pg == null) { pg = new Progress(); } @@ -346,10 +387,10 @@ public class CacheLibrary extends BasicLibrary { pg.addProgress(pgCache, 3); MetaData meta = lib.imprt(url, pgImprt); - updateInfo(meta); - + updateMetaCache(metasReal, meta); + metasMixed = null; clearFromCache(meta.getLuid()); - + pg.done(); return meta; } diff --git a/src/be/nikiroo/fanfix/library/LocalLibrary.java b/src/be/nikiroo/fanfix/library/LocalLibrary.java index c99a0fbe..80d216b8 100644 --- a/src/be/nikiroo/fanfix/library/LocalLibrary.java +++ b/src/be/nikiroo/fanfix/library/LocalLibrary.java @@ -98,7 +98,7 @@ public class LocalLibrary extends BasicLibrary { } @Override - protected List getMetas(Progress pg) { + protected synchronized List getMetas(Progress pg) { return new ArrayList(getStories(pg).keySet()); } @@ -214,7 +214,7 @@ public class LocalLibrary extends BasicLibrary { } } - invalidateInfo(); + updateInfo(meta); } @Override diff --git a/src/be/nikiroo/fanfix/library/RemoteLibrary.java b/src/be/nikiroo/fanfix/library/RemoteLibrary.java index c2774f93..65be7b17 100644 --- a/src/be/nikiroo/fanfix/library/RemoteLibrary.java +++ b/src/be/nikiroo/fanfix/library/RemoteLibrary.java @@ -459,7 +459,7 @@ public class RemoteLibrary extends BasicLibrary { } @Override - protected List getMetas(Progress pg) throws IOException { + protected synchronized List getMetas(Progress pg) throws IOException { return getMetasList("*", pg); } diff --git a/src/be/nikiroo/fanfix/reader/cli/CliReader.java b/src/be/nikiroo/fanfix/reader/cli/CliReader.java index 55605214..235276c8 100644 --- a/src/be/nikiroo/fanfix/reader/cli/CliReader.java +++ b/src/be/nikiroo/fanfix/reader/cli/CliReader.java @@ -85,7 +85,7 @@ class CliReader extends BasicReader { @Override public void browse(String source) throws IOException { - List stories = getLibrary().getListBySource(source); + List stories = getLibrary().getList().filter(source, null, null); for (MetaData story : stories) { String author = ""; diff --git a/src/be/nikiroo/fanfix/reader/tui/TuiReaderMainWindow.java b/src/be/nikiroo/fanfix/reader/tui/TuiReaderMainWindow.java index b1ebcc2e..2ee319ab 100644 --- a/src/be/nikiroo/fanfix/reader/tui/TuiReaderMainWindow.java +++ b/src/be/nikiroo/fanfix/reader/tui/TuiReaderMainWindow.java @@ -243,11 +243,11 @@ class TuiReaderMainWindow extends TWindow { try { if (mode == Mode.SOURCE) { - metas = reader.getLibrary().getListBySource(target); + metas = reader.getLibrary().getList().filter(target, null, null); } else if (mode == Mode.AUTHOR) { - metas = reader.getLibrary().getListByAuthor(target); + metas = reader.getLibrary().getList().filter(null, target, null); } else { - metas = reader.getLibrary().getList(); + metas = reader.getLibrary().getList().getMetas(); } } catch (IOException e) { Instance.getInstance().getTraceHandler().error(e); diff --git a/src/be/nikiroo/fanfix/reader/ui/GuiReaderBookInfo.java b/src/be/nikiroo/fanfix/reader/ui/GuiReaderBookInfo.java index c163834f..3cef8cfd 100644 --- a/src/be/nikiroo/fanfix/reader/ui/GuiReaderBookInfo.java +++ b/src/be/nikiroo/fanfix/reader/ui/GuiReaderBookInfo.java @@ -17,6 +17,12 @@ import be.nikiroo.utils.StringUtils; * @author niki */ public class GuiReaderBookInfo { + /** + * The type of {@link GuiReaderBook} (i.e., related to a story or to something else that + * can encompass stories). + * + * @author niki + */ public enum Type { /** A normal story, which can be "read". */ STORY, @@ -207,7 +213,7 @@ public class GuiReaderBookInfo { int size = 0; try { - size = lib.getListBySource(source).size(); + size = lib.getList().filter(source, null, null).size(); } catch (IOException e) { } @@ -237,7 +243,7 @@ public class GuiReaderBookInfo { int size = 0; try { - size = lib.getListByAuthor(author).size(); + size = lib.getList().filter(null, author, null).size(); } catch (IOException e) { } diff --git a/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java b/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java index 2843a051..a5eb6916 100644 --- a/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java +++ b/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java @@ -363,9 +363,9 @@ class GuiReaderMainPanel extends JPanel { List metas; try { if (currentType) { - metas = lib.getListBySource(value); + metas = lib.getList().filter(value, null, null); } else { - metas = lib.getListByAuthor(value); + metas = lib.getList().filter(null, value, null); } } catch (IOException e) { error(e.getLocalizedMessage(), "IOException", e); @@ -431,13 +431,13 @@ class GuiReaderMainPanel extends JPanel { break; case SOURCE: for (MetaData meta : helper.getReader().getLibrary() - .getListBySource(book.getInfo().getMainInfo())) { + .getList().filter(book.getInfo().getMainInfo(), null, null)) { luids.add(meta.getLuid()); } break; case AUTHOR: for (MetaData meta : helper.getReader().getLibrary() - .getListByAuthor(book.getInfo().getMainInfo())) { + .getList().filter(null, book.getInfo().getMainInfo(), null)) { luids.add(meta.getLuid()); } break; diff --git a/src/be/nikiroo/fanfix/test/LibraryTest.java b/src/be/nikiroo/fanfix/test/LibraryTest.java index cf85b71e..da44438d 100644 --- a/src/be/nikiroo/fanfix/test/LibraryTest.java +++ b/src/be/nikiroo/fanfix/test/LibraryTest.java @@ -43,7 +43,7 @@ class LibraryTest extends TestLauncher { addTest(new TestCase("getList") { @Override public void test() throws Exception { - List metas = lib.getList(); + List metas = lib.getList().getMetas(); assertEquals(errMess, Arrays.asList(), titlesAsList(metas)); } @@ -55,7 +55,7 @@ class LibraryTest extends TestLauncher { lib.save(story(luid1, name1, source1, author1), luid1, null); - List metas = lib.getList(); + List metas = lib.getList().getMetas(); assertEquals(errMess, Arrays.asList(name1), titlesAsList(metas)); } @@ -69,14 +69,14 @@ class LibraryTest extends TestLauncher { lib.save(story(luid2, name2, source2, author1), luid2, null); - metas = lib.getList(); + metas = lib.getList().getMetas(); assertEquals(errMess, Arrays.asList(name1, name2), titlesAsList(metas)); lib.save(story(luid3, name3, source2, author1), luid3, null); - metas = lib.getList(); + metas = lib.getList().getMetas(); assertEquals(errMess, Arrays.asList(name1, name2, name3), titlesAsList(metas)); @@ -90,7 +90,7 @@ class LibraryTest extends TestLauncher { lib.save(story(luid3, name3ex, source2, author2), luid3, null); - List metas = lib.getList(); + List metas = lib.getList().getMetas(); assertEquals(errMess, Arrays.asList(name1, name2, name3ex), titlesAsList(metas)); @@ -100,7 +100,7 @@ class LibraryTest extends TestLauncher { addTest(new TestCase("getList with results") { @Override public void test() throws Exception { - List metas = lib.getList(); + List metas = lib.getList().getMetas(); assertEquals(3, metas.size()); } }); @@ -110,13 +110,13 @@ class LibraryTest extends TestLauncher { public void test() throws Exception { List metas = null; - metas = lib.getListBySource(source1); + metas = lib.getList().filter(source1, null, null); assertEquals(1, metas.size()); - metas = lib.getListBySource(source2); + metas = lib.getList().filter(source2, null, null); assertEquals(2, metas.size()); - metas = lib.getListBySource(null); + metas = lib.getList().filter((String)null, null, null); assertEquals(3, metas.size()); } }); @@ -126,13 +126,13 @@ class LibraryTest extends TestLauncher { public void test() throws Exception { List metas = null; - metas = lib.getListByAuthor(author1); + metas = lib.getList().filter(null, author1, null); assertEquals(2, metas.size()); - metas = lib.getListByAuthor(author2); + metas = lib.getList().filter(null, author2, null); assertEquals(1, metas.size()); - metas = lib.getListByAuthor(null); + metas = lib.getList().filter((String)null, null, null); assertEquals(3, metas.size()); } }); @@ -144,13 +144,13 @@ class LibraryTest extends TestLauncher { lib.changeSource(luid3, source1, null); - metas = lib.getListBySource(source1); + metas = lib.getList().filter(source1, null, null); assertEquals(2, metas.size()); - metas = lib.getListBySource(source2); + metas = lib.getList().filter(source2, null, null); assertEquals(1, metas.size()); - metas = lib.getListBySource(null); + metas = lib.getList().filter((String)null, null, null); assertEquals(3, metas.size()); } }); @@ -164,13 +164,13 @@ class LibraryTest extends TestLauncher { lib.save(story(luid3, "My story 3", source2, author2), luid3, null); - metas = lib.getListBySource(source1); + metas = lib.getList().filter(source1, null, null); assertEquals(1, metas.size()); - metas = lib.getListBySource(source2); + metas = lib.getList().filter(source2, null, null); assertEquals(2, metas.size()); - metas = lib.getListBySource(null); + metas = lib.getList().filter((String)null, null, null); assertEquals(3, metas.size()); } }); -- 2.27.0