blob: 39110d01988b967f2e5674c2f050b03e231ab6b8 [file] [log] [blame]
// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR 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.
#include "session/generic_storage_manager.h"
#include <cstring>
#include <string>
#include <vector>
#include "base/config_file_stream.h"
#include "base/logging.h"
#include "base/mutex.h"
#include "base/port.h"
#include "base/scoped_ptr.h"
#include "base/singleton.h"
#include "storage/lru_storage.h"
namespace {
mozc::Mutex g_storage_ensure_mutex;
mozc::GenericStorageManagerInterface *g_storage_manager = NULL;
const char kSymbolStorageFileName[] =
"user://symbol_history.db";
// 32 characters * 3 bytes(typical byte size per character)
const size_t kSymbolValueSize = 32 * 3;
const size_t kSymbolSize = 100;
const uint32 kSymbolSeed = 336843897;
const char kEmoticonStorageFileName[] =
"user://emoticon_history.db";
// 64 characters * 3 bytes(typical byte size per character)
const size_t kEmoticonValueSize = 64 * 3;
const size_t kEmoticonSize = 100;
const uint32 kEmoticonSeed = 236843897;
const char kEmojiStorageFileName[] =
"user://emoji_history.db";
// 32 characters * 3 bytes(typical byte size per character)
const size_t kEmojiValueSize = 32 * 3;
const size_t kEmojiSize = 100;
const uint32 kEmojiSeed = 136843897;
} // namespace
namespace mozc {
using mozc::storage::LRUStorage;
class GenericStorageManagerImpl
: public GenericStorageManagerInterface {
public:
GenericStorageManagerImpl() :
symbol_history_storage_(kSymbolStorageFileName,
kSymbolValueSize,
kSymbolSize,
kSymbolSeed),
emoticon_history_storage_(kEmoticonStorageFileName,
kEmoticonValueSize,
kEmoticonSize,
kEmoticonSeed),
emoji_history_storage_(kEmojiStorageFileName,
kEmojiValueSize,
kEmojiSize,
kEmojiSeed) {}
virtual ~GenericStorageManagerImpl() {}
virtual GenericStorageInterface *GetStorage(
commands::GenericStorageEntry::StorageType storage_type);
private:
GenericLruStorage symbol_history_storage_;
GenericLruStorage emoticon_history_storage_;
GenericLruStorage emoji_history_storage_;
};
GenericStorageInterface *GenericStorageManagerImpl::GetStorage(
commands::GenericStorageEntry::StorageType storage_type) {
switch (storage_type) {
case commands::GenericStorageEntry::SYMBOL_HISTORY:
return &symbol_history_storage_;
case commands::GenericStorageEntry::EMOTICON_HISTORY:
return &emoticon_history_storage_;
case commands::GenericStorageEntry::EMOJI_HISTORY:
return &emoji_history_storage_;
default:
LOG(WARNING) << "Invalid storage type";
}
return NULL;
}
// static
void GenericStorageManagerFactory::SetGenericStorageManager(
GenericStorageManagerInterface *manager) {
g_storage_manager = manager;
}
// static
GenericStorageInterface *GenericStorageManagerFactory::GetStorage(
commands::GenericStorageEntry::StorageType storage_type) {
GenericStorageManagerInterface *manager = g_storage_manager ?
g_storage_manager : Singleton<GenericStorageManagerImpl>::get();
return manager->GetStorage(storage_type);
}
GenericLruStorage::GenericLruStorage(
const char *file_name, size_t value_size, size_t size, uint32 seed)
: file_name_(file_name), value_size_(value_size),
size_(size), seed_(seed), value_buffer_(new char[value_size + 1]) {
}
GenericLruStorage::~GenericLruStorage() {
}
bool GenericLruStorage::EnsureStorage() {
scoped_lock lock(&g_storage_ensure_mutex);
if (lru_storage_.get()) {
// We already have prepared storage.
return true;
}
scoped_ptr<LRUStorage> new_storage;
new_storage.reset(new LRUStorage());
const string &filename =
ConfigFileStream::GetFileName(file_name_);
if (!new_storage->OpenOrCreate(filename.data(), value_size_, size_, seed_)) {
return false;
}
lru_storage_.swap(new_storage);
return true;
}
bool GenericLruStorage::Insert(const string &key, const char *value) {
if (!EnsureStorage()) {
return false;
}
const size_t value_size = strnlen(value, value_size_ + 1);
if (value_size > value_size_) {
LOG(DFATAL) << "Too long value: [" << value << "] size: " << value_size;
return false;
}
// LRUStorage only accepts fixed-length value, so we should allocate enough
// memory to avoid illegal access.
memcpy(value_buffer_.get(), value, value_size + 1);
return lru_storage_->Insert(key, value_buffer_.get());
}
const char *GenericLruStorage::Lookup(const string &key) {
if (!EnsureStorage()) {
return NULL;
}
return lru_storage_->Lookup(key);
}
bool GenericLruStorage::GetAllValues(vector<string> *values) {
if (!EnsureStorage()) {
return false;
}
return lru_storage_->GetAllValues(values);
}
bool GenericLruStorage::Clear() {
if (!EnsureStorage()) {
return false;
}
return lru_storage_->Clear();
}
} // namespace mozc