Skip to content

Commit

Permalink
#169: improved FileCache logging to find more places for performance …
Browse files Browse the repository at this point in the history
…improving
  • Loading branch information
k3b committed Apr 27, 2021
1 parent 2b2ef95 commit 5091fa3
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 79 deletions.
68 changes: 35 additions & 33 deletions app/src/main/java/de/k3b/android/io/AndroidFileFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ public void set(IFile src) {
super.set(src);
}

private DocumentFile getDocumentFileOrDirOrNull(@NonNull File file) {
return documentFileTranslator.getDocumentFileOrDirOrNull(file, null);
private DocumentFile getDocumentFileOrDirOrNull(String debugContext, @NonNull File file) {
return documentFileTranslator.getDocumentFileOrDirOrNull(debugContext, file, null);
}

private boolean copyImpl(@NonNull AndroidFileFacade targetFullPath, boolean deleteSourceWhenSuccess) {
Expand All @@ -138,7 +138,7 @@ private boolean copyImpl(@NonNull AndroidFileFacade targetFullPath, boolean dele

@Override
public boolean renameTo(@NonNull String newName) {
if (exists() && getAndroidFile(false).renameTo(newName)) {
if (exists() && getAndroidFile("renameTo", false).renameTo(newName)) {
invalidateParentDirCache();
return true;
}
Expand All @@ -149,7 +149,7 @@ public boolean renameTo(@NonNull String newName) {

@Override
public boolean delete() {
boolean result = exists() && getAndroidFile(false).delete();
boolean result = exists() && getAndroidFile("delete", false).delete();

if (result) {
invalidateParentDirCache();
Expand All @@ -162,37 +162,37 @@ public boolean delete() {

@Override
public boolean exists() {
DocumentFile androidFile = getAndroidFile(false);
DocumentFile androidFile = getAndroidFile("exists", false);
return (androidFile != null) && androidFile.exists();
}

@Override
public boolean canWrite() {
final DocumentFile androidFile = getAndroidFile(false);
final DocumentFile androidFile = getAndroidFile("canWrite", false);
return (androidFile != null) && androidFile.canWrite();
}

@Override
public boolean canRead() {
final DocumentFile androidFile = getAndroidFile(false);
final DocumentFile androidFile = getAndroidFile("canRead", false);
return (androidFile != null) && androidFile.canRead();
}

@Override
public boolean isFile() {
final DocumentFile androidFile = getAndroidFile(false);
final DocumentFile androidFile = getAndroidFile("isFile", false);
return (androidFile != null) && androidFile.isFile();
}

@Override
public boolean isDirectory() {
final DocumentFile androidFile = getAndroidFile(false);
final DocumentFile androidFile = getAndroidFile("isDirectory", false);
return (androidFile != null) && androidFile.isDirectory();
}

@Override
public boolean isHidden() {
final DocumentFile androidFile = getAndroidFile(false);
final DocumentFile androidFile = getAndroidFile("isHidden", false);
if ((androidFile != null)) {
final String name = androidFile.getName();
return (name == null) || name.startsWith(".");
Expand All @@ -207,7 +207,7 @@ public IFile getCanonicalFile() {

@Override
public IFile getParentFile() {
final DocumentFile androidFile = getAndroidFile(false);
final DocumentFile androidFile = getAndroidFile("getParentFile", false);
if (androidFile != null) {
return new AndroidFileFacade(androidFile.getParentFile(), getFile().getParentFile());
} else {
Expand All @@ -219,7 +219,7 @@ public IFile getParentFile() {
public String getAsUriString() {
if (readUri != null) return readUri.toString();

final DocumentFile androidFile = getAndroidFile(false);
final DocumentFile androidFile = getAndroidFile("getAsUriString", false);
final Uri uri = (androidFile != null) ? androidFile.getUri() : null;
if (uri != null) {
return uri.toString();
Expand All @@ -234,7 +234,7 @@ public void setReadUri(String readUri) {

@Override
public String getName() {
final DocumentFile androidFile = getAndroidFile(false);
final DocumentFile androidFile = getAndroidFile("getName", false);
if (androidFile != null) {
return androidFile.getName();
}
Expand All @@ -243,7 +243,7 @@ public String getName() {

@Override
public long lastModified() {
final DocumentFile androidFile = getAndroidFile(false);
final DocumentFile androidFile = getAndroidFile("lastModified", false);
if (androidFile != null) {
return androidFile.lastModified();
}
Expand All @@ -252,15 +252,16 @@ public long lastModified() {

@Override
public boolean mkdirs() {
this.androidFile = documentFileTranslator.getOrCreateDirectory(getFile());
this.androidFile = documentFileTranslator.getOrCreateDirectory("mkdirs", getFile());
invalidateParentDirCache();
return null != this.androidFile;
}

@Override
public IFile[] listFiles() {
enableCache("listFiles", true);
final DocumentFile androidFile = getAndroidFile(false);
String debugContext = "listFiles";
enableCache(debugContext, true);
final DocumentFile androidFile = getAndroidFile(debugContext, false);
if (androidFile != null) {
return get(androidFile.listFiles());
}
Expand All @@ -269,7 +270,7 @@ public IFile[] listFiles() {

private void enableCache(String dbgContext, boolean enable) {
if (enable != Global.android_DocumentFile_find_cache) {
if (FileFacade.debugLogSAFFacade) {
if (FileFacade.debugLogSAFFacade || DocumentFileTranslator.debugLogSAFCache) {
Log.i(FileFacade.LOG_TAG, this.getClass().getSimpleName()
+ " " + dbgContext + ": enableCache(" + enable + ")");
}
Expand All @@ -283,9 +284,10 @@ private void enableCache(String dbgContext, boolean enable) {
}

public IFile[] listDirs() {
enableCache("listDirs", true);
String dbgContext = "listDirs";
enableCache(dbgContext, true);
List<IFile> found = new ArrayList<>();
final DocumentFile androidFile = getAndroidFile(false);
final DocumentFile androidFile = getAndroidFile(dbgContext, false);
if (androidFile != null) {
final File parent = getFile();
for (DocumentFile file : androidFile.listFiles()) {
Expand All @@ -301,7 +303,7 @@ public IFile[] listDirs() {

@Override
public long length() {
final DocumentFile androidFile = getAndroidFile(false);
final DocumentFile androidFile = getAndroidFile("length", false);
if (androidFile != null) {
return androidFile.length();
}
Expand All @@ -315,10 +317,11 @@ public boolean copy(@NonNull IFile targetFullPath, boolean deleteSourceWhenSucce

@Override
public OutputStream openOutputStream() throws FileNotFoundException {
DocumentFile androidFile = getAndroidFile(false);
String debugContext = "openOutputStream";
DocumentFile androidFile = getAndroidFile(debugContext, false);
String context = "openOutputStream overwrite existing ";
if (androidFile == null) {
final DocumentFile documentFileParent = documentFileTranslator.getOrCreateDirectory(getFile().getParentFile());
final DocumentFile documentFileParent = documentFileTranslator.getOrCreateDirectory(debugContext, getFile().getParentFile());
androidFile = this.androidFile = documentFileParent.createFile(null, getFile().getName());
context = "openOutputStream create new ";

Expand All @@ -327,29 +330,29 @@ public OutputStream openOutputStream() throws FileNotFoundException {
Log.i(LOG_TAG, context + this);
}
OutputStream result = documentFileTranslator.createOutputStream(androidFile);
enableCache("openOutputStream", false);
enableCache(debugContext, false);
return result;
}

@Override
public InputStream openInputStream() throws FileNotFoundException {
String context = "openInputStream ";
String debugContext = "openInputStream ";
if ((readUri != null)) {
if (debugLogSAFFacade) {
Log.i(LOG_TAG, context + this + " for uri " + readUri);
Log.i(LOG_TAG, debugContext + this + " for uri " + readUri);
}
return documentFileTranslator.openInputStream(readUri);
}
final DocumentFile androidFile = getAndroidFile(true);
final DocumentFile androidFile = getAndroidFile(debugContext, true);
final InputStream resultInputStream = documentFileTranslator.openInputStream(androidFile);
if (resultInputStream == null) {
final String msg = context + this + " for uri "
final String msg = debugContext + this + " for uri "
+ ((androidFile != null) ? androidFile.getUri() : "null") + " returns null";
Log.w(LOG_TAG, msg);
getAndroidFile(true); // allow debugger to step in
getAndroidFile(debugContext, true); // allow debugger to step in
throw new FileNotFoundException(msg);
} else if (debugLogSAFFacade) {
Log.i(LOG_TAG, context + this + " for uri " + androidFile.getUri());
Log.i(LOG_TAG, debugContext + this + " for uri " + androidFile.getUri());
}
return resultInputStream;
}
Expand Down Expand Up @@ -379,12 +382,11 @@ private IFile[] get(DocumentFile[] docs) {
* implements loads on demand.
*
* @return null means: DocumentFile does not exist (yet)
* @param forOpenInputStream
*/
@Nullable
private DocumentFile getAndroidFile(boolean forOpenInputStream) {
private DocumentFile getAndroidFile(String debugContext, boolean forOpenInputStream) {
if ((androidFile == null) && (forOpenInputStream || androidFileMayExist)) {
androidFile = getDocumentFileOrDirOrNull(getFile());
androidFile = getDocumentFileOrDirOrNull(debugContext, getFile());
androidFileMayExist = false;
}
return androidFile;
Expand Down
34 changes: 23 additions & 11 deletions app/src/main/java/de/k3b/android/io/DocumentFileCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,40 +41,52 @@ public CurrentFileCache getCacheStrategy() {
return currentFileCache;
}

public DocumentFile findFile(DocumentFile parentDoc, File parentFile, String displayName) {
public DocumentFile findFile(String debugContext, DocumentFile parentDoc, File parentFile, String displayName) {
if (Global.android_DocumentFile_find_cache) {
CurrentFileCache currentFileCache = getCacheStrategy();

if (currentFileCache != null) {
if (!parentFile.equals(currentFileCache.lastParentFile)) {
HashMap<String, DocumentFile> lastChildDocFiles = currentFileCache.lastChildDocFiles;
currentFileCache.lastParentFile = parentFile;
currentFileCache.lastChildDocFiles.clear();
lastChildDocFiles.clear();
int count = 0;
DocumentFile[] childDocuments = parentDoc.listFiles();
for (DocumentFile childDoc : childDocuments) {
if (childDoc.isFile()) {
String childDocName = childDoc.getName().toLowerCase();
if (PhotoPropertiesUtil.isImage(childDocName, PhotoPropertiesUtil.IMG_TYPE_ALL | PhotoPropertiesUtil.IMG_TYPE_XMP)) {
currentFileCache.lastChildDocFiles.put(childDocName, childDoc);
lastChildDocFiles.put(childDocName, childDoc);
count++;
}
}
}
if (DocumentFileTranslator.debugLogSAFCache) {
Log.i(TAG,
((debugContext == null) ? "" : debugContext)
+ this.getClass().getSimpleName()
+ ".reload cache from (" + parentFile + ") ==> " + count
+ " items");
}

}

if (PhotoPropertiesUtil.isImage(displayName, PhotoPropertiesUtil.IMG_TYPE_ALL | PhotoPropertiesUtil.IMG_TYPE_XMP)) {
return logFindFileResult(parentFile, currentFileCache.lastChildDocFiles.get(displayName.toLowerCase()));
return logFindFileResult(debugContext, parentFile, currentFileCache.lastChildDocFiles.get(displayName.toLowerCase()));
}
}
}
return logFindFileResult(parentFile, parentDoc.findFile(displayName));
return logFindFileResult(debugContext, parentFile, parentDoc.findFile(displayName));
}

private DocumentFile logFindFileResult(File parentFile, DocumentFile documentFile) {
if (FileFacade.debugLogSAFFacade) {
Log.i(FileFacade.LOG_TAG, this.getClass().getSimpleName()
+ ".findFile(" + parentFile + ",cache="
+ Global.android_DocumentFile_find_cache
+ ") ==> " + documentFile);
private DocumentFile logFindFileResult(String debugContext, File parentFile, DocumentFile documentFile) {
if (FileFacade.debugLogSAFFacade || DocumentFileTranslator.debugLogSAFCache) {
Log.i(TAG,
((debugContext == null) ? "" : debugContext)
+ this.getClass().getSimpleName()
+ ".findFile(" + parentFile + ",cache="
+ Global.android_DocumentFile_find_cache
+ ") ==> " + documentFile);
}
return documentFile;
}
Expand Down
Loading

0 comments on commit 5091fa3

Please sign in to comment.