Merge pull request #6725 from grote/is-child-performance

Improve performance of DocumentsProvider#isChildDocument()
This commit is contained in:
Tobias Kaminsky 2020-08-27 15:29:15 +02:00 committed by GitHub
commit 8a5d58a64e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 8 deletions

View file

@ -171,7 +171,7 @@ public class DownloadFileOperation extends RemoteOperation {
modificationTimestamp = downloadOperation.getModificationTimestamp();
etag = downloadOperation.getEtag();
newFile = new File(getSavePath());
if (!newFile.getParentFile().mkdirs()) {
if (!newFile.getParentFile().exists() && !newFile.getParentFile().mkdirs()) {
Log_OC.e(TAG, "Unable to create parent folder " + newFile.getParentFile().getAbsolutePath());
}

View file

@ -618,15 +618,29 @@ public class DocumentsStorageProvider extends DocumentsProvider {
Log.d(TAG, "isChildDocument(), parent=" + parentDocumentId + ", id=" + documentId);
try {
Document currentDocument = toDocument(documentId);
// get file for parent document
Document parentDocument = toDocument(parentDocumentId);
while (!ROOT_PATH.equals(currentDocument.getRemotePath())) {
currentDocument = currentDocument.getParent();
if (parentDocument.getFile().equals(currentDocument.getFile())) {
return true;
}
OCFile parentFile = parentDocument.getFile();
if (parentFile == null) {
throw new FileNotFoundException("No parent file with ID " + parentDocumentId);
}
// get file for child candidate document
Document currentDocument = toDocument(documentId);
OCFile childFile = currentDocument.getFile();
if (childFile == null) {
throw new FileNotFoundException("No child file with ID " + documentId);
}
String parentPath = parentFile.getDecryptedRemotePath();
String childPath = childFile.getDecryptedRemotePath();
// The alternative is to go up the folder hierarchy from currentDocument with getParent()
// until we arrive at parentDocument or the storage root.
// However, especially for long paths this is expensive and can take substantial time.
// The solution below uses paths and is faster by a factor of 2-10 depending on the nesting level of child.
// So far, the same document with its unique ID can never be in two places at once.
// If this assumption ever changes, this code would need to be adapted.
return parentDocument.getAccount() == currentDocument.getAccount() && childPath.startsWith(parentPath);
} catch (FileNotFoundException e) {
Log.e(TAG, "failed to check for child document", e);