OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Namespace | 5 // Namespace |
6 var importer = importer || {}; | 6 var importer = importer || {}; |
7 | 7 |
8 /** | 8 /** |
9 * Interface for import deduplicators. A duplicate finder is linked to an | 9 * Interface for import deduplicators. A duplicate finder is linked to an |
10 * import destination, and will check whether files already exist in that import | 10 * import destination, and will check whether files already exist in that import |
11 * destination. | 11 * destination. |
12 * @interface | 12 * @interface |
13 */ | 13 */ |
14 importer.DuplicateFinder = function() {}; | 14 importer.DuplicateFinder = function() {}; |
15 | 15 |
16 /** | 16 /** |
17 * Checks whether the given file already exists in the import destination. | 17 * Checks whether the given file already exists in the import destination. |
18 * @param {!FileEntry} entry The file entry to check. | 18 * @param {!FileEntry} entry The file entry to check. |
19 * @return {!Promise<boolean>} | 19 * @return {!Promise<boolean>} |
20 */ | 20 */ |
21 importer.DuplicateFinder.prototype.checkDuplicate; | 21 importer.DuplicateFinder.prototype.checkDuplicate; |
22 | 22 |
23 /** | 23 /** |
| 24 * A factory for producing duplicate finders. |
| 25 * @interface |
| 26 */ |
| 27 importer.DuplicateFinder.Factory = function() {}; |
| 28 |
| 29 /** @return {!importer.DuplicateFinder} */ |
| 30 importer.DuplicateFinder.Factory.prototype.create; |
| 31 |
| 32 /** |
24 * A duplicate finder for Google Drive. | 33 * A duplicate finder for Google Drive. |
| 34 * |
25 * @constructor | 35 * @constructor |
26 * @implements {importer.DuplicateFinder} | 36 * @implements {importer.DuplicateFinder} |
27 * @struct | 37 * @struct |
28 */ | 38 */ |
29 importer.DriveDuplicateFinder = function() { | 39 importer.DriveDuplicateFinder = function() { |
30 /** @private {Promise<string>} */ | 40 /** @private {Promise<string>} */ |
31 this.driveIdPromise_ = null; | 41 this.driveIdPromise_ = null; |
| 42 |
| 43 /** |
| 44 * Aggregate time spent computing content hashes (in ms). |
| 45 * @private {number} |
| 46 */ |
| 47 this.computeHashTime_ = 0; |
| 48 |
| 49 /** |
| 50 * Aggregate time spent performing content hash searches (in ms). |
| 51 * @private {number} |
| 52 */ |
| 53 this.searchHashTime_ = 0; |
32 }; | 54 }; |
33 | 55 |
| 56 /** |
| 57 * @typedef {{ |
| 58 * computeHashTime: number, |
| 59 * searchHashTime: number |
| 60 * }} |
| 61 */ |
| 62 importer.DriveDuplicateFinder.Statistics; |
| 63 |
34 /** @override */ | 64 /** @override */ |
35 importer.DriveDuplicateFinder.prototype.checkDuplicate = function(entry) { | 65 importer.DriveDuplicateFinder.prototype.checkDuplicate = function(entry) { |
36 return importer.DriveDuplicateFinder.computeHash_(entry) | 66 return this.computeHash_(entry) |
37 .then(this.findByHash_.bind(this)) | 67 .then(this.findByHash_.bind(this)) |
38 .then( | 68 .then( |
39 /** | 69 /** |
40 * @param {!Array<string>} urls | 70 * @param {!Array<string>} urls |
41 * @return {boolean} | 71 * @return {boolean} |
42 */ | 72 */ |
43 function(urls) { | 73 function(urls) { |
44 return urls.length > 0; | 74 return urls.length > 0; |
45 }); | 75 }); |
46 }; | 76 }; |
47 | 77 |
48 /** | 78 /** |
49 * Computes the content hash for the given file entry. | 79 * Computes the content hash for the given file entry. |
50 * @param {!FileEntry} entry | 80 * @param {!FileEntry} entry |
51 * @private | 81 * @private |
52 */ | 82 */ |
53 importer.DriveDuplicateFinder.computeHash_ = function(entry) { | 83 importer.DriveDuplicateFinder.prototype.computeHash_ = function(entry) { |
54 return new Promise( | 84 return new Promise( |
| 85 /** @this {importer.DriveDuplicateFinder} */ |
55 function(resolve, reject) { | 86 function(resolve, reject) { |
| 87 var startTime = new Date().getTime(); |
56 chrome.fileManagerPrivate.computeChecksum( | 88 chrome.fileManagerPrivate.computeChecksum( |
57 entry.toURL(), | 89 entry.toURL(), |
58 /** @param {string} result The content hash. */ | 90 /** @param {string} result The content hash. */ |
59 function(result) { | 91 function(result) { |
| 92 var endTime = new Date().getTime(); |
| 93 this.searchHashTime_ += endTime - startTime; |
60 if (chrome.runtime.lastError) { | 94 if (chrome.runtime.lastError) { |
61 reject(chrome.runtime.lastError); | 95 reject(chrome.runtime.lastError); |
62 } else { | 96 } else { |
63 resolve(result); | 97 resolve(result); |
64 } | 98 } |
65 }); | 99 }); |
66 }); | 100 }.bind(this)); |
67 }; | 101 }; |
68 | 102 |
69 /** | 103 /** |
70 * Finds files with content hashes matching the given hash. | 104 * Finds files with content hashes matching the given hash. |
71 * @param {string} hash The content hash of the file to find. | 105 * @param {string} hash The content hash of the file to find. |
72 * @return {!Promise<Array<string>>} The URLs of the found files. If there are | 106 * @return {!Promise<Array<string>>} The URLs of the found files. If there are |
73 * no matches, the list will be empty. | 107 * no matches, the list will be empty. |
74 * @private | 108 * @private |
75 */ | 109 */ |
76 importer.DriveDuplicateFinder.prototype.findByHash_ = function(hash) { | 110 importer.DriveDuplicateFinder.prototype.findByHash_ = function(hash) { |
77 return this.getDriveId_() | 111 return this.getDriveId_() |
78 .then(importer.DriveDuplicateFinder.searchFilesByHash_.bind(null, hash)); | 112 .then(this.searchFilesByHash_.bind(this, hash)); |
79 }; | 113 }; |
80 | 114 |
81 /** | 115 /** |
82 * @return {!Promise<string>} ID of the user's Drive volume. | 116 * @return {!Promise<string>} ID of the user's Drive volume. |
83 * @private | 117 * @private |
84 */ | 118 */ |
85 importer.DriveDuplicateFinder.prototype.getDriveId_ = function() { | 119 importer.DriveDuplicateFinder.prototype.getDriveId_ = function() { |
86 if (!this.driveIdPromise_) { | 120 if (!this.driveIdPromise_) { |
87 this.driveIdPromise_ = VolumeManager.getInstance() | 121 this.driveIdPromise_ = VolumeManager.getInstance() |
88 .then( | 122 .then( |
89 /** | 123 /** |
90 * @param {!VolumeManager} volumeManager | 124 * @param {!VolumeManager} volumeManager |
91 * @return {string} ID of the user's Drive volume. | 125 * @return {string} ID of the user's Drive volume. |
92 */ | 126 */ |
93 function(volumeManager) { | 127 function(volumeManager) { |
94 return volumeManager.getCurrentProfileVolumeInfo( | 128 return volumeManager.getCurrentProfileVolumeInfo( |
95 VolumeManagerCommon.VolumeType.DRIVE).volumeId; | 129 VolumeManagerCommon.VolumeType.DRIVE).volumeId; |
96 }); | 130 }); |
97 } | 131 } |
98 return this.driveIdPromise_; | 132 return this.driveIdPromise_; |
99 }; | 133 }; |
100 | 134 |
101 /** | 135 /** |
102 * A promise-based wrapper for chrome.fileManagerPrivate.searchFilesByHashes. | 136 * A promise-based wrapper for chrome.fileManagerPrivate.searchFilesByHashes. |
103 * @param {string} hash The content hash to search for. | 137 * @param {string} hash The content hash to search for. |
104 * @param {string} volumeId The volume to search. | 138 * @param {string} volumeId The volume to search. |
105 * @return <!Promise<Array<string>>> A list of file URLs. | 139 * @return <!Promise<Array<string>>> A list of file URLs. |
106 */ | 140 */ |
107 importer.DriveDuplicateFinder.searchFilesByHash_ = function(hash, volumeId) { | 141 importer.DriveDuplicateFinder.prototype.searchFilesByHash_ = |
| 142 function(hash, volumeId) { |
108 return new Promise( | 143 return new Promise( |
| 144 /** @this {importer.DriveDuplicateFinder} */ |
109 function(resolve, reject) { | 145 function(resolve, reject) { |
| 146 var startTime = new Date().getTime(); |
110 chrome.fileManagerPrivate.searchFilesByHashes( | 147 chrome.fileManagerPrivate.searchFilesByHashes( |
111 volumeId, | 148 volumeId, |
112 [hash], | 149 [hash], |
113 /** @param {!Object<string, Array<string>>} urls */ | 150 /** |
| 151 * @param {!Object<string, Array<string>>} urls |
| 152 * @this {importer.DriveDuplicateFinder} |
| 153 */ |
114 function(urls) { | 154 function(urls) { |
| 155 var endTime = new Date().getTime(); |
| 156 this.searchHashTime_ += endTime - startTime; |
115 if (chrome.runtime.lastError) { | 157 if (chrome.runtime.lastError) { |
116 reject(chrome.runtime.lastError); | 158 reject(chrome.runtime.lastError); |
117 } else { | 159 } else { |
118 resolve(urls[hash]); | 160 resolve(urls[hash]); |
119 } | 161 } |
120 }); | 162 }.bind(this)); |
121 }); | 163 }.bind(this)); |
122 }; | 164 }; |
| 165 |
| 166 /** @return {!importer.DriveDuplicateFinder.Statistics} */ |
| 167 importer.DriveDuplicateFinder.prototype.getStatistics = function() { |
| 168 return { |
| 169 computeHashTime: this.computeHashTime_, |
| 170 searchHashTime: this.searchHashTime_ |
| 171 }; |
| 172 }; |
| 173 |
| 174 /** |
| 175 * @constructor |
| 176 * @implements {importer.DuplicateFinder.Factory} |
| 177 */ |
| 178 importer.DriveDuplicateFinder.Factory = function() {}; |
| 179 |
| 180 /** @override */ |
| 181 importer.DriveDuplicateFinder.Factory.prototype.create = function() { |
| 182 return new importer.DriveDuplicateFinder(); |
| 183 }; |
OLD | NEW |