Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: webkit/dom_storage/session_storage_database.cc

Issue 10176005: Add dom_storage::SessionStorageDatabase. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Code review. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "webkit/dom_storage/session_storage_database.h"
6
7 #include "base/file_util.h"
8 #include "base/logging.h"
9 #include "base/stringprintf.h"
10 #include "base/string_number_conversions.h"
11 #include "base/utf_string_conversions.h"
12 #include "googleurl/src/gurl.h"
13 #include "third_party/leveldatabase/src/include/leveldb/db.h"
14 #include "third_party/leveldatabase/src/include/leveldb/iterator.h"
15 #include "third_party/leveldatabase/src/include/leveldb/status.h"
16 #include "third_party/leveldatabase/src/include/leveldb/options.h"
17 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
18
19 // Layout of the database:
20 // | key | value |
21 // -----------------------------------------------------------------------
22 // | map-1 | 2 (refcount, start of map-1-* keys)|
23 // | map-1-a | b (a = b in map 1) |
24 // | ... | |
25 // | namespace- | dummy (start of namespace-* keys) |
26 // | namespace-1 (1 = namespace id) | dummy (start of namespace-1-* keys)|
27 // | namespace-1-origin1 | 1 (mapid) |
28 // | namespace-1-origin2 | 2 |
29 // | namespace-2 | dummy |
30 // | namespace-2-origin1 | 1 (shallow copy) |
31 // | namespace-2-origin2 | 2 (shallow copy) |
32 // | namespace-3 | dummy |
33 // | namespace-3-origin1 | 3 (deep copy) |
34 // | namespace-3-origin2 | 2 (shallow copy) |
35 // | next-namespace-id | 4 |
36 // | next-map-id | 4 |
37
38 namespace dom_storage {
39
40 SessionStorageDatabase::SessionStorageDatabase(const FilePath& file_path)
41 : file_path_(file_path),
42 db_error_(false),
43 is_inconsistent_(false),
44 namespace_offset_(0) { }
45
46 SessionStorageDatabase::~SessionStorageDatabase() {
47 }
48
49 void SessionStorageDatabase::ReadAreaValues(int64 namespace_id,
50 const GURL& origin,
51 ValuesMap* result) {
52 // We don't create a database if it doesn't exist. In that case, there is
53 // nothing to be added to the result.
54 if (!LazyOpen(false))
55 return;
56 std::string map_id;
57 bool exists;
58 if (!GetMapForArea(namespace_id, origin, &exists, &map_id))
59 return;
60 if (exists)
61 ReadMap(map_id, result, false);
62 }
63
64 bool SessionStorageDatabase::CommitAreaChanges(int64 namespace_id,
65 const GURL& origin,
66 bool clear_all_first,
67 const ValuesMap& changes) {
68 // Even if |changes| is empty, we need to write the appropriate placeholders
69 // in the database, so that it can be later shallow-copied succssfully.
70 if (!LazyOpen(true))
71 return false;
72
73 leveldb::WriteBatch batch;
74 // Ensure that the keys "namespace-" "namespace-N" (see the schema above)
75 // exist.
76 const bool kOkIfExists = true;
77 if (!CreateNamespace(namespace_id, kOkIfExists, &batch))
78 return false;
79
80 std::string map_id;
81 bool exists;
82 if (!GetMapForArea(namespace_id, origin, &exists, &map_id))
83 return false;
84 if (exists) {
85 // We shouldn't write data into a shallow copy. If this is a shallow copy,
86 // it's a caller error (not an inconsistency in the database).
87 int64 ref_count;
88 if (!GetMapRefCount(map_id, &ref_count))
89 return false;
90 if (!CallerErrorCheck(ref_count == 1))
91 return false;
92
93 if (clear_all_first) {
94 if (!ClearMap(map_id, &batch))
95 return false;
96 }
97 } else {
98 // Map doesn't exist, create it now if needed.
99 if (!changes.empty()) {
100 if (!CreateMapForArea(namespace_id, origin, &map_id, &batch))
101 return false;
102 }
103 }
104
105 WriteValuesToMap(map_id, changes, &batch);
106
107 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
108 return DatabaseErrorCheck(s.ok());
109 }
110
111 bool SessionStorageDatabase::CloneNamespace(int64 namespace_id,
112 int64 new_namespace_id) {
113 // Go through all origins in the namespace |namespace_id|, create placeholders
114 // for them in |new_namespace_id|, and associate them with the existing maps.
115
116 // Example, data before shallow copy:
117 // | map-1 | 1 (refcount) |
118 // | map-1-a | b |
119 // | namespace-1 (1 = namespace id) | dummy |
120 // | namespace-1-origin1 | 1 (mapid) |
121
122 // Example, data after shallow copy:
123 // | map-1 | 2 (inc. refcount) |
124 // | map-1-a | b |
125 // | namespace-1 (1 = namespace id) | dummy |
126 // | namespace-1-origin1 | 1 (mapid) |
127 // | namespace-2 | dummy |
128 // | namespace-2-origin1 | 1 (mapid) << references the same map
129
130 if (!LazyOpen(true))
131 return false;
132
133 leveldb::WriteBatch batch;
134 const bool kOkIfExists = false;
135 if (!CreateNamespace(new_namespace_id, kOkIfExists, &batch))
136 return false;
137
138 std::map<std::string, std::string> areas;
139 if (!GetAreasInNamespace(namespace_id, &areas))
140 return false;
141
142 for (std::map<std::string, std::string>::const_iterator it = areas.begin();
143 it != areas.end(); ++it) {
144 const std::string& origin = it->first;
145 const std::string& map_id = it->second;
146 if (!IncreaseMapRefCount(map_id, &batch))
147 return false;
148 AddAreaToNamespace(new_namespace_id, origin, map_id, &batch);
149 }
150 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
151 return DatabaseErrorCheck(s.ok());
152 }
153
154 bool SessionStorageDatabase::DeepCopyArea(int64 namespace_id,
155 const GURL& origin) {
156 // Example, data before deep copy:
157 // | namespace-1 (1 = namespace id) | dummy |
158 // | namespace-1-origin1 | 1 (mapid) |
159 // | namespace-2 | dummy |
160 // | namespace-2-origin1 | 1 (mapid) << references the same map
161 // | map-1 | 2 (refcount) |
162 // | map-1-a | b |
163
164 // Example, data after deep copy copy:
165 // | namespace-1 (1 = namespace id) | dummy |
166 // | namespace-1-origin1 | 1 (mapid) |
167 // | namespace-2 | dummy |
168 // | namespace-2-origin1 | 2 (mapid) << references the new map
169 // | map-1 | 1 (dec. refcount) |
170 // | map-1-a | b |
171 // | map-2 | 1 (refcount) |
172 // | map-2-a | b |
173
174 if (!LazyOpen(true))
175 return false;
176
177 std::string old_map_id;
178 bool exists;
179 if (!GetMapForArea(namespace_id, origin, &exists, &old_map_id))
180 return false;
181
182 // If the area doesn't exist, or if it's not a shallow copy, it's a caller
183 // error.
184 if (!CallerErrorCheck(exists))
185 return false;
186 int64 ref_count;
187 if (!GetMapRefCount(old_map_id, &ref_count))
188 return false;
189 if (!CallerErrorCheck(ref_count > 1))
190 return false;
191
192 leveldb::WriteBatch batch;
193 std::string new_map_id;
194 if (!CreateMapForArea(namespace_id, origin, &new_map_id, &batch))
195 return false;
196
197 // Copy the values in the map.
198 ValuesMap values;
199 if (!ReadMap(old_map_id, &values, false))
200 return false;
201 WriteValuesToMap(new_map_id, values, &batch);
202
203 if (!DecreaseMapRefCount(old_map_id, 1, &batch))
204 return false;
205
206 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
207 return DatabaseErrorCheck(s.ok());
208 }
209
210 bool SessionStorageDatabase::DeleteArea(int64 namespace_id,
211 const GURL& origin) {
212 if (!LazyOpen(false)) {
213 // No need to create the database if it doesn't exist.
214 return true;
215 }
216 leveldb::WriteBatch batch;
217 if (!DeleteArea(namespace_id, origin.spec(), &batch))
218 return false;
219 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
220 return DatabaseErrorCheck(s.ok());
221 }
222
223 bool SessionStorageDatabase::DeleteNamespace(int64 namespace_id) {
224 if (!LazyOpen(false)) {
225 // No need to create the database if it doesn't exist.
226 return true;
227 }
228 // Itereate through the areas in the namespace.
229 leveldb::WriteBatch batch;
230 std::map<std::string, std::string> areas;
231 if (!GetAreasInNamespace(namespace_id, &areas))
232 return false;
233 for (std::map<std::string, std::string>::const_iterator it = areas.begin();
234 it != areas.end(); ++it) {
235 const std::string& origin = it->first;
236 if (!DeleteArea(namespace_id, origin, &batch))
237 return false;
238 }
239 batch.Delete(NamespaceStartKey(namespace_id, namespace_offset_));
240 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
241 return DatabaseErrorCheck(s.ok());
242 }
243
244 bool SessionStorageDatabase::LazyOpen(bool create_if_needed) {
245 base::AutoLock auto_lock(db_lock_);
246 if (db_error_ || is_inconsistent_) {
247 // Don't try to open a database that we know has failed already.
248 return false;
249 }
250 if (IsOpen())
251 return true;
252
253 if (!create_if_needed &&
254 (!file_util::PathExists(file_path_) ||
255 file_util::IsDirectoryEmpty(file_path_))) {
256 // If the directory doesn't exist already and we haven't been asked to
257 // create a file on disk, then we don't bother opening the database. This
258 // means we wait until we absolutely need to put something onto disk before
259 // we do so.
260 return false;
261 }
262
263 leveldb::DB* db;
264 leveldb::Status s = TryToOpen(file_path_, &db);
265 if (!s.ok()) {
266 LOG(WARNING) << "Failed to open leveldb in " << file_path_.value()
267 << ", error: " << s.ToString();
268 DCHECK(db == NULL);
269
270 // Clear the directory and try again.
271 file_util::Delete(file_path_, true);
272 s = TryToOpen(file_path_, &db);
273 if (!s.ok()) {
274 LOG(WARNING) << "Failed to open leveldb in " << file_path_.value()
275 << ", error: " << s.ToString();
276 DCHECK(db == NULL);
277 db_error_ = true;
278 return false;
279 }
280 }
281 db_.reset(db);
282
283 return GetNextNamespaceId(&namespace_offset_);
284 }
285
286 leveldb::Status SessionStorageDatabase::TryToOpen(const FilePath& file_path,
287 leveldb::DB** db) {
288 leveldb::Options options;
289 // The directory exists but a valid leveldb database might not exist inside it
290 // (e.g., a subset of the needed files might be missing). Handle this
291 // situation gracefully by creating the database now.
292 options.create_if_missing = true;
293 #if defined(OS_WIN)
294 return leveldb::DB::Open(options, WideToUTF8(file_path.value()), db);
295 #elif defined(OS_POSIX)
296 return leveldb::DB::Open(options, file_path.value(), db);
297 #endif
298 }
299
300 bool SessionStorageDatabase::IsOpen() const {
301 return db_.get() != NULL;
302 }
303
304 bool SessionStorageDatabase::CallerErrorCheck(bool ok) const {
305 DCHECK(ok);
306 return ok;
307 }
308
309 bool SessionStorageDatabase::ConsistencyCheck(bool ok) {
310 DCHECK(ok);
311 is_inconsistent_ = !ok;
michaeln 2012/04/26 22:07:02 i think the tsan bots would eventually get around
marja 2012/04/27 07:34:47 Done.
312 // We cannot recover the database during this run, e.g., the upper layer can
313 // have a different understanding of the database state (shallow and deep
314 // copies).
315 // TODO(marja): Error handling.
316 return ok;
317 }
318
319 bool SessionStorageDatabase::DatabaseErrorCheck(bool ok) {
320 db_error_ = !ok;
321 // TODO(marja): Error handling.
322 return ok;
323 }
324
325 bool SessionStorageDatabase::CreateNamespace(int64 namespace_id,
326 bool ok_if_exists,
327 leveldb::WriteBatch* batch) {
328 std::string namespace_prefix = NamespacePrefix();
329 std::string dummy;
330 leveldb::Status s = db_->Get(leveldb::ReadOptions(), namespace_prefix,
331 &dummy);
332 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound()))
333 return false;
334 if (s.IsNotFound())
335 batch->Put(namespace_prefix, "");
336
337 std::string namespace_start_key =
338 NamespaceStartKey(namespace_id, namespace_offset_);
339 s = db_->Get(leveldb::ReadOptions(), namespace_start_key, &dummy);
340 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound()))
341 return false;
342 if (s.IsNotFound()) {
343 batch->Put(namespace_start_key, "");
344 return UpdateNextNamespaceId(namespace_id, batch);
345 }
346 return CallerErrorCheck(ok_if_exists);
347 }
348
349 bool SessionStorageDatabase::GetNextNamespaceId(int64* next_namespace_id) {
350 std::string next_namespace_id_string;
351 leveldb::Status s = db_->Get(leveldb::ReadOptions(), NextNamespaceIdKey(),
352 &next_namespace_id_string);
353 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound()))
354 return false;
355 if (s.IsNotFound()) {
356 *next_namespace_id = 0;
357 return true;
358 }
359 bool conversion_ok =
360 base::StringToInt64(next_namespace_id_string, next_namespace_id);
361 return ConsistencyCheck(conversion_ok);
362 }
363
364 bool SessionStorageDatabase::UpdateNextNamespaceId(int64 namespace_id,
365 leveldb::WriteBatch* batch) {
366 int64 next_namespace_id;
367 if (!GetNextNamespaceId(&next_namespace_id))
368 return false;
369 if (next_namespace_id < namespace_id + namespace_offset_ + 1) {
370 next_namespace_id = namespace_id + namespace_offset_ + 1;
371 batch->Put(NextNamespaceIdKey(), base::Int64ToString(next_namespace_id));
372 }
373 return true;
374 }
375
376 bool SessionStorageDatabase::GetAreasInNamespace(
377 int64 namespace_id,
378 std::map<std::string, std::string>* areas) {
379 return GetAreasInNamespace(NamespaceIdStr(namespace_id, namespace_offset_),
380 areas);
381 }
382
383 bool SessionStorageDatabase::GetAreasInNamespace(
384 const std::string& namespace_id_str,
385 std::map<std::string, std::string>* areas) {
386 std::string namespace_start_key = NamespaceStartKey(namespace_id_str);
387 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions()));
388 it->Seek(namespace_start_key);
389 if (it->status().IsNotFound()) {
390 // The namespace_start_key is not found when the namespace doesn't contain
391 // any areas. We don't need to do anything.
392 return true;
393 }
394 if (!DatabaseErrorCheck(it->status().ok()))
395 return false;
396
397 // Skip the dummy entry "namespace-<namespaceid>" and iterate the origins.
398 for (it->Next(); it->Valid(); it->Next()) {
399 std::string key = it->key().ToString();
400 if (key.find(namespace_start_key) != 0) {
401 // Iterated past the origins for this namespace.
402 break;
403 }
404 size_t second_dash = key.find('-', namespace_start_key.length());
405 if (!ConsistencyCheck(second_dash != std::string::npos))
406 return false;
407 std::string origin = key.substr(second_dash + 1);
408 std::string map_id = it->value().ToString();
409 (*areas)[origin] = map_id;
410 }
411 return true;
412 }
413
414 void SessionStorageDatabase::AddAreaToNamespace(int64 namespace_id,
415 const std::string& origin,
416 const std::string& map_id,
417 leveldb::WriteBatch* batch) {
418 std::string namespace_key = NamespaceKey(
419 NamespaceIdStr(namespace_id, namespace_offset_), origin);
420 batch->Put(namespace_key, map_id);
421 }
422
423 bool SessionStorageDatabase::DeleteArea(int64 namespace_id,
424 const std::string& origin,
425 leveldb::WriteBatch* batch) {
426 return DeleteArea(NamespaceIdStr(namespace_id, namespace_offset_),
427 origin, batch);
428 }
429
430 bool SessionStorageDatabase::DeleteArea(const std::string& namespace_id_str,
431 const std::string& origin,
432 leveldb::WriteBatch* batch) {
433 std::string map_id;
434 bool exists;
435 if (!GetMapForArea(namespace_id_str, origin, &exists, &map_id))
436 return false;
437 if (!exists)
438 return true; // Nothing to delete.
439 if (!DecreaseMapRefCount(map_id, 1, batch))
440 return false;
441 std::string namespace_key = NamespaceKey(namespace_id_str, origin);
442 batch->Delete(namespace_key);
443 return true;
444 }
445
446 bool SessionStorageDatabase::GetMapForArea(int64 namespace_id,
447 const GURL& origin,
448 bool* exists,
449 std::string* map_id) {
450 return GetMapForArea(
451 base::Int64ToString(namespace_id + namespace_offset_),
452 origin.spec(), exists, map_id);
453 }
454
455 bool SessionStorageDatabase::GetMapForArea(const std::string& namespace_id_str,
456 const std::string& origin,
457 bool* exists, std::string* map_id) {
458 std::string namespace_key = NamespaceKey(namespace_id_str, origin);
459 leveldb::Status s = db_->Get(leveldb::ReadOptions(), namespace_key, map_id);
460 if (s.IsNotFound()) {
461 *exists = false;
462 return true;
463 }
464 *exists = true;
465 return DatabaseErrorCheck(s.ok());
466 }
467
468 bool SessionStorageDatabase::CreateMapForArea(int64 namespace_id,
469 const GURL& origin,
470 std::string* map_id,
471 leveldb::WriteBatch* batch) {
472 std::string next_map_id_key = NextMapIdKey();
473 leveldb::Status s = db_->Get(leveldb::ReadOptions(), next_map_id_key, map_id);
474 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound()))
475 return false;
476 int64 next_map_id = 0;
477 if (s.IsNotFound()) {
478 *map_id = "0";
479 } else {
480 bool conversion_ok = base::StringToInt64(*map_id, &next_map_id);
481 if (!ConsistencyCheck(conversion_ok))
482 return false;
483 }
484 batch->Put(next_map_id_key, base::Int64ToString(++next_map_id));
485 std::string namespace_key =
486 NamespaceKey(namespace_id, namespace_offset_, origin);
487 batch->Put(namespace_key, *map_id);
488 batch->Put(MapRefCountKey(*map_id), "1");
489 return true;
490 }
491
492 bool SessionStorageDatabase::ReadMap(const std::string& map_id,
493 ValuesMap* result,
494 bool only_keys) {
495 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions()));
496 std::string map_start_key = MapRefCountKey(map_id);
497 it->Seek(map_start_key);
498 // The map needs to exist, otherwise we have a stale map_id in the database.
499 if (!ConsistencyCheck(!it->status().IsNotFound()))
500 return false;
501 if (!DatabaseErrorCheck(it->status().ok()))
502 return false;
503 // Skip the dummy entry "map-<mapid>".
504 for (it->Next(); it->Valid(); it->Next()) {
505 // Key is of the form "map-<mapid>-<key>".
506 std::string key = it->key().ToString();
507 int prefix_length = std::string(MapPrefix()).length();
michaeln 2012/04/26 22:07:02 would be nice to pull this out of the inner loop a
marja 2012/04/27 07:34:47 Done.
508 size_t second_dash = key.find('-', prefix_length);
509 if (second_dash == std::string::npos ||
510 key.substr(prefix_length, second_dash - prefix_length) != map_id) {
511 // Iterated beyond the keys in this map.
512 break;
513 }
514 string16 key16 = UTF8ToUTF16(key.substr(second_dash + 1));
515 if (only_keys) {
516 (*result)[key16] = NullableString16(true);
517 } else {
518 // Convert the raw data stored in std::string (it->value()) to raw data
519 // stored in string16.
520 size_t len = it->value().size() / sizeof(char16);
521 const char16* data_ptr =
522 reinterpret_cast<const char16*>(it->value().data());
523 (*result)[key16] = NullableString16(string16(data_ptr, len), false);
524 }
525 }
526 return true;
527 }
528
529 void SessionStorageDatabase::WriteValuesToMap(const std::string& map_id,
530 const ValuesMap& values,
531 leveldb::WriteBatch* batch) {
532 for (ValuesMap::const_iterator it = values.begin(); it != values.end();
533 ++it) {
534 NullableString16 value = it->second;
535 std::string key = MapKey(map_id, UTF16ToUTF8(it->first));
536 if (value.is_null()) {
537 batch->Delete(key);
538 } else {
539 // Convert the raw data stored in string16 to raw data stored in
540 // std::string.
541 const char* data = reinterpret_cast<const char*>(value.string().data());
542 size_t size = value.string().size() * 2;
543 batch->Put(key, leveldb::Slice(data, size));
544 }
545 }
546 }
547
548 bool SessionStorageDatabase::GetMapRefCount(const std::string& map_id,
549 int64* ref_count) {
550 std::string ref_count_string;
551 leveldb::Status s = db_->Get(leveldb::ReadOptions(),
552 MapRefCountKey(map_id), &ref_count_string);
553 if (!ConsistencyCheck(s.ok()))
554 return false;
555 bool conversion_ok = base::StringToInt64(ref_count_string, ref_count);
556 return ConsistencyCheck(conversion_ok);
557 }
558
559 bool SessionStorageDatabase::IncreaseMapRefCount(const std::string& map_id,
560 leveldb::WriteBatch* batch) {
561 // Increase the ref count for the map.
562 int64 old_ref_count;
563 if (!GetMapRefCount(map_id, &old_ref_count))
564 return false;
565 batch->Put(MapRefCountKey(map_id), base::Int64ToString(++old_ref_count));
566 return true;
567 }
568
569 bool SessionStorageDatabase::DecreaseMapRefCount(const std::string& map_id,
570 int decrease,
571 leveldb::WriteBatch* batch) {
572 // Decrease the ref count for the map.
573 int64 ref_count;
574 if (!GetMapRefCount(map_id, &ref_count))
575 return false;
576 if (!ConsistencyCheck(decrease <= ref_count))
577 return false;
578 ref_count -= decrease;
579 if (ref_count > 0) {
580 batch->Put(MapRefCountKey(map_id), base::Int64ToString(ref_count));
581 } else {
582 // Clear all keys in the map.
583 if (!ClearMap(map_id, batch))
584 return false;
585 batch->Delete(MapRefCountKey(map_id));
586 }
587 return true;
588 }
589
590 bool SessionStorageDatabase::ClearMap(const std::string& map_id,
591 leveldb::WriteBatch* batch) {
592 ValuesMap values;
593 if (!ReadMap(map_id, &values, true))
594 return false;
595 for (ValuesMap::const_iterator it = values.begin(); it != values.end(); ++it)
596 batch->Delete(MapKey(map_id, UTF16ToUTF8(it->first)));
597 return true;
598 }
599
600 std::string SessionStorageDatabase::NamespaceStartKey(
601 const std::string& namespace_id_str) {
602 return base::StringPrintf("namespace-%s", namespace_id_str.c_str());
603 }
604
605 std::string SessionStorageDatabase::NamespaceStartKey(int64 namespace_id,
606 int64 namespace_offset) {
607 return NamespaceStartKey(NamespaceIdStr(namespace_id, namespace_offset));
608 }
609
610 std::string SessionStorageDatabase::NamespaceKey(
611 const std::string& namespace_id_str, const std::string& origin) {
612 return base::StringPrintf("namespace-%s-%s", namespace_id_str.c_str(),
613 origin.c_str());
614 }
615
616 std::string SessionStorageDatabase::NamespaceKey(
617 int64 namespace_id, int64 namespace_offset, const GURL& origin) {
618 return NamespaceKey(NamespaceIdStr(namespace_id, namespace_offset),
619 origin.spec());
620 }
621
622 std::string SessionStorageDatabase::NamespaceIdStr(int64 namespace_id,
623 int64 namespace_offset) {
624 return base::Int64ToString(namespace_id + namespace_offset);
625 }
626
627 const char* SessionStorageDatabase::NamespacePrefix() {
628 return "namespace-";
629 }
630
631 std::string SessionStorageDatabase::MapRefCountKey(const std::string& map_id) {
632 return base::StringPrintf("map-%s", map_id.c_str());
633 }
634
635 std::string SessionStorageDatabase::MapKey(const std::string& map_id,
636 const std::string& key) {
637 return base::StringPrintf("map-%s-%s", map_id.c_str(), key.c_str());
638 }
639
640 const char* SessionStorageDatabase::MapPrefix() {
641 return "map-";
642 }
643
644 const char* SessionStorageDatabase::NextNamespaceIdKey() {
645 return "next-namespace-id";
646 }
647
648 const char* SessionStorageDatabase::NextMapIdKey() {
649 return "next-map-id";
650 }
651
652 } // namespace dom_storage
OLDNEW
« no previous file with comments | « webkit/dom_storage/session_storage_database.h ('k') | webkit/dom_storage/session_storage_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698