blob: 96a86dfc5dfb36e2a0fd980b99f5020e229dc307 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <geode/Region.hpp>
#include <geode/Cache.hpp>
#include "SqLiteImpl.hpp"
#include "sqliteimpl_export.h"
#ifdef _WIN32
#include <Windows.h>
#endif
namespace {
std::string g_default_persistence_directory = "GeodeRegionData";
} // namespace
namespace apache {
namespace geode {
namespace client {
static constexpr char const* MAX_PAGE_COUNT = "MaxPageCount";
static constexpr char const* PAGE_SIZE = "PageSize";
static constexpr char const* PERSISTENCE_DIR = "PersistenceDirectory";
void SqLiteImpl::init(const std::shared_ptr<Region> &region,
const std::shared_ptr<Properties> &diskProperties) {
// Set the default values
int maxPageCount = 0;
int pageSize = 0;
m_regionPtr = region;
m_persistanceDir = g_default_persistence_directory;
std::string regionName = region->getName();
if (diskProperties != nullptr) {
auto maxPageCountPtr = diskProperties->find(MAX_PAGE_COUNT);
auto pageSizePtr = diskProperties->find(PAGE_SIZE);
auto persDir = diskProperties->find(PERSISTENCE_DIR);
if (maxPageCountPtr != nullptr) {
maxPageCount = atoi(maxPageCountPtr->value().c_str());
}
if (pageSizePtr != nullptr) pageSize = atoi(pageSizePtr->value().c_str());
if (persDir != nullptr) m_persistanceDir = persDir->value().c_str();
}
#ifndef _WIN32
char currWDPath[512];
::getcwd(currWDPath, 512);
if (m_persistanceDir.at(0) != '/') {
if (0 == ::strlen(currWDPath)) {
throw InitFailedException(
"Failed to get absolute path for persistence directory.");
}
m_persistanceDir = std::string(currWDPath) + "/" + m_persistanceDir;
}
// Create persistence directory
::mkdir(m_persistanceDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
// Create region directory
std::string regionDirectory = m_persistanceDir + "/" + regionName;
::mkdir(regionDirectory.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
m_regionDBFile = regionDirectory + "/" + regionName + ".db";
#else
char currWDPath[512];
GetCurrentDirectory(512, currWDPath);
if (m_persistanceDir.find(":", 0) == std::string::npos) {
if (currWDPath == NULL)
throw InitFailedException(
"Failed to get absolute path for persistence directory.");
m_persistanceDir = std::string(currWDPath) + "/" + m_persistanceDir;
}
// Create persistence directory
CreateDirectory(m_persistanceDir.c_str(), NULL);
// Create region directory
std::string regionDirectory = m_persistanceDir + "/" + regionName;
CreateDirectory(regionDirectory.c_str(), NULL);
m_regionDBFile = regionDirectory + "/" + regionName + ".db";
#endif
if (m_sqliteHelper->initDB(region->getName().c_str(), maxPageCount, pageSize,
m_regionDBFile.c_str()) != 0) {
throw IllegalStateException("Failed to initialize database in SQLITE.");
}
}
void SqLiteImpl::write(const std::shared_ptr<CacheableKey> &key,
const std::shared_ptr<Cacheable> &value,
std::shared_ptr<void> &) {
// Serialize key and value.
auto &cache = m_regionPtr->getCache();
auto keyDataBuffer = cache.createDataOutput();
auto valueDataBuffer = cache.createDataOutput();
size_t keyBufferSize, valueBufferSize;
keyDataBuffer.writeObject(key);
valueDataBuffer.writeObject(value);
void *keyData =
const_cast<uint8_t *>(keyDataBuffer.getBuffer(&keyBufferSize));
void *valueData =
const_cast<uint8_t *>(valueDataBuffer.getBuffer(&valueBufferSize));
if (m_sqliteHelper->insertKeyValue(keyData, static_cast<int>(keyBufferSize),
valueData,
static_cast<int>(valueBufferSize)) != 0) {
throw IllegalStateException("Failed to write key value in SQLITE.");
}
}
bool SqLiteImpl::writeAll() { return true; }
std::shared_ptr<Cacheable> SqLiteImpl::read(
const std::shared_ptr<CacheableKey> &key, const std::shared_ptr<void> &) {
// Serialize key.
auto keyDataBuffer = m_regionPtr->getCache().createDataOutput();
size_t keyBufferSize;
keyDataBuffer.writeObject(key);
void *keyData =
const_cast<uint8_t *>(keyDataBuffer.getBuffer(&keyBufferSize));
void *valueData;
int valueBufferSize;
if (m_sqliteHelper->getValue(keyData, static_cast<int>(keyBufferSize),
valueData, valueBufferSize) != 0) {
throw IllegalStateException("Failed to read the value from SQLITE.");
}
// Deserialize object and return value.
auto valueDataBuffer = m_regionPtr->getCache().createDataInput(
reinterpret_cast<uint8_t *>(valueData), valueBufferSize);
std::shared_ptr<Cacheable> retValue;
valueDataBuffer.readObject(retValue);
// Free memory for serialized form of Cacheable object.
free(valueData);
return retValue;
}
bool SqLiteImpl::readAll() { return true; }
void SqLiteImpl::destroyRegion() {
if (m_sqliteHelper->closeDB() != 0) {
throw IllegalStateException("Failed to destroy region from SQLITE.");
}
#ifndef _WIN32
::unlink(m_regionDBFile.c_str());
::rmdir(m_regionDir.c_str());
::rmdir(m_persistanceDir.c_str());
#else
DeleteFile(m_regionDBFile.c_str());
RemoveDirectory(m_regionDir.c_str());
RemoveDirectory(m_persistanceDir.c_str());
#endif
}
void SqLiteImpl::destroy(const std::shared_ptr<CacheableKey> &key,
const std::shared_ptr<void> &) {
// Serialize key and value.
auto keyDataBuffer = m_regionPtr->getCache().createDataOutput();
size_t keyBufferSize;
keyDataBuffer.writeObject(key);
void *keyData =
const_cast<uint8_t *>(keyDataBuffer.getBuffer(&keyBufferSize));
if (m_sqliteHelper->removeKey(keyData, static_cast<int>(keyBufferSize)) !=
0) {
throw IllegalStateException("Failed to destroy the key from SQLITE.");
}
}
SqLiteImpl::SqLiteImpl() { m_sqliteHelper = std::unique_ptr<SqLiteHelper>(new SqLiteHelper()); }
void SqLiteImpl::close() {
m_sqliteHelper->closeDB();
#ifndef _WIN32
::unlink(m_regionDBFile.c_str());
::rmdir(m_regionDir.c_str());
::rmdir(m_persistanceDir.c_str());
#else
DeleteFile(m_regionDBFile.c_str());
RemoveDirectory(m_regionDir.c_str());
RemoveDirectory(m_persistanceDir.c_str());
#endif
}
} // namespace client
} // namespace geode
} // namespace apache
extern "C" {
using apache::geode::client::PersistenceManager;
using apache::geode::client::SqLiteImpl;
SQLITEIMPL_EXPORT PersistenceManager *createSqLiteInstance() {
return new SqLiteImpl();
}
}