Commit f6bc2704 authored by Luciano Pacheco's avatar Luciano Pacheco Committed by Commit Bot

Files app: ES6 class for metadata_cache_item.js, function_sequence.js and function_parallel.js

Bug: 778674
Change-Id: I37b5d58f5f3b5d7cb2f30ada3e383c655ec69978
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1750464
Auto-Submit: Luciano Pacheco <lucmult@chromium.org>
Reviewed-by: default avatarAustin Tankiang <austinct@chromium.org>
Commit-Queue: Austin Tankiang <austinct@chromium.org>
Cr-Commit-Position: refs/heads/master@{#686328}
parent ad34509a
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
// found in the LICENSE file. // found in the LICENSE file.
/** /**
* @class FunctionSequence to invoke steps in sequence * @class FunctionParallel to invoke steps in parallel.
* */
class FunctionParallel {
/**
* @param {string} name Name of the function. * @param {string} name Name of the function.
* @param {Array<Function>} steps Array of functions to invoke in parallel. * @param {Array<Function>} steps Array of functions to invoke in parallel.
* @param {MetadataParser} logger Logger object. * @param {MetadataParser} logger Logger object.
* @param {function()} callback Callback to invoke on success. * @param {function()} callback Callback to invoke on success.
* @param {function(string)} failureCallback Callback to invoke on failure. * @param {function(string)} failureCallback Callback to invoke on failure.
* @constructor
* @struct
*/ */
function FunctionParallel(name, steps, logger, callback, failureCallback) { constructor(name, steps, logger, callback, failureCallback) {
// Private variables hidden in closure // Private variables hidden in closure
this.currentStepIdx_ = -1; this.currentStepIdx_ = -1;
this.failed_ = false; this.failed_ = false;
...@@ -28,40 +28,40 @@ function FunctionParallel(name, steps, logger, callback, failureCallback) { ...@@ -28,40 +28,40 @@ function FunctionParallel(name, steps, logger, callback, failureCallback) {
this.nextStep = this.nextStep_.bind(this); this.nextStep = this.nextStep_.bind(this);
this.onError = this.onError_.bind(this); this.onError = this.onError_.bind(this);
this.apply = this.start.bind(this); this.apply = this.start.bind(this);
} }
/** /**
* Error handling function, which fires error callback. * Error handling function, which fires error callback.
* *
* @param {string} err Error message. * @param {string} err Error message.
* @private * @private
*/ */
FunctionParallel.prototype.onError_ = function(err) { onError_(err) {
if (!this.failed_) { if (!this.failed_) {
this.failed_ = true; this.failed_ = true;
this.failureCallback_(err); this.failureCallback_(err);
} }
}; }
/** /**
* Advances to next step. This method should not be used externally. In external * Advances to next step. This method should not be used externally. In
* cases should be used nextStep function, which is defined in closure and thus * external cases should be used nextStep function, which is defined in
* has access to internal variables of functionsequence. * closure and thus has access to internal variables of functionsequence.
* *
* @private * @private
*/ */
FunctionParallel.prototype.nextStep_ = function() { nextStep_() {
if (--this.remaining == 0 && !this.failed_) { if (--this.remaining == 0 && !this.failed_) {
this.callback_(); this.callback_();
} }
}; }
/** /**
* This function should be called only once on start, so start all the children * This function should be called only once on start, so start all the
* at once * children at once
* @param {...} var_args Arguments to be passed to all the steps. * @param {...} var_args Arguments to be passed to all the steps.
*/ */
FunctionParallel.prototype.start = function(var_args) { start(var_args) {
this.logger.vlog( this.logger.vlog(
'Starting [' + this.steps_.length + '] parallel tasks ' + 'Starting [' + this.steps_.length + '] parallel tasks ' +
'with ' + arguments.length + ' argument(s)'); 'with ' + arguments.length + ' argument(s)');
...@@ -71,11 +71,13 @@ FunctionParallel.prototype.start = function(var_args) { ...@@ -71,11 +71,13 @@ FunctionParallel.prototype.start = function(var_args) {
} }
} }
for (let i = 0; i < this.steps_.length; i++) { for (let i = 0; i < this.steps_.length; i++) {
this.logger.vlog('Attempting to start step [' + this.steps_[i].name + ']'); this.logger.vlog(
'Attempting to start step [' + this.steps_[i].name + ']');
try { try {
this.steps_[i].apply(this, arguments); this.steps_[i].apply(this, arguments);
} catch (e) { } catch (e) {
this.onError(e.toString()); this.onError(e.toString());
} }
} }
}; }
}
...@@ -3,16 +3,17 @@ ...@@ -3,16 +3,17 @@
// found in the LICENSE file. // found in the LICENSE file.
/** /**
* @class FunctionSequence to invoke steps in sequence * @class FunctionSequence to invoke steps in sequence.
* */
class FunctionSequence {
/**
* @param {string} name Name of the function. * @param {string} name Name of the function.
* @param {Array} steps Array of functions to invoke in sequence. * @param {Array} steps Array of functions to invoke in sequence.
* @param {MetadataParser} logger Logger object. * @param {MetadataParser} logger Logger object.
* @param {function()} callback Callback to invoke on success. * @param {function()} callback Callback to invoke on success.
* @param {function(string)} failureCallback Callback to invoke on failure. * @param {function(string)} failureCallback Callback to invoke on failure.
* @constructor
*/ */
function FunctionSequence(name, steps, logger, callback, failureCallback) { constructor(name, steps, logger, callback, failureCallback) {
// Private variables hidden in closure // Private variables hidden in closure
this.currentStepIdx_ = -1; this.currentStepIdx_ = -1;
this.failed_ = false; this.failed_ = false;
...@@ -21,71 +22,73 @@ function FunctionSequence(name, steps, logger, callback, failureCallback) { ...@@ -21,71 +22,73 @@ function FunctionSequence(name, steps, logger, callback, failureCallback) {
this.failureCallback_ = failureCallback; this.failureCallback_ = failureCallback;
this.logger = logger; this.logger = logger;
this.name = name; this.name = name;
/** @public {boolean} */
this.started = false;
this.onError = this.onError_.bind(this); this.onError = this.onError_.bind(this);
this.finish = this.finish_.bind(this); this.finish = this.finish_.bind(this);
this.nextStep = this.nextStep_.bind(this); this.nextStep = this.nextStep_.bind(this);
this.apply = this.apply_.bind(this); this.apply = this.apply_.bind(this);
} }
/** /**
* Sets new callback * Sets new callback
* *
* @param {function()} callback New callback to call on succeed. * @param {function()} callback New callback to call on succeed.
*/ */
FunctionSequence.prototype.setCallback = function(callback) { setCallback(callback) {
this.callback_ = callback; this.callback_ = callback;
}; }
/** /**
* Sets new error callback * Sets new error callback
* *
* @param {function(string)} failureCallback New callback to call on failure. * @param {function(string)} failureCallback New callback to call on failure.
*/ */
FunctionSequence.prototype.setFailureCallback = function(failureCallback) { setFailureCallback(failureCallback) {
this.failureCallback_ = failureCallback; this.failureCallback_ = failureCallback;
}; }
/** /**
* Error handling function, which traces current error step, stops sequence * Error handling function, which traces current error step, stops sequence
* advancing and fires error callback. * advancing and fires error callback.
* *
* @param {string} err Error message. * @param {string} err Error message.
* @private * @private
*/ */
FunctionSequence.prototype.onError_ = function(err) { onError_(err) {
this.logger.vlog( this.logger.vlog(
'Failed step: ' + this.steps_[this.currentStepIdx_].name + ': ' + err); 'Failed step: ' + this.steps_[this.currentStepIdx_].name + ': ' + err);
if (!this.failed_) { if (!this.failed_) {
this.failed_ = true; this.failed_ = true;
this.failureCallback_(err); this.failureCallback_(err);
} }
}; }
/** /**
* Finishes sequence processing and jumps to the last step. * Finishes sequence processing and jumps to the last step.
* This method should not be used externally. In external * This method should not be used externally. In external
* cases should be used finish function, which is defined in closure and thus * cases should be used finish function, which is defined in closure and thus
* has access to internal variables of functionsequence. * has access to internal variables of functionsequence.
* @private * @private
*/ */
FunctionSequence.prototype.finish_ = function() { finish_() {
if (!this.failed_ && this.currentStepIdx_ < this.steps_.length) { if (!this.failed_ && this.currentStepIdx_ < this.steps_.length) {
this.currentStepIdx_ = this.steps_.length; this.currentStepIdx_ = this.steps_.length;
this.callback_(); this.callback_();
} }
}; }
/** /**
* Advances to next step. * Advances to next step.
* This method should not be used externally. In external * This method should not be used externally. In external
* cases should be used nextStep function, which is defined in closure and thus * cases should be used nextStep function, which is defined in closure and
* has access to internal variables of functionsequence. * thus has access to internal variables of functionsequence.
* @param {...} var_args Arguments to be passed to the next step. * @param {...} var_args Arguments to be passed to the next step.
* @private * @private
*/ */
FunctionSequence.prototype.nextStep_ = function(var_args) { nextStep_(var_args) {
if (this.failed_) { if (this.failed_) {
return; return;
} }
...@@ -95,37 +98,40 @@ FunctionSequence.prototype.nextStep_ = function(var_args) { ...@@ -95,37 +98,40 @@ FunctionSequence.prototype.nextStep_ = function(var_args) {
this.callback_.apply(this, arguments); this.callback_.apply(this, arguments);
} else { } else {
this.logger.vlog( this.logger.vlog(
'Attempting to start step [' + this.steps_[this.currentStepIdx_].name + 'Attempting to start step [' +
']'); this.steps_[this.currentStepIdx_].name + ']');
try { try {
this.steps_[this.currentStepIdx_].apply(this, arguments); this.steps_[this.currentStepIdx_].apply(this, arguments);
} catch (e) { } catch (e) {
this.onError(e.toString()); this.onError(e.toString());
} }
} }
}; }
/** /**
* This function should be called only once on start, so start sequence pipeline * This function should be called only once on start, so start sequence
* pipeline
* @param {...} var_args Arguments to be passed to the first step. * @param {...} var_args Arguments to be passed to the first step.
*/ */
FunctionSequence.prototype.start = function(var_args) { start(var_args) {
if (this.started) { if (this.started) {
throw new Error('"Start" method of FunctionSequence was called twice'); throw new Error('"Start" method of FunctionSequence was called twice');
} }
this.logger.log('Starting sequence with ' + arguments.length + ' arguments'); this.logger.log(
'Starting sequence with ' + arguments.length + ' arguments');
this.started = true; this.started = true;
this.nextStep.apply(this, arguments); this.nextStep.apply(this, arguments);
}; }
/** /**
* Add Function object mimics to FunctionSequence * Add Function object mimics to FunctionSequence
* @private * @private
* @param {*} obj Object. * @param {*} obj Object.
* @param {Array} args Arguments. * @param {Array} args Arguments.
*/ */
FunctionSequence.prototype.apply_ = function(obj, args) { apply_(obj, args) {
this.start.apply(this, args); this.start.apply(this, args);
}; }
}
...@@ -4,24 +4,23 @@ ...@@ -4,24 +4,23 @@
/** /**
* Cache of metadata for a FileEntry. * Cache of metadata for a FileEntry.
* @constructor
* @struct
*/ */
function MetadataCacheItem() { class MetadataCacheItem {
constructor() {
/** /**
* Map of property name and MetadataCacheItemProperty. * Map of property name and MetadataCacheItemProperty.
* @private {!Object<!MetadataCacheItemProperty>} * @private {!Object<!MetadataCacheItemProperty>}
* @const * @const
*/ */
this.properties_ = {}; this.properties_ = {};
} }
/** /**
* Creates requested names that need to be loaded. * Creates requested names that need to be loaded.
* @param {!Array<string>} names * @param {!Array<string>} names
* @return {!Array<string>} Property names that need to be loaded. * @return {!Array<string>} Property names that need to be loaded.
*/ */
MetadataCacheItem.prototype.createRequests = function(names) { createRequests(names) {
const loadRequested = []; const loadRequested = [];
for (let i = 0; i < names.length; i++) { for (let i = 0; i < names.length; i++) {
const name = names[i]; const name = names[i];
...@@ -35,14 +34,14 @@ MetadataCacheItem.prototype.createRequests = function(names) { ...@@ -35,14 +34,14 @@ MetadataCacheItem.prototype.createRequests = function(names) {
loadRequested.push(name); loadRequested.push(name);
} }
return loadRequested; return loadRequested;
}; }
/** /**
* Marks the given properies as loading. * Marks the given properties as loading.
* @param {number} requestId * @param {number} requestId
* @param {!Array<string>} names * @param {!Array<string>} names
*/ */
MetadataCacheItem.prototype.startRequests = function(requestId, names) { startRequests(requestId, names) {
for (let i = 0; i < names.length; i++) { for (let i = 0; i < names.length; i++) {
const name = names[i]; const name = names[i];
assert(!/Error$/.test(name)); assert(!/Error$/.test(name));
...@@ -52,15 +51,15 @@ MetadataCacheItem.prototype.startRequests = function(requestId, names) { ...@@ -52,15 +51,15 @@ MetadataCacheItem.prototype.startRequests = function(requestId, names) {
this.properties_[name].requestId = requestId; this.properties_[name].requestId = requestId;
this.properties_[name].state = MetadataCacheItemPropertyState.LOADING; this.properties_[name].state = MetadataCacheItemPropertyState.LOADING;
} }
}; }
/** /**
* Feeds the result of startRequests. * Feeds the result of startRequests.
* @param {number} requestId Request ID passed when calling startRequests. * @param {number} requestId Request ID passed when calling startRequests.
* @param {!MetadataItem} typedObject Map of property name and value. * @param {!MetadataItem} typedObject Map of property name and value.
* @return {boolean} Whether at least one property is updated or not. * @return {boolean} Whether at least one property is updated or not.
*/ */
MetadataCacheItem.prototype.storeProperties = function(requestId, typedObject) { storeProperties(requestId, typedObject) {
let changed = false; let changed = false;
const object = /** @type {!Object} */ (typedObject); const object = /** @type {!Object} */ (typedObject);
for (let name in object) { for (let name in object) {
...@@ -87,29 +86,29 @@ MetadataCacheItem.prototype.storeProperties = function(requestId, typedObject) { ...@@ -87,29 +86,29 @@ MetadataCacheItem.prototype.storeProperties = function(requestId, typedObject) {
this.properties_[name].state = MetadataCacheItemPropertyState.FULFILLED; this.properties_[name].state = MetadataCacheItemPropertyState.FULFILLED;
} }
return changed; return changed;
}; }
/** /**
* Marks the caches of all properties in the item as invalidates and forces to * Marks the caches of all properties in the item as invalidates and forces to
* reload at the next time of startRequests. * reload at the next time of startRequests.
* @param {number} requestId Request ID of the invalidation request. This must * @param {number} requestId Request ID of the invalidation request. This must
* be larger than other requets ID passed to the item before. * be larger than other requets ID passed to the item before.
*/ */
MetadataCacheItem.prototype.invalidate = function(requestId) { invalidate(requestId) {
for (const name in this.properties_) { for (const name in this.properties_) {
assert(this.properties_[name].requestId < requestId); assert(this.properties_[name].requestId < requestId);
this.properties_[name].requestId = requestId; this.properties_[name].requestId = requestId;
this.properties_[name].state = MetadataCacheItemPropertyState.INVALIDATED; this.properties_[name].state = MetadataCacheItemPropertyState.INVALIDATED;
} }
}; }
/** /**
* Obtains property for entries and names. * Obtains property for entries and names.
* Note that it returns invalidated properties also. * Note that it returns invalidated properties also.
* @param {!Array<string>} names * @param {!Array<string>} names
* @return {!MetadataItem} * @return {!MetadataItem}
*/ */
MetadataCacheItem.prototype.get = function(names) { get(names) {
const result = /** @type {!Object} */ (new MetadataItem()); const result = /** @type {!Object} */ (new MetadataItem());
for (let i = 0; i < names.length; i++) { for (let i = 0; i < names.length; i++) {
const name = names[i]; const name = names[i];
...@@ -120,13 +119,13 @@ MetadataCacheItem.prototype.get = function(names) { ...@@ -120,13 +119,13 @@ MetadataCacheItem.prototype.get = function(names) {
} }
} }
return /** @type {!MetadataItem} */ (result); return /** @type {!MetadataItem} */ (result);
}; }
/** /**
* Creates deep copy of the item. * Creates deep copy of the item.
* @return {!MetadataCacheItem} * @return {!MetadataCacheItem}
*/ */
MetadataCacheItem.prototype.clone = function() { clone() {
const clonedItem = new MetadataCacheItem(); const clonedItem = new MetadataCacheItem();
for (const name in this.properties_) { for (const name in this.properties_) {
const property = this.properties_[name]; const property = this.properties_[name];
...@@ -137,14 +136,14 @@ MetadataCacheItem.prototype.clone = function() { ...@@ -137,14 +136,14 @@ MetadataCacheItem.prototype.clone = function() {
clonedItem.properties_[name].state = property.state; clonedItem.properties_[name].state = property.state;
} }
return clonedItem; return clonedItem;
}; }
/** /**
* Returns whether all the given properties are fulfilled. * Returns whether all the given properties are fulfilled.
* @param {!Array<string>} names Property names. * @param {!Array<string>} names Property names.
* @return {boolean} * @return {boolean}
*/ */
MetadataCacheItem.prototype.hasFreshCache = function(names) { hasFreshCache(names) {
for (let i = 0; i < names.length; i++) { for (let i = 0; i < names.length; i++) {
if (!(this.properties_[names[i]] && if (!(this.properties_[names[i]] &&
this.properties_[names[i]].state === this.properties_[names[i]].state ===
...@@ -153,7 +152,8 @@ MetadataCacheItem.prototype.hasFreshCache = function(names) { ...@@ -153,7 +152,8 @@ MetadataCacheItem.prototype.hasFreshCache = function(names) {
} }
} }
return true; return true;
}; }
}
/** /**
* @enum {string} * @enum {string}
...@@ -166,10 +166,9 @@ const MetadataCacheItemPropertyState = { ...@@ -166,10 +166,9 @@ const MetadataCacheItemPropertyState = {
/** /**
* Cache of metadata for a property. * Cache of metadata for a property.
* @constructor
* @struct
*/ */
function MetadataCacheItemProperty() { class MetadataCacheItemProperty {
constructor() {
/** /**
* Cached value of property. * Cached value of property.
* @public {*} * @public {*}
...@@ -192,4 +191,5 @@ function MetadataCacheItemProperty() { ...@@ -192,4 +191,5 @@ function MetadataCacheItemProperty() {
* @public {MetadataCacheItemPropertyState} * @public {MetadataCacheItemPropertyState}
*/ */
this.state = MetadataCacheItemPropertyState.INVALIDATED; this.state = MetadataCacheItemPropertyState.INVALIDATED;
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment