+ AsyncReadEntry getOrCreateAsyncReadEntry(AsyncRead<?> r) throws DatabaseException {
+ AsyncReadEntry existing = null;
+ synchronized(asyncReadEntryMap) {
+ existing = (AsyncReadEntry)asyncReadEntryMap.get(r);
+ if(existing == null) {
+ existing = new AsyncReadEntry(r);
+ existing.clearResult(querySupport);
+ existing.setPending();
+ asyncReadEntryMap.put(id(r), existing);
+ return existing;
+ }
+ if(existing.requiresComputation()) {
+ existing.setPending();
+ return existing;
+ }
+ }
+ if(existing.isPending()) waitPending(existing);
+ return existing;
+ }
+
+ void remove(AsyncReadEntry entry) {
+ synchronized(asyncReadEntryMap) {
+ asyncReadEntryMap.remove(entry.request);
+ }
+ }
+
+ public static void runnerAsyncReadEntry(ReadGraphImpl graph, AsyncRead<?> r, CacheEntry parent, ListenerBase listener, AsyncProcedure procedure) throws DatabaseException {
+ if(parent == null && listener == null) {
+ AsyncReadEntry.computeForEach(graph, r, null, procedure);
+ return;
+ }
+ QueryCache cache = graph.processor.cache;
+ if(procedure == null) procedure = emptyProcedureAsyncReadEntry;
+ AsyncReadEntry entry = (AsyncReadEntry)cache.getOrCreateAsyncReadEntry(r);
+ ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false);
+ if(entry.isReady()) entry.performFromCache(graph, procedure);
+ else {
+ AsyncReadEntry.computeForEach(graph, r, entry, procedure);
+ if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+ }
+ }
+