From 6bd0182261c8e3713fdbca5e14b59071e0f27a5a Mon Sep 17 00:00:00 2001 From: Dave McKnight Date: Mon, 24 Mar 2014 16:51:10 -0400 Subject: [PATCH] [431060][local] RSE performance over local network drives are suboptimal --- .../META-INF/MANIFEST.MF | 5 +- .../org.eclipse.rse.services.local/pom.xml | 2 +- .../local/files/LocalFileService.java | 82 +++++++++++++------ .../services/local/files/LocalHostFile.java | 70 ++++++++++++++-- .../local/search/LocalSearchHandler.java | 6 +- 5 files changed, 124 insertions(+), 41 deletions(-) diff --git a/rse/plugins/org.eclipse.rse.services.local/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.services.local/META-INF/MANIFEST.MF index e81707ecb53..7b39ab2dc0e 100644 --- a/rse/plugins/org.eclipse.rse.services.local/META-INF/MANIFEST.MF +++ b/rse/plugins/org.eclipse.rse.services.local/META-INF/MANIFEST.MF @@ -2,12 +2,13 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.rse.services.local;singleton:=true -Bundle-Version: 2.1.500.qualifier +Bundle-Version: 3.0.0.qualifier Bundle-Activator: org.eclipse.rse.internal.services.local.Activator Bundle-Vendor: %providerName Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, - org.eclipse.rse.services;bundle-version="[3.0.0,4.0.0)" + org.eclipse.rse.services;bundle-version="[3.0.0,4.0.0)", + org.eclipse.core.filesystem Bundle-ActivationPolicy: lazy Eclipse-LazyStart: true Export-Package: org.eclipse.rse.internal.services.local;x-friends:="org.eclipse.rse.subsystems.files.local,org.eclipse.rse.subsystems.processes.local,org.eclipse.rse.subsystems.shells.local", diff --git a/rse/plugins/org.eclipse.rse.services.local/pom.xml b/rse/plugins/org.eclipse.rse.services.local/pom.xml index 5e39de08380..5af406b7449 100644 --- a/rse/plugins/org.eclipse.rse.services.local/pom.xml +++ b/rse/plugins/org.eclipse.rse.services.local/pom.xml @@ -10,6 +10,6 @@ org.eclipse.tm org.eclipse.rse.services.local - 2.1.500-SNAPSHOT + 3.0.0-SNAPSHOT eclipse-plugin diff --git a/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/files/LocalFileService.java b/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/files/LocalFileService.java index e388e3ad7d3..b3ede99b189 100644 --- a/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/files/LocalFileService.java +++ b/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/files/LocalFileService.java @@ -82,6 +82,8 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; +import org.eclipse.core.filesystem.provider.FileInfo; +import org.eclipse.core.internal.filesystem.local.LocalFileNativesManager; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -161,12 +163,22 @@ public class LocalFileService extends AbstractFileService implements ILocalServi private boolean _isWin95 = false; private boolean _isWinNT = false; private String _osCmdShell = null; + + private boolean _getParentCanonicalPath = false; protected ISystemFileTypes _fileTypeRegistry; public LocalFileService(ISystemFileTypes fileTypeRegistry) { _fileTypeRegistry = fileTypeRegistry; + String getParentCanonicalPathStr = System.getProperty("local.get.parent.canonical.path"); //$NON-NLS-1$ + if (getParentCanonicalPathStr != null){ + try { + _getParentCanonicalPath = Boolean.parseBoolean(getParentCanonicalPathStr); + } + catch (Exception e){ + } + } } @@ -226,13 +238,11 @@ public class LocalFileService extends AbstractFileService implements ILocalServi public boolean accept(File dir, String name) { boolean result = false; File entry = new File(dir, name); - if (entry.exists()) { - boolean isDirectory = entry.isDirectory(); + FileInfo info = fetchInfo(entry); + + if (info.exists()) { + boolean isDirectory = info.isDirectory(); boolean isFile = !isDirectory; - if (isFile){ - isFile = entry.isFile(); - } - if (isFile) { result = _matcher.matches(name); } else if (isDirectory) { @@ -731,15 +741,18 @@ public class LocalFileService extends AbstractFileService implements ILocalServi protected IHostFile[] internalFetch(String remoteParent, String fileFilter, int type, IProgressMonitor monitor) throws SystemMessageException { LocalFileNameFilter fFilter = new LocalFileNameFilter(fileFilter, type); File localParent = new File(remoteParent); + FileInfo parentInfo = fetchInfo(localParent); + boolean isArchive = false; boolean isVirtual = false; - if (localParent.exists()) { - if (localParent.isFile()) { + boolean parentExists = parentInfo.exists(); + if (parentExists) { + if (!parentInfo.isDirectory()) { isArchive = ArchiveHandlerManager.getInstance().isArchive(localParent); } // if the system type is Windows, we get the canonical path so that we have the correct case in the path // this is needed because Windows paths are case insensitive - if (isWindows()) { + if (isWindows() && _getParentCanonicalPath) { // slows things down significantly so only do if property is on try { localParent = localParent.getCanonicalFile(); // can this be avoided for network drives? } catch (IOException e) { @@ -783,7 +796,7 @@ public class LocalFileService extends AbstractFileService implements ILocalServi return convertToHostFiles(new File[] { file }, type); } */ - if (localParent.exists()) { + if (parentExists) { File[] files = localParent.listFiles(fFilter); if (files == null) { //throw new RemoteFileException("Error listing: " + localParent.getAbsolutePath()); @@ -804,18 +817,16 @@ public class LocalFileService extends AbstractFileService implements ILocalServi for (int i = 0; i < files.length; i++) { File file = files[i]; - boolean isDirectory = file.isDirectory(); - boolean isFile = !isDirectory; - if (isFile){ - isFile = file.isFile(); - } + FileInfo info = fetchInfo(file); + boolean isDirectory = info.isDirectory(); + boolean isFile = !isDirectory; if (isDirectory) { if (type == IFileService.FILE_TYPE_FILES_AND_FOLDERS || type == IFileService.FILE_TYPE_FOLDERS) { - results.add(new LocalHostFile(file, false, isFile)); + results.add(new LocalHostFile(file, false, info)); } } else if (isFile) @@ -823,28 +834,43 @@ public class LocalFileService extends AbstractFileService implements ILocalServi if (type == IFileService.FILE_TYPE_FILES_AND_FOLDERS || type == IFileService.FILE_TYPE_FILES) { - results.add(new LocalHostFile(file, false, isFile)); + results.add(new LocalHostFile(file, false, info)); } else if (type == IFileService.FILE_TYPE_FOLDERS && ArchiveHandlerManager.getInstance().isArchive(file)) { // On Local Archive's should be considered Folders // as they are containers that can be opened. - results.add(new LocalHostFile(file, false, isFile)); + results.add(new LocalHostFile(file, false, info)); } } - else if (file.exists()) + else if (info.exists()) { - results.add(new LocalHostFile(file, false, isFile)); + results.add(new LocalHostFile(file, false, info)); } } } return (IHostFile[])results.toArray(new IHostFile[results.size()]); } + + private FileInfo fetchInfo(File file) { + if (LocalFileNativesManager.isUsingNatives()) { + FileInfo info = LocalFileNativesManager.fetchFileInfo(file.getAbsolutePath()); + //natives don't set the file name on all platforms + if (info.getName().length() == 0) { + String name = file.getName(); + //Bug 294429: make sure that substring baggage is removed + info.setName(new String(name.toCharArray())); + } + return info; + } + return null; + } public IHostFile getUserHome() { String userHome =System.getProperty("user.home"); //$NON-NLS-1$ File userHomeFile = new File(userHome); - return new LocalHostFile(userHomeFile, (userHomeFile.getParent() == null), userHomeFile.isFile()); + FileInfo info = fetchInfo(userHomeFile); + return new LocalHostFile(userHomeFile, (userHomeFile.getParent() == null), info); } @@ -876,7 +902,9 @@ public class LocalFileService extends AbstractFileService implements ILocalServi IHostFile[] fileObjs = new LocalHostFile[v.size()]; for (int idx = 0; idx < v.size(); idx++) { - fileObjs[idx] = new LocalHostFile((File) v.get(idx), true, false); + File file = (File)v.get(idx); + FileInfo info = fetchInfo(file); + fileObjs[idx] = new LocalHostFile((File) v.get(idx), true, info); } return fileObjs; @@ -895,17 +923,17 @@ public class LocalFileService extends AbstractFileService implements ILocalServi boolean isArchiveParent = false; boolean isRoot = (remoteParent == null || remoteParent.length() == 0); if (!isRoot) { - File remoteParentFile = new File(remoteParent); - if (!remoteParentFile.exists()) { - isVirtualParent = ArchiveHandlerManager.isVirtual(remoteParent); - } else if (remoteParentFile.isFile()) { + isVirtualParent = ArchiveHandlerManager.isVirtual(remoteParent); + if (!isVirtualParent){ + File remoteParentFile = new File(remoteParent); isArchiveParent = ArchiveHandlerManager.getInstance().isArchive(remoteParentFile); } } if (!isVirtualParent && !isArchiveParent) { File file = isRoot ? new File(name) : new File(remoteParent, name); - return new LocalHostFile(file, isRoot, file.isFile()); + FileInfo info = fetchInfo(file); + return new LocalHostFile(file, isRoot, info); } else { diff --git a/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/files/LocalHostFile.java b/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/files/LocalHostFile.java index e29a09fb2d7..b7b82a04c9e 100644 --- a/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/files/LocalHostFile.java +++ b/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/files/LocalHostFile.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 IBM Corporation and others. + * Copyright (c) 2006, 2014 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -16,12 +16,16 @@ * David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files * David McKnight (IBM) - [294521] Local "hidden" files and folders are always shown * David McKnight (IBM) - [420798] Slow performances in RDz 9.0 with opening 7000 files located on a network driver. + * David McKnight (IBM) - [431060][local] RSE performance over local network drives are suboptimal *******************************************************************************/ package org.eclipse.rse.internal.services.local.files; import java.io.File; +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.provider.FileInfo; +import org.eclipse.core.internal.filesystem.local.LocalFileNativesManager; import org.eclipse.rse.services.clientserver.archiveutils.ArchiveHandlerManager; import org.eclipse.rse.services.files.IHostFile; import org.eclipse.rse.services.files.IHostFilePermissions; @@ -42,24 +46,38 @@ public class LocalHostFile implements IHostFile, IHostFilePermissionsContainer private boolean _isRoot = false; private boolean _isArchive = false; private IHostFilePermissions _permissions = null; + private FileInfo _info = null; public LocalHostFile(File file) { _file = file; _isArchive = ArchiveHandlerManager.getInstance().isArchive(_file); + fetchInfo(); } - public LocalHostFile(File file, boolean isRoot, boolean isFile) + public LocalHostFile(File file, boolean isRoot, FileInfo info) { _file = file; + _info = info; _isRoot = isRoot; if (!isRoot){ _isArchive = ArchiveHandlerManager.getInstance().isArchive(_file); - _isFile = new Boolean(isFile); - _isDirectory = new Boolean(!isFile); } } + private void fetchInfo() { + if (LocalFileNativesManager.isUsingNatives()) { + _info = LocalFileNativesManager.fetchFileInfo(_file.getAbsolutePath()); + //natives don't set the file name on all platforms + if (_info.getName().length() == 0) { + String name = _file.getName(); + //Bug 294429: make sure that substring baggage is removed + _info.setName(new String(name.toCharArray())); + } + } + } + + /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @@ -88,8 +106,13 @@ public class LocalHostFile implements IHostFile, IHostFilePermissionsContainer public boolean isHidden() { if (_isHidden == null || needsQuery()){ - String name = getName(); - _isHidden = new Boolean(name.charAt(0) == '.' || (!_isRoot && _file.isHidden())); + if (_info != null){ + _isHidden = new Boolean(_info.getAttribute(EFS.ATTRIBUTE_HIDDEN)); + } + else { + String name = getName(); + _isHidden = new Boolean(name.charAt(0) == '.' || (!_isRoot && _file.isHidden())); + } } return _isHidden.booleanValue(); } @@ -102,7 +125,13 @@ public class LocalHostFile implements IHostFile, IHostFilePermissionsContainer public boolean isDirectory() { if (_isDirectory == null){ - _isDirectory = new Boolean(_file.isDirectory()); + if (_info != null){ + // use cached info + _isDirectory = new Boolean(_info.isDirectory()); + } + else { + _isDirectory = new Boolean(_file.isDirectory()); + } } return _isDirectory.booleanValue(); } @@ -115,7 +144,13 @@ public class LocalHostFile implements IHostFile, IHostFilePermissionsContainer public boolean isFile() { if (_isFile == null){ - _isFile = new Boolean(_file.isFile()); + if (_info != null){ + // use cached info + _isFile = new Boolean(!_info.isDirectory()); + } + else { + _isFile = new Boolean(_file.isFile()); + } } return _isFile.booleanValue(); } @@ -128,7 +163,12 @@ public class LocalHostFile implements IHostFile, IHostFilePermissionsContainer public boolean exists() { if (_exists == null || needsQuery()){ - _exists = new Boolean(_file.exists()); + if (_info != null){ + _exists = new Boolean(_info.exists()); + } + else { + _exists = new Boolean(_file.exists()); + } } return _exists.booleanValue(); } @@ -140,11 +180,17 @@ public class LocalHostFile implements IHostFile, IHostFilePermissionsContainer public long getSize() { + if (_info != null){ + return _info.getLength(); + } return _file.length(); } public long getModifiedDate() { + if (_info != null){ + return _info.getLastModified(); + } return _file.lastModified(); } @@ -160,10 +206,16 @@ public class LocalHostFile implements IHostFile, IHostFilePermissionsContainer } public boolean canRead() { + if (_info != null){ + return _info.getAttribute(EFS.ATTRIBUTE_OWNER_READ); + } return _file.canRead(); } public boolean canWrite() { + if (_info != null){ + return _info.getAttribute(EFS.ATTRIBUTE_OWNER_WRITE); + } return _file.canWrite(); } diff --git a/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/search/LocalSearchHandler.java b/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/search/LocalSearchHandler.java index a10ae3d65f6..068c40065ac 100644 --- a/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/search/LocalSearchHandler.java +++ b/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/search/LocalSearchHandler.java @@ -17,6 +17,7 @@ * Xuan Chen (IBM) - [194865] [local][Archives] Searching contents of a file in an Archive doesn't work * Xuan Chen (IBM) - [205448] [search]All the files are listed as in the Remote Search view even only found one match in a file * David McKnight (IBM) - [420798] Slow performances in RDz 9.0 with opening 7000 files located on a network driver. + * David McKnight (IBM) - [431060][local] RSE performance over local network drives are suboptimal *******************************************************************************/ package org.eclipse.rse.internal.services.local.search; @@ -271,7 +272,8 @@ public class LocalSearchHandler implements ISearchHandler { // note that the file can not be root - file = new LocalHostFile(theFile, false, true); + + file = new LocalHostFile(theFile); /* TODO if (!isArchive) @@ -379,7 +381,7 @@ public class LocalSearchHandler implements ISearchHandler // file is root boolean isRoot = false; //TODO - fileImpl = new LocalHostFile(theFile, isRoot, true); + fileImpl = new LocalHostFile(theFile); } // create local file differently for virtual directory else