| 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 #include "webkit/dom_storage/session_storage_database.h" | 5 #include "webkit/dom_storage/session_storage_database.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
| 10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 // | namespace-3-origin2 | 2 (shallow copy) | | 34 // | namespace-3-origin2 | 2 (shallow copy) | |
| 35 // | next-namespace-id | 4 | | 35 // | next-namespace-id | 4 | |
| 36 // | next-map-id | 4 | | 36 // | next-map-id | 4 | |
| 37 | 37 |
| 38 namespace dom_storage { | 38 namespace dom_storage { |
| 39 | 39 |
| 40 SessionStorageDatabase::SessionStorageDatabase(const FilePath& file_path) | 40 SessionStorageDatabase::SessionStorageDatabase(const FilePath& file_path) |
| 41 : file_path_(file_path), | 41 : file_path_(file_path), |
| 42 db_error_(false), | 42 db_error_(false), |
| 43 is_inconsistent_(false), | 43 is_inconsistent_(false), |
| 44 namespace_offset_(0) { | 44 next_namespace_id_(0), |
| 45 next_negative_namespace_id_(-1) { |
| 46 } |
| 47 |
| 48 SessionStorageDatabase::SessionStorageDatabase( |
| 49 const FilePath& file_path, |
| 50 const SessionStorageAssociatedCallback& associated_callback) |
| 51 : file_path_(file_path), |
| 52 db_error_(false), |
| 53 is_inconsistent_(false), |
| 54 next_namespace_id_(0), |
| 55 next_negative_namespace_id_(-1), |
| 56 associated_callback_(associated_callback) { |
| 45 } | 57 } |
| 46 | 58 |
| 47 SessionStorageDatabase::~SessionStorageDatabase() { | 59 SessionStorageDatabase::~SessionStorageDatabase() { |
| 48 } | 60 } |
| 49 | 61 |
| 50 void SessionStorageDatabase::ReadAreaValues(int64 namespace_id, | 62 void SessionStorageDatabase::ReadAreaValues(int64 namespace_id, |
| 51 const GURL& origin, | 63 const GURL& origin, |
| 52 ValuesMap* result) { | 64 ValuesMap* result) { |
| 53 // We don't create a database if it doesn't exist. In that case, there is | 65 // We don't create a database if it doesn't exist. In that case, there is |
| 54 // nothing to be added to the result. | 66 // nothing to be added to the result. |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 return DatabaseErrorCheck(s.ok()); | 164 return DatabaseErrorCheck(s.ok()); |
| 153 } | 165 } |
| 154 | 166 |
| 155 bool SessionStorageDatabase::DeleteArea(int64 namespace_id, | 167 bool SessionStorageDatabase::DeleteArea(int64 namespace_id, |
| 156 const GURL& origin) { | 168 const GURL& origin) { |
| 157 if (!LazyOpen(false)) { | 169 if (!LazyOpen(false)) { |
| 158 // No need to create the database if it doesn't exist. | 170 // No need to create the database if it doesn't exist. |
| 159 return true; | 171 return true; |
| 160 } | 172 } |
| 161 leveldb::WriteBatch batch; | 173 leveldb::WriteBatch batch; |
| 162 if (!DeleteArea(namespace_id, origin.spec(), &batch)) | 174 if (!DeleteAreaHelper(namespace_id, origin.spec(), &batch)) |
| 163 return false; | 175 return false; |
| 164 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch); | 176 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch); |
| 165 return DatabaseErrorCheck(s.ok()); | 177 return DatabaseErrorCheck(s.ok()); |
| 166 } | 178 } |
| 167 | 179 |
| 168 bool SessionStorageDatabase::DeleteNamespace(int64 namespace_id) { | 180 bool SessionStorageDatabase::DeleteNamespace(int64 namespace_id) { |
| 169 if (!LazyOpen(false)) { | 181 if (!LazyOpen(false)) { |
| 170 // No need to create the database if it doesn't exist. | 182 // No need to create the database if it doesn't exist. |
| 171 return true; | 183 return true; |
| 172 } | 184 } |
| 173 // Itereate through the areas in the namespace. | 185 // Itereate through the areas in the namespace. |
| 174 leveldb::WriteBatch batch; | 186 leveldb::WriteBatch batch; |
| 175 std::map<std::string, std::string> areas; | 187 std::map<std::string, std::string> areas; |
| 176 if (!GetAreasInNamespace(namespace_id, &areas)) | 188 if (!GetAreasInNamespace(namespace_id, &areas)) |
| 177 return false; | 189 return false; |
| 178 for (std::map<std::string, std::string>::const_iterator it = areas.begin(); | 190 for (std::map<std::string, std::string>::const_iterator it = areas.begin(); |
| 179 it != areas.end(); ++it) { | 191 it != areas.end(); ++it) { |
| 180 const std::string& origin = it->first; | 192 const std::string& origin = it->first; |
| 181 if (!DeleteArea(namespace_id, origin, &batch)) | 193 if (!DeleteAreaHelper(namespace_id, origin, &batch)) |
| 182 return false; | 194 return false; |
| 183 } | 195 } |
| 184 batch.Delete(NamespaceStartKey(namespace_id, namespace_offset_)); | 196 batch.Delete(NamespaceStartKey(namespace_id)); |
| 185 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch); | 197 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch); |
| 186 return DatabaseErrorCheck(s.ok()); | 198 return DatabaseErrorCheck(s.ok()); |
| 187 } | 199 } |
| 188 | 200 |
| 201 bool SessionStorageDatabase::ReadNamespaceIds( |
| 202 std::vector<int64>* namespace_ids) { |
| 203 if (!LazyOpen(true)) |
| 204 return false; |
| 205 |
| 206 std::string namespace_prefix = NamespacePrefix(); |
| 207 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); |
| 208 it->Seek(namespace_prefix); |
| 209 if (it->status().IsNotFound()) |
| 210 return true; |
| 211 |
| 212 if (!DatabaseErrorCheck(it->status().ok())) |
| 213 return false; |
| 214 |
| 215 // Skip the dummy entry "namespace-" and iterate the namespaces. |
| 216 for (it->Next(); it->Valid(); it->Next()) { |
| 217 std::string key = it->key().ToString(); |
| 218 if (key.find(namespace_prefix) != 0) { |
| 219 // Iterated past the "namespace-" keys. |
| 220 break; |
| 221 } |
| 222 size_t second_dash = key.find('-', namespace_prefix.length()); |
| 223 if (second_dash != std::string::npos) |
| 224 continue; |
| 225 |
| 226 // The key is of the form "namespace-<namespaceid>". |
| 227 std::string namespace_id_str = key.substr(namespace_prefix.length()); |
| 228 int64 real_namespace_id; |
| 229 bool conversion_ok = |
| 230 base::StringToInt64(namespace_id_str, &real_namespace_id); |
| 231 if (!ConsistencyCheck(conversion_ok)) |
| 232 return false; |
| 233 std::map<int64, int64>::const_iterator it = |
| 234 real_id_to_id_.find(real_namespace_id); |
| 235 if (it != real_id_to_id_.end()) { |
| 236 namespace_ids->push_back(it->second); |
| 237 } else { |
| 238 // There is no known upper layer ID for this namespace. Create one. (The |
| 239 // upper layer will only create positive IDs, so this won't overlap with |
| 240 // the IDs created by it.) |
| 241 int64 upper_layer_id = next_negative_namespace_id_--; |
| 242 AssociateNamespaceId(upper_layer_id, real_namespace_id); |
| 243 namespace_ids->push_back(upper_layer_id); |
| 244 } |
| 245 } |
| 246 return true; |
| 247 } |
| 248 |
| 249 void SessionStorageDatabase::AssociateNamespaceId(int64 namespace_id, |
| 250 int64 real_id) { |
| 251 id_to_real_id_[namespace_id] = real_id; |
| 252 real_id_to_id_[real_id] = namespace_id; |
| 253 } |
| 254 |
| 189 bool SessionStorageDatabase::LazyOpen(bool create_if_needed) { | 255 bool SessionStorageDatabase::LazyOpen(bool create_if_needed) { |
| 190 base::AutoLock auto_lock(db_lock_); | 256 base::AutoLock auto_lock(db_lock_); |
| 191 if (db_error_ || is_inconsistent_) { | 257 if (db_error_ || is_inconsistent_) { |
| 192 // Don't try to open a database that we know has failed already. | 258 // Don't try to open a database that we know has failed already. |
| 193 return false; | 259 return false; |
| 194 } | 260 } |
| 195 if (IsOpen()) | 261 if (IsOpen()) |
| 196 return true; | 262 return true; |
| 197 | 263 |
| 198 if (!create_if_needed && | 264 if (!create_if_needed && |
| (...skipping 18 matching lines...) Expand all Loading... |
| 217 s = TryToOpen(&db); | 283 s = TryToOpen(&db); |
| 218 if (!s.ok()) { | 284 if (!s.ok()) { |
| 219 LOG(WARNING) << "Failed to open leveldb in " << file_path_.value() | 285 LOG(WARNING) << "Failed to open leveldb in " << file_path_.value() |
| 220 << ", error: " << s.ToString(); | 286 << ", error: " << s.ToString(); |
| 221 DCHECK(db == NULL); | 287 DCHECK(db == NULL); |
| 222 db_error_ = true; | 288 db_error_ = true; |
| 223 return false; | 289 return false; |
| 224 } | 290 } |
| 225 } | 291 } |
| 226 db_.reset(db); | 292 db_.reset(db); |
| 227 | 293 return GetNextNamespaceId(&next_namespace_id_); |
| 228 return GetNextNamespaceId(&namespace_offset_); | |
| 229 } | 294 } |
| 230 | 295 |
| 231 leveldb::Status SessionStorageDatabase::TryToOpen(leveldb::DB** db) { | 296 leveldb::Status SessionStorageDatabase::TryToOpen(leveldb::DB** db) { |
| 232 leveldb::Options options; | 297 leveldb::Options options; |
| 233 // The directory exists but a valid leveldb database might not exist inside it | 298 // The directory exists but a valid leveldb database might not exist inside it |
| 234 // (e.g., a subset of the needed files might be missing). Handle this | 299 // (e.g., a subset of the needed files might be missing). Handle this |
| 235 // situation gracefully by creating the database now. | 300 // situation gracefully by creating the database now. |
| 236 options.create_if_missing = true; | 301 options.create_if_missing = true; |
| 237 #if defined(OS_WIN) | 302 #if defined(OS_WIN) |
| 238 return leveldb::DB::Open(options, WideToUTF8(file_path_.value()), db); | 303 return leveldb::DB::Open(options, WideToUTF8(file_path_.value()), db); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 leveldb::WriteBatch* batch) { | 342 leveldb::WriteBatch* batch) { |
| 278 leveldb::Slice namespace_prefix = NamespacePrefix(); | 343 leveldb::Slice namespace_prefix = NamespacePrefix(); |
| 279 std::string dummy; | 344 std::string dummy; |
| 280 leveldb::Status s = db_->Get(leveldb::ReadOptions(), namespace_prefix, | 345 leveldb::Status s = db_->Get(leveldb::ReadOptions(), namespace_prefix, |
| 281 &dummy); | 346 &dummy); |
| 282 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound())) | 347 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound())) |
| 283 return false; | 348 return false; |
| 284 if (s.IsNotFound()) | 349 if (s.IsNotFound()) |
| 285 batch->Put(namespace_prefix, ""); | 350 batch->Put(namespace_prefix, ""); |
| 286 | 351 |
| 287 std::string namespace_start_key = | 352 std::string namespace_start_key = NamespaceStartKey(namespace_id); |
| 288 NamespaceStartKey(namespace_id, namespace_offset_); | |
| 289 s = db_->Get(leveldb::ReadOptions(), namespace_start_key, &dummy); | 353 s = db_->Get(leveldb::ReadOptions(), namespace_start_key, &dummy); |
| 290 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound())) | 354 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound())) |
| 291 return false; | 355 return false; |
| 292 if (s.IsNotFound()) { | 356 if (s.IsNotFound()) { |
| 293 batch->Put(namespace_start_key, ""); | 357 batch->Put(namespace_start_key, ""); |
| 294 return UpdateNextNamespaceId(namespace_id, batch); | 358 return UpdateNextNamespaceId(namespace_id, batch); |
| 295 } | 359 } |
| 296 return CallerErrorCheck(ok_if_exists); | 360 return CallerErrorCheck(ok_if_exists); |
| 297 } | 361 } |
| 298 | 362 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 309 bool conversion_ok = | 373 bool conversion_ok = |
| 310 base::StringToInt64(next_namespace_id_string, next_namespace_id); | 374 base::StringToInt64(next_namespace_id_string, next_namespace_id); |
| 311 return ConsistencyCheck(conversion_ok); | 375 return ConsistencyCheck(conversion_ok); |
| 312 } | 376 } |
| 313 | 377 |
| 314 bool SessionStorageDatabase::UpdateNextNamespaceId(int64 namespace_id, | 378 bool SessionStorageDatabase::UpdateNextNamespaceId(int64 namespace_id, |
| 315 leveldb::WriteBatch* batch) { | 379 leveldb::WriteBatch* batch) { |
| 316 int64 next_namespace_id; | 380 int64 next_namespace_id; |
| 317 if (!GetNextNamespaceId(&next_namespace_id)) | 381 if (!GetNextNamespaceId(&next_namespace_id)) |
| 318 return false; | 382 return false; |
| 319 if (next_namespace_id < namespace_id + namespace_offset_ + 1) { | 383 int64 real_id; |
| 320 next_namespace_id = namespace_id + namespace_offset_ + 1; | 384 if (!GetRealId(namespace_id, &real_id)) |
| 385 return false; |
| 386 if (next_namespace_id < real_id + 1) { |
| 387 next_namespace_id = real_id + 1; |
| 321 batch->Put(NextNamespaceIdKey(), base::Int64ToString(next_namespace_id)); | 388 batch->Put(NextNamespaceIdKey(), base::Int64ToString(next_namespace_id)); |
| 322 } | 389 } |
| 323 return true; | 390 return true; |
| 324 } | 391 } |
| 325 | 392 |
| 326 bool SessionStorageDatabase::GetAreasInNamespace( | 393 bool SessionStorageDatabase::GetAreasInNamespace( |
| 327 int64 namespace_id, | 394 int64 namespace_id, |
| 328 std::map<std::string, std::string>* areas) { | 395 std::map<std::string, std::string>* areas) { |
| 329 return GetAreasInNamespace(NamespaceIdStr(namespace_id, namespace_offset_), | 396 return GetAreasInNamespace(NamespaceIdStr(namespace_id), areas); |
| 330 areas); | |
| 331 } | 397 } |
| 332 | 398 |
| 333 bool SessionStorageDatabase::GetAreasInNamespace( | 399 bool SessionStorageDatabase::GetAreasInNamespace( |
| 334 const std::string& namespace_id_str, | 400 const std::string& namespace_id_str, |
| 335 std::map<std::string, std::string>* areas) { | 401 std::map<std::string, std::string>* areas) { |
| 336 std::string namespace_start_key = NamespaceStartKey(namespace_id_str); | 402 std::string namespace_start_key = NamespaceStartKey(namespace_id_str); |
| 337 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); | 403 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); |
| 338 it->Seek(namespace_start_key); | 404 it->Seek(namespace_start_key); |
| 339 if (it->status().IsNotFound()) { | 405 if (it->status().IsNotFound()) { |
| 340 // The namespace_start_key is not found when the namespace doesn't contain | 406 // The namespace_start_key is not found when the namespace doesn't contain |
| 341 // any areas. We don't need to do anything. | 407 // any areas. We don't need to do anything. |
| 342 return true; | 408 return true; |
| 343 } | 409 } |
| 344 if (!DatabaseErrorCheck(it->status().ok())) | 410 if (!DatabaseErrorCheck(it->status().ok())) |
| 345 return false; | 411 return false; |
| 346 | 412 |
| 347 // Skip the dummy entry "namespace-<namespaceid>" and iterate the origins. | 413 // Skip the dummy entry "namespace-<namespaceid>" and iterate the origins. |
| 348 for (it->Next(); it->Valid(); it->Next()) { | 414 for (it->Next(); it->Valid(); it->Next()) { |
| 349 std::string key = it->key().ToString(); | 415 std::string key = it->key().ToString(); |
| 350 if (key.find(namespace_start_key) != 0) { | 416 if (key.find(namespace_start_key) != 0) { |
| 351 // Iterated past the origins for this namespace. | 417 // Iterated past the origins for this namespace. |
| 352 break; | 418 break; |
| 353 } | 419 } |
| 354 size_t second_dash = key.find('-', namespace_start_key.length()); | 420 size_t second_dash = key.find('-', namespace_start_key.length()); |
| 355 if (!ConsistencyCheck(second_dash != std::string::npos)) | 421 if (second_dash == std::string::npos) |
| 356 return false; | 422 break; |
| 357 std::string origin = key.substr(second_dash + 1); | 423 std::string origin = key.substr(second_dash + 1); |
| 358 std::string map_id = it->value().ToString(); | 424 std::string map_id = it->value().ToString(); |
| 359 (*areas)[origin] = map_id; | 425 (*areas)[origin] = map_id; |
| 360 } | 426 } |
| 361 return true; | 427 return true; |
| 362 } | 428 } |
| 363 | 429 |
| 364 void SessionStorageDatabase::AddAreaToNamespace(int64 namespace_id, | 430 void SessionStorageDatabase::AddAreaToNamespace(int64 namespace_id, |
| 365 const std::string& origin, | 431 const std::string& origin, |
| 366 const std::string& map_id, | 432 const std::string& map_id, |
| 367 leveldb::WriteBatch* batch) { | 433 leveldb::WriteBatch* batch) { |
| 368 std::string namespace_key = NamespaceKey( | 434 std::string namespace_key = |
| 369 NamespaceIdStr(namespace_id, namespace_offset_), origin); | 435 NamespaceKey(NamespaceIdStr(namespace_id), origin); |
| 370 batch->Put(namespace_key, map_id); | 436 batch->Put(namespace_key, map_id); |
| 371 } | 437 } |
| 372 | 438 |
| 373 bool SessionStorageDatabase::DeleteArea(int64 namespace_id, | 439 bool SessionStorageDatabase::DeleteAreaHelper(int64 namespace_id, |
| 374 const std::string& origin, | 440 const std::string& origin, |
| 375 leveldb::WriteBatch* batch) { | 441 leveldb::WriteBatch* batch) { |
| 376 return DeleteArea(NamespaceIdStr(namespace_id, namespace_offset_), | 442 return DeleteAreaHelper(NamespaceIdStr(namespace_id), origin, batch); |
| 377 origin, batch); | |
| 378 } | 443 } |
| 379 | 444 |
| 380 bool SessionStorageDatabase::DeleteArea(const std::string& namespace_id_str, | 445 bool SessionStorageDatabase::DeleteAreaHelper( |
| 381 const std::string& origin, | 446 const std::string& namespace_id_str, |
| 382 leveldb::WriteBatch* batch) { | 447 const std::string& origin, |
| 448 leveldb::WriteBatch* batch) { |
| 383 std::string map_id; | 449 std::string map_id; |
| 384 bool exists; | 450 bool exists; |
| 385 if (!GetMapForArea(namespace_id_str, origin, &exists, &map_id)) | 451 if (!GetMapForArea(namespace_id_str, origin, &exists, &map_id)) |
| 386 return false; | 452 return false; |
| 387 if (!exists) | 453 if (!exists) |
| 388 return true; // Nothing to delete. | 454 return true; // Nothing to delete. |
| 389 if (!DecreaseMapRefCount(map_id, 1, batch)) | 455 if (!DecreaseMapRefCount(map_id, 1, batch)) |
| 390 return false; | 456 return false; |
| 391 std::string namespace_key = NamespaceKey(namespace_id_str, origin); | 457 std::string namespace_key = NamespaceKey(namespace_id_str, origin); |
| 392 batch->Delete(namespace_key); | 458 batch->Delete(namespace_key); |
| 393 return true; | 459 return true; |
| 394 } | 460 } |
| 395 | 461 |
| 396 bool SessionStorageDatabase::GetMapForArea(int64 namespace_id, | 462 bool SessionStorageDatabase::GetMapForArea(int64 namespace_id, |
| 397 const GURL& origin, | 463 const GURL& origin, |
| 398 bool* exists, | 464 bool* exists, |
| 399 std::string* map_id) { | 465 std::string* map_id) { |
| 400 return GetMapForArea( | 466 int64 real_id; |
| 401 base::Int64ToString(namespace_id + namespace_offset_), | 467 if (!GetRealId(namespace_id, &real_id)) |
| 402 origin.spec(), exists, map_id); | 468 return false; |
| 469 return GetMapForArea(base::Int64ToString(real_id), origin.spec(), |
| 470 exists, map_id); |
| 403 } | 471 } |
| 404 | 472 |
| 405 bool SessionStorageDatabase::GetMapForArea(const std::string& namespace_id_str, | 473 bool SessionStorageDatabase::GetMapForArea(const std::string& namespace_id_str, |
| 406 const std::string& origin, | 474 const std::string& origin, |
| 407 bool* exists, std::string* map_id) { | 475 bool* exists, std::string* map_id) { |
| 408 std::string namespace_key = NamespaceKey(namespace_id_str, origin); | 476 std::string namespace_key = NamespaceKey(namespace_id_str, origin); |
| 409 leveldb::Status s = db_->Get(leveldb::ReadOptions(), namespace_key, map_id); | 477 leveldb::Status s = db_->Get(leveldb::ReadOptions(), namespace_key, map_id); |
| 410 if (s.IsNotFound()) { | 478 if (s.IsNotFound()) { |
| 411 *exists = false; | 479 *exists = false; |
| 412 return true; | 480 return true; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 425 return false; | 493 return false; |
| 426 int64 next_map_id = 0; | 494 int64 next_map_id = 0; |
| 427 if (s.IsNotFound()) { | 495 if (s.IsNotFound()) { |
| 428 *map_id = "0"; | 496 *map_id = "0"; |
| 429 } else { | 497 } else { |
| 430 bool conversion_ok = base::StringToInt64(*map_id, &next_map_id); | 498 bool conversion_ok = base::StringToInt64(*map_id, &next_map_id); |
| 431 if (!ConsistencyCheck(conversion_ok)) | 499 if (!ConsistencyCheck(conversion_ok)) |
| 432 return false; | 500 return false; |
| 433 } | 501 } |
| 434 batch->Put(next_map_id_key, base::Int64ToString(++next_map_id)); | 502 batch->Put(next_map_id_key, base::Int64ToString(++next_map_id)); |
| 435 std::string namespace_key = | 503 std::string namespace_key = NamespaceKey(namespace_id, origin); |
| 436 NamespaceKey(namespace_id, namespace_offset_, origin); | |
| 437 batch->Put(namespace_key, *map_id); | 504 batch->Put(namespace_key, *map_id); |
| 438 batch->Put(MapRefCountKey(*map_id), "1"); | 505 batch->Put(MapRefCountKey(*map_id), "1"); |
| 439 return true; | 506 return true; |
| 440 } | 507 } |
| 441 | 508 |
| 442 bool SessionStorageDatabase::ReadMap(const std::string& map_id, | 509 bool SessionStorageDatabase::ReadMap(const std::string& map_id, |
| 443 ValuesMap* result, | 510 ValuesMap* result, |
| 444 bool only_keys) { | 511 bool only_keys) { |
| 445 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); | 512 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); |
| 446 std::string map_start_key = MapRefCountKey(map_id); | 513 std::string map_start_key = MapRefCountKey(map_id); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 return false; | 644 return false; |
| 578 // Create a new map (this will also break the association to the old map) and | 645 // Create a new map (this will also break the association to the old map) and |
| 579 // write the old data into it. This will write the id of the created map into | 646 // write the old data into it. This will write the id of the created map into |
| 580 // |map_id|. | 647 // |map_id|. |
| 581 if (!CreateMapForArea(namespace_id, origin, map_id, batch)) | 648 if (!CreateMapForArea(namespace_id, origin, map_id, batch)) |
| 582 return false; | 649 return false; |
| 583 WriteValuesToMap(*map_id, values, batch); | 650 WriteValuesToMap(*map_id, values, batch); |
| 584 return true; | 651 return true; |
| 585 } | 652 } |
| 586 | 653 |
| 654 bool SessionStorageDatabase::AllocateNamespaceId(int64* namespace_id) { |
| 655 if (!LazyOpen(true)) |
| 656 return false; |
| 657 *namespace_id = next_namespace_id_++; |
| 658 // The next namespace id field in the db will be increased when data is |
| 659 // actually written to the namespace. |
| 660 return true; |
| 661 } |
| 662 |
| 663 bool SessionStorageDatabase::GetRealId(int64 namespace_id, int64* real_id) { |
| 664 std::map<int64, int64>::const_iterator it = id_to_real_id_.find(namespace_id); |
| 665 if (it != id_to_real_id_.end()) { |
| 666 *real_id = it->second; |
| 667 return true; |
| 668 } |
| 669 if (!AllocateNamespaceId(real_id)) |
| 670 return false; |
| 671 if (!associated_callback_.is_null()) |
| 672 associated_callback_.Run(namespace_id, *real_id); |
| 673 AssociateNamespaceId(namespace_id, *real_id); |
| 674 return true; |
| 675 } |
| 676 |
| 587 std::string SessionStorageDatabase::NamespaceStartKey( | 677 std::string SessionStorageDatabase::NamespaceStartKey( |
| 588 const std::string& namespace_id_str) { | 678 const std::string& namespace_id_str) { |
| 589 return base::StringPrintf("namespace-%s", namespace_id_str.c_str()); | 679 return base::StringPrintf("namespace-%s", namespace_id_str.c_str()); |
| 590 } | 680 } |
| 591 | 681 |
| 592 std::string SessionStorageDatabase::NamespaceStartKey(int64 namespace_id, | 682 std::string SessionStorageDatabase::NamespaceStartKey(int64 namespace_id) { |
| 593 int64 namespace_offset) { | 683 return NamespaceStartKey(NamespaceIdStr(namespace_id)); |
| 594 return NamespaceStartKey(NamespaceIdStr(namespace_id, namespace_offset)); | |
| 595 } | 684 } |
| 596 | 685 |
| 597 std::string SessionStorageDatabase::NamespaceKey( | 686 std::string SessionStorageDatabase::NamespaceKey( |
| 598 const std::string& namespace_id_str, const std::string& origin) { | 687 const std::string& namespace_id_str, const std::string& origin) { |
| 599 return base::StringPrintf("namespace-%s-%s", namespace_id_str.c_str(), | 688 return base::StringPrintf("namespace-%s-%s", namespace_id_str.c_str(), |
| 600 origin.c_str()); | 689 origin.c_str()); |
| 601 } | 690 } |
| 602 | 691 |
| 603 std::string SessionStorageDatabase::NamespaceKey( | 692 std::string SessionStorageDatabase::NamespaceKey(int64 namespace_id, |
| 604 int64 namespace_id, int64 namespace_offset, const GURL& origin) { | 693 const GURL& origin) { |
| 605 return NamespaceKey(NamespaceIdStr(namespace_id, namespace_offset), | 694 return NamespaceKey(NamespaceIdStr(namespace_id), origin.spec()); |
| 606 origin.spec()); | |
| 607 } | 695 } |
| 608 | 696 |
| 609 std::string SessionStorageDatabase::NamespaceIdStr(int64 namespace_id, | 697 std::string SessionStorageDatabase::NamespaceIdStr(int64 namespace_id) { |
| 610 int64 namespace_offset) { | 698 int64 real_id; |
| 611 return base::Int64ToString(namespace_id + namespace_offset); | 699 if (!GetRealId(namespace_id, &real_id)) |
| 700 return ""; |
| 701 return base::Int64ToString(real_id); |
| 612 } | 702 } |
| 613 | 703 |
| 614 const char* SessionStorageDatabase::NamespacePrefix() { | 704 const char* SessionStorageDatabase::NamespacePrefix() { |
| 615 return "namespace-"; | 705 return "namespace-"; |
| 616 } | 706 } |
| 617 | 707 |
| 618 std::string SessionStorageDatabase::MapRefCountKey(const std::string& map_id) { | 708 std::string SessionStorageDatabase::MapRefCountKey(const std::string& map_id) { |
| 619 return base::StringPrintf("map-%s", map_id.c_str()); | 709 return base::StringPrintf("map-%s", map_id.c_str()); |
| 620 } | 710 } |
| 621 | 711 |
| 622 std::string SessionStorageDatabase::MapKey(const std::string& map_id, | 712 std::string SessionStorageDatabase::MapKey(const std::string& map_id, |
| 623 const std::string& key) { | 713 const std::string& key) { |
| 624 return base::StringPrintf("map-%s-%s", map_id.c_str(), key.c_str()); | 714 return base::StringPrintf("map-%s-%s", map_id.c_str(), key.c_str()); |
| 625 } | 715 } |
| 626 | 716 |
| 627 const char* SessionStorageDatabase::MapPrefix() { | 717 const char* SessionStorageDatabase::MapPrefix() { |
| 628 return "map-"; | 718 return "map-"; |
| 629 } | 719 } |
| 630 | 720 |
| 631 const char* SessionStorageDatabase::NextNamespaceIdKey() { | 721 const char* SessionStorageDatabase::NextNamespaceIdKey() { |
| 632 return "next-namespace-id"; | 722 return "next-namespace-id"; |
| 633 } | 723 } |
| 634 | 724 |
| 635 const char* SessionStorageDatabase::NextMapIdKey() { | 725 const char* SessionStorageDatabase::NextMapIdKey() { |
| 636 return "next-map-id"; | 726 return "next-map-id"; |
| 637 } | 727 } |
| 638 | 728 |
| 639 } // namespace dom_storage | 729 } // namespace dom_storage |
| OLD | NEW |