/** * This method searches across multiple indexes and combines the answers. Create the business * object and only initialize the attributes you want to actually use in the query. You can AND or * OR all these attributes. * * @param criteria A business object with only attributes in the query set. Others must be null * @param isAND TRUE if results are to be ANDed otherwise the results are ORed * @return The list of keys for the matching entries @See TestSubstringIndex */ public SearchResult<RK> searchMultipleIndexes(A criteria, boolean isAND) { try { Set<ByteArrayKey> result = null; // first run the individual queries for each attribute in parallel Collection<Future<SearchResult<byte[]>>> threads = new ArrayList<Future<SearchResult<byte[]>>>(); for (Field f : indexedFields) { final String value = (String) f.get(criteria); // non null field means it's in the query if (value != null) { final Index<A, RK> index = getIndex(f.getName()); Callable<SearchResult<byte[]>> c = new Callable<SearchResult<byte[]>>() { public SearchResult<byte[]> call() { SearchResult<byte[]> r = index.rawContains(value); return r; } }; Future<SearchResult<byte[]>> future = utils.getExecutorService().submit(c); threads.add(future); } } // the collect the results and AND/OR them for (Future<SearchResult<byte[]>> future : threads) { SearchResult<byte[]> r = future.get(); if (!r.isTooManyMatches()) { Collection<ByteArrayKey> rr = convertToKeys(r.getResults()); if (result == null) result = new HashSet<ByteArrayKey>(rr); else if (isAND) { // AND this index match with the current running results LinkedList<ByteArrayKey> removeList = new LinkedList<ByteArrayKey>(); for (ByteArrayKey k : rr) { if (!result.contains(k)) removeList.add(k); } for (ByteArrayKey k : result) { if (!rr.contains(k)) removeList.add(k); } result.removeAll(removeList); } else result.addAll(rr); } } if (result != null) { Map<ByteArrayKey, RK> rc = utils.getAll(result, utils.getObjectGrid().getMap(internalKeyToRealKeyMapName)); return new SearchResult<RK>(new ArrayList<RK>(rc.values())); } else return new SearchResult<RK>(); } catch (Exception e) { throw new ObjectGridRuntimeException(e); } }