@Override public boolean update(DatabaseDocument<T> d) { if (!cache.update(d)) { DatabaseDocument<T> doc = reader.getDocumentById(d.getID()); if (doc != null) { cache.add(doc); cache.update(d); } if (cache.getDocumentById(d.getID()) == null) { d.removeFetchedBy(CACHE_TAG); } return writer.update(d); } return true; }
@Override public DatabaseDocument<T> getDocument(DatabaseQuery<T> q) { DatabaseDocument<T> doc = cache.getDocument(q); if (doc == null) { doc = reader.getDocument(q); cache.add(doc); } return getCopy(doc); }
/** * Flushes all documents in the cache that have not been touched for the * specified number of milliseconds. */ public void flush(int staleTimeout) { Collection<DatabaseDocument<T>> docs = cache.removeStale(staleTimeout); if (docs.size() > 0) { logger.debug("Flushing " + docs.size() + " out of " + (docs.size() + cache.getSize()) + " documents from cache"); } for (DatabaseDocument<T> d : docs) { d.removeFetchedBy(CACHE_TAG); writer.update(d); } }
@Override public DatabaseDocument<T> getDocumentById(DocumentID<T> id) { DatabaseDocument<T> doc = cache.getDocumentById(id); if (doc == null) { doc = reader.getDocumentById(id, false); if(doc != null) { cache.add(doc); } else { return null; } } return getCopy(doc); }
@Override public boolean markProcessed(DatabaseDocument<T> d, String stage) { DatabaseDocument<T> cached = cache.getDocumentById(d.getID()); if (cached != null) { d.putAll(cached); cache.remove(d.getID()); } if (writer.markProcessed(d, stage)) { return true; } return false; }
@Override public Collection<DatabaseDocument<T>> getAndTag(DatabaseQuery<T> query, int n, String... tags) { Collection<DatabaseDocument<T>> list = new ArrayList<DatabaseDocument<T>>(); Collection<DatabaseDocument<T>> c = cache.getAndTag(query, n, tags); if (c != null) { list.addAll(c); } if (list.size() == 0) { for (String t : tags) { query.requireNotFetchedByStage(t); } list = writer.getAndTag(query, n, addCacheTag(tags)); for (DatabaseDocument<T> d : list) { for (String t : tags) { d.setFetchedBy(t, new Date()); } } cache.add(list); } return list; }
@Override public void deleteAll() { cache.removeAll(); writer.deleteAll(); }
@Override public void prepare() { writer.prepare(); cache.prepare(); }
/** * Since skip becomes impossible to calculate in a cached scenario, this * will simply query the underlying reader. */ @Override public List<DatabaseDocument<T>> getDocuments(DatabaseQuery<T> q, int limit, int skip) { List<DatabaseDocument<T>> docs = reader.getDocuments(q, limit, skip); cache.add(docs); return docs; }
@Override public DatabaseDocument<T> getDocumentById(DocumentID<T> id, boolean includeInactive) { DatabaseDocument<T> doc = getDocumentById(id); if (doc == null && includeInactive) { return reader.getDocumentById(id, includeInactive); } return cache.getDocumentById(id); }
@Override public void delete(DatabaseDocument<T> d) { cache.remove(d.getID()); writer.delete(d); }
@Override public boolean markTouched(DocumentID<T> id, String tag) { if (!cache.markTouched(id, tag)) { DatabaseDocument<T> d = reader.getDocumentById(id); if (d != null) { d.removeFetchedBy(CACHE_TAG); d.setTouchedBy(tag, new Date()); return writer.update(d); } return false; } return true; }
@Override public boolean markFailed(DatabaseDocument<T> d, String stage) { DatabaseDocument<T> cached = cache.getDocumentById(d.getID()); d.putAll(cached); cache.remove(d.getID()); if (writer.markFailed(d, stage)) { return true; } return false; }
@Override public DatabaseDocument<T> getAndTag(DatabaseQuery<T> query, String... tags) { DatabaseDocument<T> doc = cache.getAndTag(query, tags); if (doc == null) { for (String t : tags) { query.requireNotFetchedByStage(t); } doc = writer.getAndTag(query, addCacheTag(tags)); if (doc != null) { for (String t : tags) { doc.setFetchedBy(t, new Date()); } cache.add(doc); } } return getCopy(doc); }
/** * Flushes the cache back to the database */ public void flush() { Collection<DatabaseDocument<T>> docs = cache.removeAll(); for (DatabaseDocument<T> d : docs) { d.removeFetchedBy(CACHE_TAG); writer.update(d); } }
@Override public boolean markDiscarded(DatabaseDocument<T> d, String stage) { DatabaseDocument<T> cached = cache.getDocumentById(d.getID()); d.putAll(cached); cache.remove(d.getID()); if (writer.markDiscarded(d, stage)) { return true; } return false; }
/** * If there is any documents in the cache matching the query, those are * returned, otherwise a direct call is made to the underlying reader. * * As such, this may return 1 document (if one is found in the cache) even * though there are thousands of documents in the underlying database that * match. */ @Override public List<DatabaseDocument<T>> getDocuments(DatabaseQuery<T> q, int limit) { List<DatabaseDocument<T>> docs = new ArrayList<DatabaseDocument<T>>(); docs.addAll(cache.getDocument(q, limit)); if (docs.size() == 0) { docs = reader.getDocuments(q, limit); cache.add(docs); } return docs; }
@Override public boolean markPending(DatabaseDocument<T> d, String stage) { DatabaseDocument<T> cached = cache.getDocumentById(d.getID()); d.putAll(cached); cache.remove(d.getID()); return writer.markPending(d, stage); }