Index: src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopier.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopier.java (revision 1688821) +++ src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopier.java (working copy) @@ -120,7 +120,7 @@ public Directory wrapForRead(String indexPath, IndexDefinition definition, Directory remote) throws IOException { Directory local = createLocalDirForIndexReader(indexPath, definition); - return new CopyOnReadDirectory(remote, local); + return new CopyOnReadDirectory(remote, local, indexPath); } public Directory wrapForWrite(IndexDefinition definition, Directory remote, boolean reindexMode) throws IOException { @@ -241,6 +241,7 @@ private class CopyOnReadDirectory extends FilterDirectory { private final Directory remote; private final Directory local; + private final String indexPath; private final ConcurrentMap files = newConcurrentMap(); /** @@ -249,10 +250,11 @@ */ private final Set localFileNames = Sets.newConcurrentHashSet(); - public CopyOnReadDirectory(Directory remote, Directory local) throws IOException { + public CopyOnReadDirectory(Directory remote, Directory local, String indexPath) throws IOException { super(remote); this.remote = remote; this.local = local; + this.indexPath = indexPath; this.localFileNames.addAll(Arrays.asList(local.listAll())); } @@ -269,15 +271,20 @@ @Override public IndexInput openInput(String name, IOContext context) throws IOException { if (REMOTE_ONLY.contains(name)) { + log.trace("[{}] opening remote only file {}", indexPath, name); return remote.openInput(name, context); } CORFileReference ref = files.get(name); if (ref != null) { if (ref.isLocalValid()) { + log.trace("[{}] opening existing local file {}", indexPath, name); return files.get(name).openLocalInput(context); } else { readerRemoteReadCount.incrementAndGet(); + log.trace( + "[{}] opening existing remote file as local version is not valid {}", + indexPath, name); return remote.openInput(name, context); } } @@ -285,14 +292,17 @@ CORFileReference toPut = new CORFileReference(name); CORFileReference old = files.putIfAbsent(name, toPut); if (old == null) { + log.trace("[{}] scheduled local copy for {}", indexPath, name); copy(toPut); } //If immediate executor is used the result would be ready right away if (toPut.isLocalValid()) { + log.trace("[{}] opening new local file {}", indexPath, name); return toPut.openLocalInput(context); } + log.trace("[{}] opening new remote file {}", indexPath, name); readerRemoteReadCount.incrementAndGet(); return remote.openInput(name, context); } @@ -316,6 +326,7 @@ remote.copy(local, name, name, IOContext.READ); reference.markValid(); + log.trace("[{}] finished copy of remote file {}", indexPath, name); doneCopy(file, start); } else { long localLength = local.fileLength(name); @@ -324,9 +335,8 @@ //Do a simple consistency check. Ideally Lucene index files are never //updated but still do a check if the copy is consistent if (localLength != remoteLength) { - log.warn("Found local copy for {} in {} but size of local {} differs from remote {}. " + - "Content would be read from remote file only", - name, local, localLength, remoteLength); + log.warn("[{}] Found local copy for {} in {} but size of local {} differs from remote {}. Content would be read from remote file only", + indexPath, name, local, localLength, remoteLength); invalidFileCount.incrementAndGet(); } else { reference.markValid(); @@ -336,8 +346,8 @@ } catch (IOException e) { //TODO In case of exception there would not be any other attempt //to download the file. Look into support for retry - log.warn("Error occurred while copying file [{}] " + - "from {} to {}", name, remote, local, e); + log.warn("[{}] Error occurred while copying file [{}] " + + "from {} to {}", indexPath, name, remote, local, e); } finally { if (copyAttempted && !success){ try { @@ -345,7 +355,7 @@ local.deleteFile(name); } } catch (IOException e) { - log.warn("Error occurred while deleting corrupted file [{}] from [{}]", name, local, e); + log.warn("[{}] Error occurred while deleting corrupted file [{}] from [{}]", indexPath, name, local, e); } } } @@ -381,8 +391,7 @@ try{ removeDeletedFiles(); } catch (IOException e) { - log.warn("Error occurred while removing deleted files from Local {}, " + - "Remote {}", local, remote, e); + log.warn("[{}] Error occurred while removing deleted files from Local {}, Remote {}", indexPath, local, remote, e); } try { @@ -392,7 +401,7 @@ local.close(); remote.close(); } catch (IOException e) { - log.warn("Error occurred while closing directory ", e); + log.warn("[{}] Error occurred while closing directory ", indexPath, e); } } }); @@ -417,8 +426,8 @@ filesToBeDeleted = new HashSet(filesToBeDeleted); filesToBeDeleted.removeAll(failedToDelete); if(!filesToBeDeleted.isEmpty()) { - log.debug("Following files have been removed from Lucene " + - "index directory [{}]", filesToBeDeleted); + log.debug("[{}] Following files have been removed from Lucene " + + "index directory [{}]", indexPath, filesToBeDeleted); } } Index: src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java (revision 1688821) +++ src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java (working copy) @@ -45,10 +45,12 @@ Directory directory = null; IndexDefinition definition = new IndexDefinition(root, defnNodeState, indexPath); NodeState data = defnNodeState.getChildNode(INDEX_DATA_CHILD_NAME); + boolean copyOnReadEnabled = false; if (data.exists()) { directory = new OakDirectory(new ReadOnlyBuilder(data), definition, true); - if (cloner != null){ + if (cloner != null) { directory = cloner.wrapForRead(indexPath, definition, directory); + copyOnReadEnabled = true; } } else if (PERSISTENCE_FILE.equalsIgnoreCase(defnNodeState.getString(PERSISTENCE_NAME))) { String path = defnNodeState.getString(PERSISTENCE_PATH); @@ -60,6 +62,7 @@ if (directory != null) { try { IndexNode index = new IndexNode(PathUtils.getName(indexPath), definition, directory); + index.copyOnReadEnabled = copyOnReadEnabled; directory = null; // closed in Index.close() return index; } finally { @@ -86,6 +89,8 @@ private boolean closed = false; + private boolean copyOnReadEnabled = false; + IndexNode(String name, IndexDefinition definition, Directory directory) throws IOException { this.name = name; @@ -137,4 +142,8 @@ } } + protected boolean isCopyOnReadEnabled() { + return copyOnReadEnabled; + } + } Index: src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java (revision 1688821) +++ src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java (working copy) @@ -96,7 +96,7 @@ try { long start = PERF_LOGGER.start(); IndexNode index = IndexNode.open(path, root, after, cloner); - PERF_LOGGER.end(start, -1, "Index found to be updated at [{}]. Reopening the IndexNode", path); + PERF_LOGGER.end(start, -1, "Index found to be updated at [{}]. Reopening the IndexNode, COR enabled {}", path, index.isCopyOnReadEnabled()); updates.put(path, index); // index can be null } catch (IOException e) { log.error("Failed to open Lucene index at " + path, e);