| Index: ui/file_manager/file_manager/foreground/js/directory_contents.js
|
| diff --git a/ui/file_manager/file_manager/foreground/js/directory_contents.js b/ui/file_manager/file_manager/foreground/js/directory_contents.js
|
| index c380e53d6ae5ca8ea574dc7752f79e4b2f7bb996..2f0bf38740b635e443cca84871f12fc79c8be3d3 100644
|
| --- a/ui/file_manager/file_manager/foreground/js/directory_contents.js
|
| +++ b/ui/file_manager/file_manager/foreground/js/directory_contents.js
|
| @@ -2,6 +2,64 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +/**
|
| + * Cached directory content reader factory.
|
| + * @param {DirectoryEntry} dirEntry
|
| + * @constructor
|
| + */
|
| +function CachedDirectoryReaderFactory(dirEntry) {
|
| + this.dirEntry_ = dirEntry;
|
| + this.reader_ = null;
|
| + this.readEntries_ = [];
|
| +}
|
| +
|
| +CachedDirectoryReaderFactory.prototype.createReader = function() {
|
| + return new CachedDirectoryReader(this);
|
| +};
|
| +
|
| +CachedDirectoryReaderFactory.prototype.refresh = function() {
|
| + console.log('CachedDirectoryReaderFactory refresh');
|
| + this.reader_ = null;
|
| + this.readEntries_ = [];
|
| +};
|
| +
|
| +/**
|
| + * Cached directory content reader.
|
| + * @param {CachedDirectoryReaderFactory} factory
|
| + * @constructor
|
| + */
|
| +function CachedDirectoryReader(factory) {
|
| + this.factory_ = factory;
|
| + this.firstTime_ = true;
|
| +}
|
| +
|
| +CachedDirectoryReader.prototype.readEntries = function(
|
| + successCallback, errorCallback) {
|
| + if (this.factory_.readEntries_.length === 0) {
|
| + console.log('no cached item is feeded.');
|
| + }
|
| + if (this.firstTime_ && this.factory_.readEntries_.length > 0) {
|
| + this.firstTime_ = false;
|
| + console.log(
|
| + 'cached item ' + this.factory_.readEntries_.length + ' is feeded.');
|
| + successCallback(this.factory_.readEntries_);
|
| + } else {
|
| + this.firstTime_ = false;
|
| + if (!this.factory_.reader_) {
|
| + this.factory_.reader_ = this.factory_.dirEntry_.createReader();
|
| + }
|
| + this.factory_.reader_.readEntries(
|
| + function(newEntries) {
|
| + this.factory_.readEntries_ =
|
| + this.factory_.readEntries_.concat(newEntries);
|
| + successCallback(newEntries);
|
| + }.bind(this),
|
| + function(error) {
|
| + errorCallback(error);
|
| + }.bind(this));
|
| + }
|
| +};
|
| +
|
| /**
|
| * Scanner of the entries.
|
| * @constructor
|
| @@ -40,9 +98,10 @@ ContentScanner.prototype.cancel = function() {
|
| * @constructor
|
| * @extends {ContentScanner}
|
| */
|
| -function DirectoryContentScanner(entry) {
|
| +function DirectoryContentScanner(entry, cachedReaderFactory) {
|
| ContentScanner.call(this);
|
| this.entry_ = entry;
|
| + this.cachedReaderFactory_ = cachedReaderFactory;
|
| }
|
|
|
| /**
|
| @@ -64,7 +123,7 @@ DirectoryContentScanner.prototype.scan = function(
|
| }
|
|
|
| metrics.startInterval('DirectoryScan');
|
| - var reader = this.entry_.createReader();
|
| + var reader = this.cachedReaderFactory_.createReader();
|
| var readEntries = function() {
|
| reader.readEntries(
|
| function(entries) {
|
| @@ -185,10 +244,11 @@ DriveSearchContentScanner.prototype.scan = function(
|
| * @constructor
|
| * @extends {ContentScanner}
|
| */
|
| -function LocalSearchContentScanner(entry, query) {
|
| +function LocalSearchContentScanner(entry, query, cachedReaderFactory) {
|
| ContentScanner.call(this);
|
| this.entry_ = entry;
|
| this.query_ = query.toLowerCase();
|
| + this.cachedReaderFactory_ = cachedReaderFactory;
|
| }
|
|
|
| /**
|
| @@ -205,6 +265,9 @@ LocalSearchContentScanner.prototype.scan = function(
|
| var numRunningTasks = 0;
|
| var error = null;
|
| var maybeRunCallback = function() {
|
| + if (this.cancelled_) {
|
| + console.log('scan cancelation for "' + this.query_ + '" propagated.');
|
| + }
|
| if (numRunningTasks === 0) {
|
| if (this.cancelled_)
|
| errorCallback(util.createDOMError(util.FileError.ABORT_ERR));
|
| @@ -215,7 +278,9 @@ LocalSearchContentScanner.prototype.scan = function(
|
| }
|
| }.bind(this);
|
|
|
| - var processEntry = function(entry) {
|
| + var processEntry = function(entry, isTopLevel) {
|
| + var reader;
|
| +
|
| numRunningTasks++;
|
| var onError = function(fileError) {
|
| if (!error)
|
| @@ -241,18 +306,22 @@ LocalSearchContentScanner.prototype.scan = function(
|
| // Start to process sub directories.
|
| for (var i = 0; i < entries.length; i++) {
|
| if (entries[i].isDirectory)
|
| - processEntry(entries[i]);
|
| + processEntry(entries[i], false);
|
| }
|
|
|
| // Read remaining entries.
|
| reader.readEntries(onSuccess, onError);
|
| }.bind(this);
|
|
|
| - var reader = entry.createReader();
|
| + if (isTopLevel) {
|
| + reader = this.cachedReaderFactory_.createReader();
|
| + } else {
|
| + reader = entry.createReader();
|
| + }
|
| reader.readEntries(onSuccess, onError);
|
| }.bind(this);
|
|
|
| - processEntry(this.entry_);
|
| + processEntry(this.entry_, true);
|
| };
|
|
|
| /**
|
| @@ -461,13 +530,13 @@ FileListContext.createPrefetchPropertyNames_ = function() {
|
| * directory.
|
| * @param {function():ContentScanner} scannerFactory The factory to create
|
| * ContentScanner instance.
|
| + * @param {CachedDirectoryReaderFactory=} opt_cachedReaderFactory
|
| * @constructor
|
| * @extends {cr.EventTarget}
|
| */
|
| -function DirectoryContents(context,
|
| - isSearch,
|
| - directoryEntry,
|
| - scannerFactory) {
|
| +function DirectoryContents(
|
| + context, isSearch, directoryEntry, scannerFactory,
|
| + opt_cachedReaderFactory) {
|
| this.context_ = context;
|
| this.fileList_ = context.fileList;
|
|
|
| @@ -484,6 +553,8 @@ function DirectoryContents(context,
|
| * @type {Object}
|
| */
|
| this.metadataSnapshot_ = null;
|
| +
|
| + this.cachedReaderFactory_ = opt_cachedReaderFactory;
|
| }
|
|
|
| /**
|
| @@ -491,16 +562,18 @@ function DirectoryContents(context,
|
| */
|
| DirectoryContents.prototype.__proto__ = cr.EventTarget.prototype;
|
|
|
| +DirectoryContents.prototype.getCachedReaderFactory = function() {
|
| + return this.cachedReaderFactory_;
|
| +};
|
| +
|
| /**
|
| * Create the copy of the object, but without scan started.
|
| * @return {!DirectoryContents} Object copy.
|
| */
|
| DirectoryContents.prototype.clone = function() {
|
| return new DirectoryContents(
|
| - this.context_,
|
| - this.isSearch_,
|
| - this.directoryEntry_,
|
| - this.scannerFactory_);
|
| + this.context_, this.isSearch_, this.directoryEntry_, this.scannerFactory_,
|
| + this.cachedReaderFactory_);
|
| };
|
|
|
| /**
|
| @@ -629,6 +702,9 @@ DirectoryContents.prototype.scan = function(refresh) {
|
| this.onScanError_();
|
| }
|
|
|
| + if (refresh && this.cachedReaderFactory_)
|
| + this.cachedReaderFactory_.refresh();
|
| +
|
| // TODO(hidehiko,mtomasz): this scan method must be called at most once.
|
| // Remove such a limitation.
|
| this.scanner_ = this.scannerFactory_();
|
| @@ -810,7 +886,9 @@ DirectoryContents.prototype.onNewEntries_ = function(refresh, entries) {
|
|
|
| var chunk = entriesFiltered.slice(i, i + MAX_CHUNK_SIZE);
|
| prefetchMetadataQueue.run(function(chunk, callbackInner) {
|
| + var t0 = performance.now();
|
| this.prefetchMetadata(chunk, refresh, function() {
|
| + var t1 = performance.now();
|
| if (!prefetchMetadataQueue.isCancelled()) {
|
| if (this.scanCancelled_)
|
| prefetchMetadataQueue.cancel();
|
| @@ -850,16 +928,21 @@ DirectoryContents.prototype.prefetchMetadata =
|
| *
|
| * @param {FileListContext} context File list context.
|
| * @param {DirectoryEntry} directoryEntry The current directory entry.
|
| + * @param {CachedDirectoryReaderFactory=} opt_cachedReaderFactory
|
| * @return {DirectoryContents} Created DirectoryContents instance.
|
| */
|
| -DirectoryContents.createForDirectory = function(context, directoryEntry) {
|
| +DirectoryContents.createForDirectory = function(
|
| + context, directoryEntry, opt_cachedReaderFactory) {
|
| + if (!opt_cachedReaderFactory) {
|
| + opt_cachedReaderFactory = new CachedDirectoryReaderFactory(directoryEntry);
|
| + }
|
| return new DirectoryContents(
|
| context,
|
| false, // Non search.
|
| - directoryEntry,
|
| - function() {
|
| - return new DirectoryContentScanner(directoryEntry);
|
| - });
|
| + directoryEntry, function() {
|
| + return new DirectoryContentScanner(
|
| + directoryEntry, opt_cachedReaderFactory);
|
| + }, opt_cachedReaderFactory);
|
| };
|
|
|
| /**
|
| @@ -889,17 +972,21 @@ DirectoryContents.createForDriveSearch = function(
|
| * @param {FileListContext} context File list context.
|
| * @param {DirectoryEntry} directoryEntry The current directory entry.
|
| * @param {string} query Search query.
|
| + * @param {CachedDirectoryReaderFactory=} opt_cachedReaderFactory
|
| * @return {DirectoryContents} Created DirectoryContents instance.
|
| */
|
| DirectoryContents.createForLocalSearch = function(
|
| - context, directoryEntry, query) {
|
| + context, directoryEntry, query, opt_cachedReaderFactory) {
|
| + if (!opt_cachedReaderFactory) {
|
| + opt_cachedReaderFactory = new CachedDirectoryReaderFactory(directoryEntry);
|
| + }
|
| return new DirectoryContents(
|
| context,
|
| true, // Search.
|
| - directoryEntry,
|
| - function() {
|
| - return new LocalSearchContentScanner(directoryEntry, query);
|
| - });
|
| + directoryEntry, function() {
|
| + return new LocalSearchContentScanner(
|
| + directoryEntry, query, opt_cachedReaderFactory);
|
| + }, opt_cachedReaderFactory);
|
| };
|
|
|
| /**
|
|
|