Current section
Files
Jump to
Current section
Files
c_src/transaction_log.cc
// -------------------------------------------------------------------
// Copyright (c) 2016-2017 Benoit Chesneau. All Rights Reserved.
//
// This file is provided 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 "erocksdb_db.h"
#include "transaction_log.h"
#include "refobjects.h"
#include "atoms.h"
namespace erocksdb {
TransactionLogHandler::TransactionLogHandler(ErlNifEnv* env)
: rocksdb::WriteBatch::Handler()
{
t_Env = env;
t_List = enif_make_list(env, 0);
}
ERL_NIF_TERM
TransactionLogIterator(
ErlNifEnv *env,
int /*argc*/,
const ERL_NIF_TERM argv[])
{
ErlNifSInt64 since;
rocksdb::unique_ptr<rocksdb::TransactionLogIterator> iter;
ReferencePtr<DbObject> db_ptr;
if(!enif_get_db(env, argv[0], &db_ptr))
return enif_make_badarg(env);
if(!enif_get_int64(env, argv[1], &since))
return enif_make_badarg(env);
rocksdb::SequenceNumber seq = since;
rocksdb::Status status = db_ptr->m_Db->GetUpdatesSince(seq, &iter);
if(!status.ok())
return error_tuple(env, ATOM_ERROR, status);
if(!iter->Valid())
{
return enif_make_tuple2(env, ATOM_ERROR, ATOM_INVALID_ITERATOR);;
}
auto itr_ptr = iter.release();
TLogItrObject * tlog_ptr;
tlog_ptr = TLogItrObject::CreateTLogItrObject(db_ptr.get(), itr_ptr);
ERL_NIF_TERM result = enif_make_resource(env, tlog_ptr);
enif_release_resource(tlog_ptr);
iter = NULL;
return enif_make_tuple2(env, ATOM_OK, result);
}
ERL_NIF_TERM
TransactionLogIteratorClose(
ErlNifEnv* env,
int /*argc*/,
const ERL_NIF_TERM argv[])
{
TLogItrObject * tlog_ptr;
tlog_ptr=TLogItrObject::RetrieveTLogItrObject(env, argv[0]);
if(NULL!=tlog_ptr)
{
ErlRefObject::InitiateCloseRequest(tlog_ptr);
tlog_ptr = NULL;
return ATOM_OK;
}
return enif_make_badarg(env);
}
ERL_NIF_TERM
TransactionLogNextUpdate(
ErlNifEnv *env,
int /*argc*/,
const ERL_NIF_TERM argv[])
{
const ERL_NIF_TERM& itr_handle_ref = argv[0];
ReferencePtr<TLogItrObject> itr_ptr;
itr_ptr.assign(TLogItrObject::RetrieveTLogItrObject(env, itr_handle_ref));
if(NULL==itr_ptr.get())
{
return enif_make_badarg(env);
}
rocksdb::TransactionLogIterator* itr = itr_ptr->m_Iter;
if(!itr->Valid())
return enif_make_tuple2(env, ATOM_ERROR, ATOM_INVALID_ITERATOR);
rocksdb::Status status = itr->status();
if (!status.ok()) {
return error_tuple(env, ATOM_ERROR, status);
}
rocksdb::BatchResult batch = itr->GetBatch();
TransactionLogHandler handler = TransactionLogHandler(env);
batch.writeBatchPtr->Iterate(&handler);
ERL_NIF_TERM log;
enif_make_reverse_list(env, handler.t_List, &log);
ERL_NIF_TERM binlog;
std::string data = batch.writeBatchPtr->Data();
unsigned char* value = enif_make_new_binary(env, data.size(), &binlog);
memcpy(value, data.data(), data.size());
itr->Next();
return enif_make_tuple4(env,
ATOM_OK,
enif_make_int64(env, batch.sequence),
log,
binlog);
}
ERL_NIF_TERM
TransactionLogNextBinaryUpdate(
ErlNifEnv *env,
int /*argc*/,
const ERL_NIF_TERM argv[])
{
const ERL_NIF_TERM& itr_handle_ref = argv[0];
ReferencePtr<TLogItrObject> itr_ptr;
itr_ptr.assign(TLogItrObject::RetrieveTLogItrObject(env, itr_handle_ref));
if(NULL==itr_ptr.get())
{
return enif_make_badarg(env);
}
rocksdb::TransactionLogIterator* itr = itr_ptr->m_Iter;
if(!itr->Valid())
return enif_make_tuple2(env, ATOM_ERROR, ATOM_INVALID_ITERATOR);
rocksdb::Status status = itr->status();
if (!status.ok()) {
return error_tuple(env, ATOM_ERROR, status);
}
rocksdb::BatchResult batch = itr->GetBatch();
ERL_NIF_TERM bindata;
std::string data = batch.writeBatchPtr->Data();
unsigned char* value = enif_make_new_binary(env, data.size(), &bindata);
memcpy(value, data.data(), data.size());
itr->Next();
return enif_make_tuple3(env,
ATOM_OK,
enif_make_int64(env, batch.sequence),
bindata);
}
ERL_NIF_TERM
WriteBinaryUpdate(
ErlNifEnv* env,
int /*argc*/,
const ERL_NIF_TERM argv[])
{
ReferencePtr<DbObject> db_ptr;
if(!enif_get_db(env, argv[0], &db_ptr))
return enif_make_badarg(env);
ErlNifBinary bin;
if(!enif_inspect_binary(env, argv[1], &bin))
return enif_make_badarg(env);
const std::string batch_str = std::string((const char*)bin.data, bin.size);
rocksdb::WriteOptions* opts = new rocksdb::WriteOptions;
fold(env, argv[2], parse_write_option, *opts);
rocksdb::WriteBatch* batch = new rocksdb::WriteBatch(batch_str);
rocksdb::Status status = db_ptr->m_Db->Write(*opts, batch);
if (status.ok())
{
return ATOM_OK;
}
return error_tuple(env, ATOM_ERROR, status);
}
}