// ----------------------------------------------------------------------
// File: InternalKeyParsing.cc
// Author: Georgios Bitzes - CERN
// ----------------------------------------------------------------------
/************************************************************************
* quarkdb - a redis-like highly available key-value store *
* Copyright (C) 2016 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#include "InternalKeyParsing.hh"
#include
#include
#include
namespace quarkdb {
// Copied from rocksdb
enum ValueType : unsigned char {
kTypeDeletion = 0x0,
kTypeValue = 0x1,
kTypeMerge = 0x2,
kTypeLogData = 0x3, // WAL only.
kTypeColumnFamilyDeletion = 0x4, // WAL only.
kTypeColumnFamilyValue = 0x5, // WAL only.
kTypeColumnFamilyMerge = 0x6, // WAL only.
kTypeSingleDeletion = 0x7,
kTypeColumnFamilySingleDeletion = 0x8, // WAL only.
kTypeBeginPrepareXID = 0x9, // WAL only.
kTypeEndPrepareXID = 0xA, // WAL only.
kTypeCommitXID = 0xB, // WAL only.
kTypeRollbackXID = 0xC, // WAL only.
kTypeNoop = 0xD, // WAL only.
kTypeColumnFamilyRangeDeletion = 0xE, // WAL only.
kTypeRangeDeletion = 0xF, // meta block
kTypeColumnFamilyBlobIndex = 0x10, // Blob DB only
kTypeBlobIndex = 0x11, // Blob DB only
// When the prepared record is also persisted in db, we use a different
// record. This is to ensure that the WAL that is generated by a WritePolicy
// is not mistakenly read by another, which would result into data
// inconsistency.
kTypeBeginPersistedPrepareXID = 0x12, // WAL only.
// Similar to kTypeBeginPersistedPrepareXID, this is to ensure that WAL
// generated by WriteUnprepared write policy is not mistakenly read by
// another.
kTypeBeginUnprepareXID = 0x13, // WAL only.
kMaxValue = 0x7F // Not used for storing records.
};
// copied from rocksdb
static uint64_t DecodeFixed64(const char* ptr) {
uint64_t result;
memcpy(&result, ptr, sizeof(result));
return result;
}
static ValueType getValueType(std::string_view internalKey) {
uint64_t num = DecodeFixed64(internalKey.data() + internalKey.size() - 8);
unsigned char c = num & 0xff;
return static_cast(c);
}
bool isTombstone(std::string_view internalKey) {
if(internalKey.size() < 8) return false;
ValueType valueType = getValueType(internalKey);
return valueType == kTypeDeletion || valueType == kTypeSingleDeletion;
}
std::string getInternalKeyType(std::string_view internalKey) {
if(internalKey.size() < 8) return "(invalid key type)";
ValueType valueType = getValueType(internalKey);
switch(valueType) {
case kTypeDeletion: {
return "deletion";
}
case kTypeValue: {
return "value";
}
case kTypeMerge: {
return "merge";
}
case kTypeLogData: {
return "log data";
}
case kTypeColumnFamilyDeletion: {
return "column family deletion";
}
case kTypeColumnFamilyValue: {
return "column family value";
}
case kTypeColumnFamilyMerge: {
return "column family merge";
}
case kTypeSingleDeletion: {
return "single deletion";
}
case kTypeColumnFamilySingleDeletion: {
return "column family single deletion";
}
case kTypeBeginPrepareXID: {
return "begin prepare xid";
}
case kTypeEndPrepareXID: {
return "end prepare xid";
}
case kTypeCommitXID: {
return "commit xid";
}
case kTypeRollbackXID: {
return "rollback xid";
}
case kTypeNoop: {
return "noop";
}
case kTypeColumnFamilyRangeDeletion: {
return "column family range deletion";
}
case kTypeRangeDeletion: {
return "range deletion";
}
case kTypeColumnFamilyBlobIndex: {
return "column family blob index";
}
case kTypeBlobIndex: {
return "blob index";
}
case kTypeBeginPersistedPrepareXID: {
return "begin persisted prepare xid";
}
case kTypeBeginUnprepareXID: {
return "begin unprepare xid";
}
default: {
return "(cannot determine key type)";
}
}
}
}