diff options
author | Steve Block <steveblock@google.com> | 2009-10-08 17:19:54 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2009-10-20 00:41:58 +0100 |
commit | 231d4e3152a9c27a73b6ac7badbe6be673aa3ddf (patch) | |
tree | a6c7e2d6cd7bfa7011cc39abbb436142d7a4a7c8 /WebCore/storage/StorageMap.cpp | |
parent | e196732677050bd463301566a68a643b6d14b907 (diff) | |
download | external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.zip external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.gz external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.bz2 |
Merge webkit.org at R49305 : Automatic merge by git.
Change-Id: I8968561bc1bfd72b8923b7118d3728579c6dbcc7
Diffstat (limited to 'WebCore/storage/StorageMap.cpp')
-rw-r--r-- | WebCore/storage/StorageMap.cpp | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/WebCore/storage/StorageMap.cpp b/WebCore/storage/StorageMap.cpp index 32eb350..5498d9e 100644 --- a/WebCore/storage/StorageMap.cpp +++ b/WebCore/storage/StorageMap.cpp @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -30,20 +30,22 @@ namespace WebCore { -PassRefPtr<StorageMap> StorageMap::create() +PassRefPtr<StorageMap> StorageMap::create(unsigned quota) { - return adoptRef(new StorageMap); + return adoptRef(new StorageMap(quota)); } - -StorageMap::StorageMap() + +StorageMap::StorageMap(unsigned quota) : m_iterator(m_map.end()) , m_iteratorIndex(UINT_MAX) + , m_quotaSize(quota) // quota measured in bytes + , m_currentLength(0) { } PassRefPtr<StorageMap> StorageMap::copy() { - RefPtr<StorageMap> newMap = create(); + RefPtr<StorageMap> newMap = create(m_quotaSize); newMap->m_map = m_map; return newMap.release(); } @@ -54,22 +56,22 @@ void StorageMap::invalidateIterator() m_iteratorIndex = UINT_MAX; } -void StorageMap::setIteratorToIndex(unsigned index) const +void StorageMap::setIteratorToIndex(unsigned index) { // FIXME: Once we have bidirectional iterators for HashMap we can be more intelligent about this. - // The requested index will be closest to begin(), our current iterator, or end(), and we + // The requested index will be closest to begin(), our current iterator, or end(), and we // can take the shortest route. // Until that mechanism is available, we'll always increment our iterator from begin() or current. - + if (m_iteratorIndex == index) return; - + if (index < m_iteratorIndex) { m_iteratorIndex = 0; m_iterator = m_map.begin(); ASSERT(m_iterator != m_map.end()); } - + while (m_iteratorIndex < index) { ++m_iteratorIndex; ++m_iterator; @@ -82,11 +84,11 @@ unsigned StorageMap::length() const return m_map.size(); } -String StorageMap::key(unsigned index) const +String StorageMap::key(unsigned index) { if (index >= length()) return String(); - + setIteratorToIndex(index); return m_iterator->first; } @@ -96,27 +98,34 @@ String StorageMap::getItem(const String& key) const return m_map.get(key); } -PassRefPtr<StorageMap> StorageMap::setItem(const String& key, const String& value, String& oldValue) +PassRefPtr<StorageMap> StorageMap::setItem(const String& key, const String& value, String& oldValue, bool& quotaException) { ASSERT(!value.isNull()); - + quotaException = false; + // Implement copy-on-write semantics here. We're guaranteed that the only refs of StorageMaps belong to Storage objects // so if more than one Storage object refs this map, copy it before mutating it. if (refCount() > 1) { RefPtr<StorageMap> newStorageMap = copy(); - newStorageMap->setItem(key, value, oldValue); + newStorageMap->setItem(key, value, oldValue, quotaException); return newStorageMap.release(); } - pair<HashMap<String, String>::iterator, bool> addResult = m_map.add(key, value); + // Quota tracking. If the quota is enabled and this would go over it, bail. + oldValue = m_map.get(key); + unsigned newLength = m_currentLength + value.length() - oldValue.length(); + bool overQuota = newLength > m_quotaSize / sizeof(UChar); + bool overflow = (newLength > m_currentLength) != (value.length() > oldValue.length()); + ASSERT(!overflow); // If we're debugging, make a fuss. But it's still worth checking this in the following if statement. + if (m_quotaSize != noQuota && (overflow || overQuota)) { + quotaException = true; + return 0; + } + m_currentLength = newLength; - if (addResult.second) { - // There was no "oldValue" so null it out. - oldValue = String(); - } else { - oldValue = addResult.first->second; + pair<HashMap<String, String>::iterator, bool> addResult = m_map.add(key, value); + if (!addResult.second) addResult.first->second = value; - } invalidateIterator(); @@ -137,6 +146,10 @@ PassRefPtr<StorageMap> StorageMap::removeItem(const String& key, String& oldValu if (!oldValue.isNull()) invalidateIterator(); + // Update quota. + ASSERT(m_currentLength - oldValue.length() <= m_currentLength); + m_currentLength -= oldValue.length(); + return 0; } @@ -145,17 +158,20 @@ bool StorageMap::contains(const String& key) const return m_map.contains(key); } -void StorageMap::importItem(const String& key, const String& value) const +void StorageMap::importItem(const String& key, const String& value) { // Be sure to copy the keys/values as items imported on a background thread are destined // to cross a thread boundary - pair<HashMap<String, String>::iterator, bool> result = m_map.add(key.copy(), String()); + pair<HashMap<String, String>::iterator, bool> result = m_map.add(key.threadsafeCopy(), String()); if (result.second) - result.first->second = value.copy(); + result.first->second = value.threadsafeCopy(); + + // Update quota. + ASSERT(m_currentLength + value.length() >= m_currentLength); + m_currentLength += value.length(); } } #endif // ENABLE(DOM_STORAGE) - |