/* Copyright (C) 2014 InfiniDB, Inc. 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; version 2 of the License. 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /******************************************************************************* * $Id: we_blockop.cpp 4500 2013-01-31 20:25:42Z dhall $ * *******************************************************************************/ /** @file */ #include #include #include "joblisttypes.h" #include "mcs_datatype.h" #include "we_blockop.h" #include "we_config.h" #include "we_brm.h" #include "we_convertor.h" using namespace execplan; namespace WriteEngine { /** * Constructor */ BlockOp::BlockOp(): m_typeHandler(nullptr) {} /** * Default Destructor */ BlockOp::~BlockOp() {} /*********************************************************** * DESCRIPTION: * Calculate the location of Row ID * PARAMETERS: * rowId - row id * epb - entry per block * width - width per column record * RETURN: * fbo - File block offset * bio - Block internal offset * true if success, false otherwise ***********************************************************/ bool BlockOp::calculateRowId( RID rowId, const int epb, const int width, int& fbo, int& bio ) const { if ( std::numeric_limits::max() == rowId ) return false; fbo = (int)( rowId / epb ); bio = ( rowId & ( epb - 1 )) * width; return true; } /*********************************************************** * DESCRIPTION: * Get the value that represents empty row * PARAMETERS: * colDataType - data type * width - data width in byte * RETURN: * emptyVal - the value of empty row ***********************************************************/ const uint8_t* BlockOp::getEmptyRowValue( const CalpontSystemCatalog::ColDataType colDataType, const int width) const { auto attrs = datatypes::SystemCatalog::TypeAttributesStd(width, 0, -1); // Bulk operation runtime should have m_typeHandler nullptr calling this // Non-bulk operations runtime branch if (m_typeHandler) return m_typeHandler->getEmptyValueForType(attrs); // Bulk operation branch auto* typeHandler = datatypes::TypeHandler::find(colDataType, attrs); return typeHandler->getEmptyValueForType(attrs); } /*********************************************************** * DESCRIPTION: * Get the correct width for a row * PARAMETERS: * colDataType - data type * width - data width in byte * RETURN: * emptyVal - the value of empty row ***********************************************************/ int BlockOp::getCorrectRowWidth( const CalpontSystemCatalog::ColDataType colDataType, const int width ) const { return Convertor::getCorrectRowWidth(colDataType, width); } /*********************************************************** * DESCRIPTION: * Get row id * PARAMETERS: * fbo - file block offset * bio - block internal offset * bbo - byte internal offset * RETURN: * row id ***********************************************************/ RID BlockOp::getRowId( const long fbo, const int width, const int rowPos /*const int bio, const int bbo*/ ) const { // return fbo*BYTE_PER_BLOCK*ROW_PER_BYTE + bio*ROW_PER_BYTE + bbo; return (BYTE_PER_BLOCK / width) * fbo + rowPos; } /*********************************************************** * DESCRIPTION: * Get buffer value * PARAMETERS: * buf - buffer * width - data width in byte * RETURN: * val - buffer value ***********************************************************/ void BlockOp::readBufValue( const unsigned char* buf, void* val, const short width ) const { memcpy( val, buf, width ); } /*********************************************************** * DESCRIPTION: * Reset a buffer * PARAMETERS: * buf - buffer * bufSize - buffer size * RETURN: * none ***********************************************************/ void BlockOp::resetBuf( unsigned char* buf, const int bufSize ) const { memset( buf, 0, bufSize ); } /*********************************************************** * DESCRIPTION: * Fill buffer with empty values * PARAMETERS: * buf - buffer * bufSize - buffer size * emptyVal - empty value * width - type width * RETURN: * none ***********************************************************/ /* static */ void BlockOp::setEmptyBuf( unsigned char* buf, const int bufSize, const uint8_t* emptyVal, const int width ) { const int ARRAY_COUNT = 128; const int NBYTES_IN_ARRAY = width * ARRAY_COUNT; //unsigned char emptyValArray[NBYTES_IN_ARRAY]; unsigned char* emptyValArray = (unsigned char*)alloca(NBYTES_IN_ARRAY); // Optimize buffer initialization by constructing and copying in an array // instead of individual values. This reduces the number of calls to // memcpy(). for(uint8_t* pos = emptyValArray, * end = pos + NBYTES_IN_ARRAY; pos < end; pos += width) //FIXME for no loop { memcpy(pos, emptyVal, width); } int countFull128 = (bufSize / width) / ARRAY_COUNT; int countRemain = (bufSize / width) % ARRAY_COUNT; // Copy in the 128 element array into "buf" as many times as needed if (countFull128 > 0) { for ( int i = 0; i < countFull128; i++ ) memcpy( buf + (i * (NBYTES_IN_ARRAY)), emptyValArray, NBYTES_IN_ARRAY ); } // Initialize the remainder of "buf" that is leftover if (countRemain > 0) { memcpy( buf + (countFull128 * NBYTES_IN_ARRAY), emptyValArray, width * countRemain ); } } /*********************************************************** * DESCRIPTION: * Set a value in a buffer * PARAMETERS: * buf - buffer * val - buffer value * width - data width in byte * RETURN: * none ***********************************************************/ void BlockOp::writeBufValue( unsigned char* buf, const void* val, const size_t width, const bool clear ) const { if ( clear ) memset( buf, 0, width ); memcpy( buf, val, width ); } void BlockOp::findTypeHandler(const int colWidth, const execplan::CalpontSystemCatalog::ColDataType colDataType) { auto attrs = datatypes::SystemCatalog::TypeAttributesStd(colWidth, 0, -1); m_typeHandler = datatypes::TypeHandler::find(colDataType, attrs); } } //end of namespace