@Override public Set<Subscription> loadByTopic(final String topicQuery) { final Set<String> topicSubQueries = decomposeTopicQuery(topicQuery); final Map<String, Optional<Subscription>> cachedResults = subscriptionCache.loadTopicSubscriptions(topicSubQueries); final Set<Subscription> result = new HashSet<Subscription>(); // Iterate through the results from the cache, and remove any topics // that were found from the list of topics left to query, and add // the non-null subscriptions to the list of results for (String topic : cachedResults.keySet()) { if (cachedResults.get(topic).isPresent()) { result.add(cachedResults.get(topic).get()); topicSubQueries.remove(topic); } } // all topics that are found in the cache will be removed, so if no // topic subqueries are left, we are done if (!topicSubQueries.isEmpty()) { Collection<Subscription> dbResults = dbi.withHandle( new HandleCallback<Collection<Subscription>>() { @Override public Collection<Subscription> withHandle(Handle handle) throws Exception { final Set<Subscription> dbResult = new HashSet<Subscription>(); InClauseExpander in = new InClauseExpander(topicSubQueries); Iterator<Subscription> subscriptionsIter = handle .createQuery( "select id, metadata, channel, topic from subscriptions where topic in (" + in.getExpansion() + ")") .bindNamedArgumentFinder(in) .map(new SubscriptionMapper()) .iterator(); if (subscriptionsIter != null) { while (subscriptionsIter.hasNext()) { Subscription dbSubscription = subscriptionsIter.next(); dbResult.add(dbSubscription); subscriptionCache.addTopicSubscriptions( dbSubscription.getTopic(), Optional.of(dbSubscription)); topicSubQueries.remove(dbSubscription.getTopic()); } } return dbResult; } }); // Add the database results to the results from the cache result.addAll(dbResults); // Add empty subscriptions to the cache if (!topicSubQueries.isEmpty()) { subscriptionCache.addEmptyTopicSubscriptions(topicSubQueries); } } return ImmutableSet.copyOf(result); }