| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 'use strict'; | 5 'use strict'; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * MetadataCache is a map from Entry to an object containing properties. | 8 * MetadataCache is a map from Entry to an object containing properties. |
| 9 * Properties are divided by types, and all properties of one type are accessed | 9 * Properties are divided by types, and all properties of one type are accessed |
| 10 * at once. | 10 * at once. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 * type - metadata type; | 69 * type - metadata type; |
| 70 * callback - the callback. | 70 * callback - the callback. |
| 71 * @private | 71 * @private |
| 72 */ | 72 */ |
| 73 this.observers_ = []; | 73 this.observers_ = []; |
| 74 this.observerId_ = 0; | 74 this.observerId_ = 0; |
| 75 | 75 |
| 76 this.batchCount_ = 0; | 76 this.batchCount_ = 0; |
| 77 this.totalCount_ = 0; | 77 this.totalCount_ = 0; |
| 78 | 78 |
| 79 this.currentCacheSize_ = 0; |
| 80 |
| 79 /** | 81 /** |
| 80 * Time of first get query of the current batch. Items updated later than this | 82 * Time of first get query of the current batch. Items updated later than this |
| 81 * will not be evicted. | 83 * will not be evicted. |
| 82 * @private | 84 * @private |
| 83 */ | 85 */ |
| 84 this.lastBatchStart_ = new Date(); | 86 this.lastBatchStart_ = new Date(); |
| 85 } | 87 } |
| 86 | 88 |
| 87 /** | 89 /** |
| 88 * Observer type: it will be notified if the changed Entry is exactly the same | 90 * Observer type: it will be notified if the changed Entry is exactly the same |
| 89 * as the observed Entry. | 91 * as the observed Entry. |
| 90 */ | 92 */ |
| 91 MetadataCache.EXACT = 0; | 93 MetadataCache.EXACT = 0; |
| 92 | 94 |
| 93 /** | 95 /** |
| 94 * Observer type: it will be notified if the changed Entry is an immediate child | 96 * Observer type: it will be notified if the changed Entry is an immediate child |
| 95 * of the observed Entry. | 97 * of the observed Entry. |
| 96 */ | 98 */ |
| 97 MetadataCache.CHILDREN = 1; | 99 MetadataCache.CHILDREN = 1; |
| 98 | 100 |
| 99 /** | 101 /** |
| 100 * Observer type: it will be notified if the changed Entry is a descendant of | 102 * Observer type: it will be notified if the changed Entry is a descendant of |
| 101 * of the observer Entry. | 103 * of the observer Entry. |
| 102 */ | 104 */ |
| 103 MetadataCache.DESCENDANTS = 2; | 105 MetadataCache.DESCENDANTS = 2; |
| 104 | 106 |
| 105 /** | 107 /** |
| 106 * Minimum number of items in cache to start eviction. | 108 * Margin of the cache size. This amount of caches may be kept in addition. |
| 107 */ | 109 */ |
| 108 MetadataCache.EVICTION_NUMBER = 1000; | 110 MetadataCache.EVICTION_THRESHOLD_MARGIN = 500; |
| 109 | 111 |
| 110 /** | 112 /** |
| 111 * @param {VolumeManagerWrapper} volumeManager Volume manager instance. | 113 * @param {VolumeManagerWrapper} volumeManager Volume manager instance. |
| 112 * @return {MetadataCache!} The cache with all providers. | 114 * @return {MetadataCache!} The cache with all providers. |
| 113 */ | 115 */ |
| 114 MetadataCache.createFull = function(volumeManager) { | 116 MetadataCache.createFull = function(volumeManager) { |
| 115 var cache = new MetadataCache(); | 117 var cache = new MetadataCache(); |
| 116 cache.providers_.push(new FilesystemProvider()); | 118 cache.providers_.push(new FilesystemProvider()); |
| 117 cache.providers_.push(new DriveProvider(volumeManager)); | 119 cache.providers_.push(new DriveProvider(volumeManager)); |
| 118 cache.providers_.push(new ContentProvider()); | 120 cache.providers_.push(new ContentProvider()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 * @return {boolean} Whether all providers are ready. | 154 * @return {boolean} Whether all providers are ready. |
| 153 */ | 155 */ |
| 154 MetadataCache.prototype.isInitialized = function() { | 156 MetadataCache.prototype.isInitialized = function() { |
| 155 for (var index = 0; index < this.providers_.length; index++) { | 157 for (var index = 0; index < this.providers_.length; index++) { |
| 156 if (!this.providers_[index].isInitialized()) return false; | 158 if (!this.providers_[index].isInitialized()) return false; |
| 157 } | 159 } |
| 158 return true; | 160 return true; |
| 159 }; | 161 }; |
| 160 | 162 |
| 161 /** | 163 /** |
| 164 * Sets the size of cache. The actual cache size may be larger than the given |
| 165 * value. |
| 166 * @param {number} size The cache size to be set. |
| 167 */ |
| 168 MetadataCache.prototype.setCacheSize = function(size) { |
| 169 this.currentCacheSize_ = size; |
| 170 |
| 171 if (this.totalCount_ > this.currentEvictionThreshold_()) |
| 172 this.evict_(); |
| 173 }; |
| 174 |
| 175 /** |
| 176 * Returns the current threshold to evict caches. When the number of caches |
| 177 * exceeds this, the cache should be evicted. |
| 178 * @return {number} Threshold to evict caches. |
| 179 * @private |
| 180 */ |
| 181 MetadataCache.prototype.currentEvictionThreshold_ = function() { |
| 182 return this.currentCacheSize_ * 2 + MetadataCache.EVICTION_THRESHOLD_MARGIN; |
| 183 }; |
| 184 |
| 185 /** |
| 162 * Fetches the metadata, puts it in the cache, and passes to callback. | 186 * Fetches the metadata, puts it in the cache, and passes to callback. |
| 163 * If required metadata is already in the cache, does not fetch it again. | 187 * If required metadata is already in the cache, does not fetch it again. |
| 164 * @param {Entry|Array.<Entry>} entries The list of entries. May be just a | 188 * @param {Entry|Array.<Entry>} entries The list of entries. May be just a |
| 165 * single item. | 189 * single item. |
| 166 * @param {string} type The metadata type. | 190 * @param {string} type The metadata type. |
| 167 * @param {function(Object)} callback The metadata is passed to callback. | 191 * @param {function(Object)} callback The metadata is passed to callback. |
| 168 */ | 192 */ |
| 169 MetadataCache.prototype.get = function(entries, type, callback) { | 193 MetadataCache.prototype.get = function(entries, type, callback) { |
| 170 if (!(entries instanceof Array)) { | 194 if (!(entries instanceof Array)) { |
| 171 this.getOne(entries, type, callback); | 195 this.getOne(entries, type, callback); |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 if (this.batchCount_ === 1) | 475 if (this.batchCount_ === 1) |
| 452 this.lastBatchStart_ = new Date(); | 476 this.lastBatchStart_ = new Date(); |
| 453 }; | 477 }; |
| 454 | 478 |
| 455 /** | 479 /** |
| 456 * End batch updates. Notifies observers if all nested updates are finished. | 480 * End batch updates. Notifies observers if all nested updates are finished. |
| 457 */ | 481 */ |
| 458 MetadataCache.prototype.endBatchUpdates = function() { | 482 MetadataCache.prototype.endBatchUpdates = function() { |
| 459 this.batchCount_--; | 483 this.batchCount_--; |
| 460 if (this.batchCount_ !== 0) return; | 484 if (this.batchCount_ !== 0) return; |
| 461 if (this.totalCount_ > MetadataCache.EVICTION_NUMBER) | 485 if (this.totalCount_ > this.currentEvictionThreshold_()) |
| 462 this.evict_(); | 486 this.evict_(); |
| 463 for (var index = 0; index < this.observers_.length; index++) { | 487 for (var index = 0; index < this.observers_.length; index++) { |
| 464 var observer = this.observers_[index]; | 488 var observer = this.observers_[index]; |
| 465 var entries = []; | 489 var entries = []; |
| 466 var properties = {}; | 490 var properties = {}; |
| 467 for (var entryURL in observer.pending) { | 491 for (var entryURL in observer.pending) { |
| 468 if (observer.pending.hasOwnProperty(entryURL) && | 492 if (observer.pending.hasOwnProperty(entryURL) && |
| 469 entryURL in this.cache_) { | 493 entryURL in this.cache_) { |
| 470 var entry = observer.pending[entryURL]; | 494 var entry = observer.pending[entryURL]; |
| 471 entries.push(entry); | 495 entries.push(entry); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 | 530 |
| 507 /** | 531 /** |
| 508 * Removes the oldest items from the cache. | 532 * Removes the oldest items from the cache. |
| 509 * This method never removes the items from last batch. | 533 * This method never removes the items from last batch. |
| 510 * @private | 534 * @private |
| 511 */ | 535 */ |
| 512 MetadataCache.prototype.evict_ = function() { | 536 MetadataCache.prototype.evict_ = function() { |
| 513 var toRemove = []; | 537 var toRemove = []; |
| 514 | 538 |
| 515 // We leave only a half of items, so we will not call evict_ soon again. | 539 // We leave only a half of items, so we will not call evict_ soon again. |
| 516 var desiredCount = Math.round(MetadataCache.EVICTION_NUMBER / 2); | 540 var desiredCount = this.currentEvictionThreshold_(); |
| 517 var removeCount = this.totalCount_ - desiredCount; | 541 var removeCount = this.totalCount_ - desiredCount; |
| 518 for (var url in this.cache_) { | 542 for (var url in this.cache_) { |
| 519 if (this.cache_.hasOwnProperty(url) && | 543 if (this.cache_.hasOwnProperty(url) && |
| 520 this.cache_[url].time < this.lastBatchStart_) { | 544 this.cache_[url].time < this.lastBatchStart_) { |
| 521 toRemove.push(url); | 545 toRemove.push(url); |
| 522 } | 546 } |
| 523 } | 547 } |
| 524 | 548 |
| 525 toRemove.sort(function(a, b) { | 549 toRemove.sort(function(a, b) { |
| 526 var aTime = this.cache_[a].time; | 550 var aTime = this.cache_[a].time; |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 | 1044 |
| 1021 /** | 1045 /** |
| 1022 * Handles the 'log' message from the worker. | 1046 * Handles the 'log' message from the worker. |
| 1023 * @param {Array.<*>} arglist Log arguments. | 1047 * @param {Array.<*>} arglist Log arguments. |
| 1024 * @private | 1048 * @private |
| 1025 */ | 1049 */ |
| 1026 ContentProvider.prototype.onLog_ = function(arglist) { | 1050 ContentProvider.prototype.onLog_ = function(arglist) { |
| 1027 if (MetadataCache.log) // Avoid log spam by default. | 1051 if (MetadataCache.log) // Avoid log spam by default. |
| 1028 console.log.apply(console, ['metadata:'].concat(arglist)); | 1052 console.log.apply(console, ['metadata:'].concat(arglist)); |
| 1029 }; | 1053 }; |
| OLD | NEW |