1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/value_store/value_store_frontend.h"
#include "chrome/browser/value_store/failing_value_store.h"
#include "chrome/browser/value_store/leveldb_value_store.h"
#include "content/public/browser/browser_thread.h"
using content::BrowserThread;
class ValueStoreFrontend::Backend : public base::RefCountedThreadSafe<Backend> {
public:
explicit Backend(const FilePath& db_path) : storage_(NULL) {
}
void Init(const FilePath& db_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
DCHECK(!storage_);
storage_ = LeveldbValueStore::Create(db_path);
if (!storage_)
storage_ = new FailingValueStore();
}
void Get(const std::string& key,
const ValueStoreFrontend::ReadCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
ValueStore::ReadResult result = storage_->Get(key);
// Extract the value from the ReadResult and pass ownership of it to the
// callback.
base::Value* value = NULL;
if (!result->HasError())
result->settings()->RemoveWithoutPathExpansion(key, &value);
scoped_ptr<base::Value> passed_value(value);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&ValueStoreFrontend::Backend::RunCallback,
this, callback, base::Passed(passed_value.Pass())));
}
void Set(const std::string& key, scoped_ptr<base::Value> value) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
// We don't need the old value, so skip generating changes.
storage_->Set(ValueStore::IGNORE_QUOTA | ValueStore::NO_GENERATE_CHANGES,
key, *value.get());
}
void Remove(const std::string& key) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
storage_->Remove(key);
}
private:
friend class base::RefCountedThreadSafe<Backend>;
virtual ~Backend() {
if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
delete storage_;
} else {
BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, storage_);
}
}
void RunCallback(const ValueStoreFrontend::ReadCallback& callback,
scoped_ptr<base::Value> value) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
callback.Run(value.Pass());
}
// The actual ValueStore that handles persisting the data to disk. Used
// exclusively on the FILE thread.
ValueStore* storage_;
DISALLOW_COPY_AND_ASSIGN(Backend);
};
ValueStoreFrontend::ValueStoreFrontend(const FilePath& db_path)
: backend_(new Backend(db_path)) {
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
base::Bind(&ValueStoreFrontend::Backend::Init,
backend_, db_path));
}
ValueStoreFrontend::~ValueStoreFrontend() {
DCHECK(CalledOnValidThread());
}
void ValueStoreFrontend::Get(const std::string& key,
const ReadCallback& callback) {
DCHECK(CalledOnValidThread());
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
base::Bind(&ValueStoreFrontend::Backend::Get,
backend_, key, callback));
}
void ValueStoreFrontend::Set(const std::string& key,
scoped_ptr<base::Value> value) {
DCHECK(CalledOnValidThread());
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
base::Bind(&ValueStoreFrontend::Backend::Set,
backend_, key, base::Passed(value.Pass())));
}
void ValueStoreFrontend::Remove(const std::string& key) {
DCHECK(CalledOnValidThread());
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
base::Bind(&ValueStoreFrontend::Backend::Remove,
backend_, key));
}
|