value_store_frontend.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/value_store/value_store_frontend.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/debug/trace_event.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/value_store/leveldb_value_store.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ValueStoreFrontend::Backend : public base::RefCountedThreadSafe<Backend> { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Backend() : storage_(NULL) {} 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Init(const base::FilePath& db_path) { 21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::FILE); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!storage_); 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT0("ValueStoreFrontend::Backend", "Init"); 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) db_path_ = db_path; 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) storage_ = new LeveldbValueStore(db_path); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This variant is useful for testing (using a mock ValueStore). 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitWithStore(scoped_ptr<ValueStore> storage) { 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::FILE); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!storage_); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_ = storage.release(); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Get(const std::string& key, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ValueStoreFrontend::ReadCallback& callback) { 37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::FILE); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueStore::ReadResult result = storage_->Get(key); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extract the value from the ReadResult and pass ownership of it to the 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callback. 423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch scoped_ptr<base::Value> value; 433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (!result->HasError()) { 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) result->settings().RemoveWithoutPathExpansion(key, &value); 453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } else { 4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LOG(WARNING) << "Reading " << key << " from " << db_path_.value() 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) << " failed: " << result->error().message; 483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ValueStoreFrontend::Backend::RunCallback, 523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch this, callback, base::Passed(&value))); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Set(const std::string& key, scoped_ptr<base::Value> value) { 56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::FILE); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't need the old value, so skip generating changes. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->Set(ValueStore::IGNORE_QUOTA | ValueStore::NO_GENERATE_CHANGES, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key, *value.get()); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Remove(const std::string& key) { 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::FILE); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->Remove(key); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCountedThreadSafe<Backend>; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Backend() { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete storage_; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, storage_); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunCallback(const ValueStoreFrontend::ReadCallback& callback, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Value> value) { 80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(value.Pass()); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The actual ValueStore that handles persisting the data to disk. Used 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exclusively on the FILE thread. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueStore* storage_; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath db_path_; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Backend); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ValueStoreFrontend::ValueStoreFrontend() 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : backend_(new Backend()) { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ValueStoreFrontend::ValueStoreFrontend(const base::FilePath& db_path) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : backend_(new Backend()) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Init(db_path); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ValueStoreFrontend::ValueStoreFrontend(scoped_ptr<ValueStore> value_store) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : backend_(new Backend()) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ValueStoreFrontend::Backend::InitWithStore, 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) backend_, base::Passed(&value_store))); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ValueStoreFrontend::~ValueStoreFrontend() { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ValueStoreFrontend::Init(const base::FilePath& db_path) { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ValueStoreFrontend::Backend::Init, 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backend_, db_path)); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ValueStoreFrontend::Get(const std::string& key, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ReadCallback& callback) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ValueStoreFrontend::Backend::Get, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_, key, callback)); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ValueStoreFrontend::Set(const std::string& key, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Value> value) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ValueStoreFrontend::Backend::Set, 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backend_, key, base::Passed(&value))); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ValueStoreFrontend::Remove(const std::string& key) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ValueStoreFrontend::Backend::Remove, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_, key)); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 144