bdb_types.cpp
来自「ncbi源码」· C++ 代码 · 共 966 行 · 第 1/2 页
CPP
966 行
/* * =========================================================================== * PRODUCTION $Log: bdb_types.cpp,v $ * PRODUCTION Revision 1000.3 2004/06/01 18:37:36 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.23 * PRODUCTION * =========================================================================== *//* $Id: bdb_types.cpp,v 1000.3 2004/06/01 18:37:36 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Author: Anatoliy Kuznetsov * * File Description: BDB libarary types implementations. * */#include <ncbi_pch.hpp>#include <corelib/ncbi_bswap.hpp>#include <bdb/bdb_types.hpp>#include <db.h>BEGIN_NCBI_SCOPEstaticconst unsigned char* s_GetLString(const unsigned char* str, bool check_legacy, int* str_len){ _ASSERT(str); _ASSERT(str_len); // string length reconstruction *str_len = (str[0]) | (str[1] << 8) | (str[2] << 16) | (str[3] << 24); if (check_legacy) { if (*str_len < 0) { // true L-string *str_len = -(*str_len); str += 4; } else { *str_len = ::strlen((const char*)str); } } else { // no legacy strings if (*str_len < 0) { // true L-string *str_len = -(*str_len); str += 4; } else { _ASSERT(0); // positive length ! } } return str;}static const unsigned char* s_GetLString(const DBT* val, bool check_legacy, int* str_len){ const unsigned char* str = (const unsigned char*)val->data; if (val->size <= 4) { // looks like legacy C-string _ASSERT(check_legacy); *str_len = ::strlen((const char*)str); return str; } return s_GetLString(str, check_legacy, str_len);}extern "C"{/////////////////////////////////////////////////////////////////////////////// BDB comparison functions//int BDB_UintCompare(DB*, const DBT* val1, const DBT* val2){ unsigned int v1, v2; ::memcpy(&v1, val1->data, sizeof(unsigned)); ::memcpy(&v2, val2->data, sizeof(unsigned)); return (v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0);}int BDB_IntCompare(DB*, const DBT* val1, const DBT* val2){ int v1, v2; ::memcpy(&v1, val1->data, sizeof(int)); ::memcpy(&v2, val2->data, sizeof(int)); return (v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0);}int BDB_Int2Compare(DB*, const DBT* val1, const DBT* val2){ Int2 v1, v2; ::memcpy(&v1, val1->data, sizeof(Int2)); ::memcpy(&v2, val2->data, sizeof(Int2)); return (v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0);}int BDB_UCharCompare(DB*, const DBT* val1, const DBT* val2){ const unsigned char& v1=*static_cast<unsigned char*>(val1->data); const unsigned char& v2=*static_cast<unsigned char*>(val2->data); return (v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0);}int BDB_FloatCompare(DB*, const DBT* val1, const DBT* val2){ float v1, v2; ::memcpy(&v1, val1->data, sizeof(v1)); ::memcpy(&v2, val2->data, sizeof(v2)); return (v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0);}int BDB_DoubleCompare(DB*, const DBT* val1, const DBT* val2){ double v1, v2; ::memcpy(&v1, val1->data, sizeof(v1)); ::memcpy(&v2, val2->data, sizeof(v2)); return (v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0);}int BDB_StringCompare(DB*, const DBT* val1, const DBT* val2){ return ::strcmp((const char*)val1->data, (const char*)val2->data);}int BDB_LStringCompare(DB* db, const DBT* val1, const DBT* val2){ const CBDB_BufferManager* fbuf1 = static_cast<CBDB_BufferManager*> (db->app_private); bool check_legacy = fbuf1->IsLegacyStrings(); const unsigned char* str1; const unsigned char* str2; int str_len1; int str_len2; str1 = s_GetLString(val1, check_legacy, &str_len1); str2 = s_GetLString(val2, check_legacy, &str_len2); int cmp_len = min(str_len1, str_len2); int r = ::memcmp(str1, str2, cmp_len); if (r == 0) { return (str_len1 < str_len2) ? -1 : ((str_len2 < str_len1) ? 1 : 0); } return r;}int BDB_StringCaseCompare(DB*, const DBT* val1, const DBT* val2){ return NStr::strcasecmp((const char*)val1->data, (const char*)val2->data);}int BDB_Compare(DB* db, const DBT* val1, const DBT* val2){ const CBDB_BufferManager* fbuf1 = static_cast<CBDB_BufferManager*> (db->app_private); bool byte_swapped = fbuf1->IsByteSwapped(); _ASSERT(fbuf1); const char* p1 = static_cast<char*> (val1->data); const char* p2 = static_cast<char*> (val2->data); unsigned int cmp_limit = fbuf1->GetFieldCompareLimit(); if (cmp_limit == 0) { cmp_limit = fbuf1->FieldCount(); } else { _ASSERT(cmp_limit <= fbuf1->FieldCount()); } for (unsigned int i = 0; i < cmp_limit; ++i) { const CBDB_Field& fld1 = fbuf1->GetField(i); int ret = fld1.Compare(p1, p2, byte_swapped); if ( ret ) return ret; p1 += fld1.GetDataLength(p1); p2 += fld1.GetDataLength(p2); } return 0;}int BDB_ByteSwap_UintCompare(DB*, const DBT* val1, const DBT* val2){ unsigned int v1, v2; v1 = (unsigned int) CByteSwap::GetInt4((unsigned char*)val1->data); v2 = (unsigned int) CByteSwap::GetInt4((unsigned char*)val2->data); return (v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0);}int BDB_ByteSwap_IntCompare(DB*, const DBT* val1, const DBT* val2){ int v1, v2; v1 = CByteSwap::GetInt4((unsigned char*)val1->data); v2 = CByteSwap::GetInt4((unsigned char*)val2->data); return (v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0);}int BDB_ByteSwap_Int2Compare(DB*, const DBT* val1, const DBT* val2){ Int2 v1, v2; v1 = CByteSwap::GetInt2((unsigned char*)val1->data); v2 = CByteSwap::GetInt2((unsigned char*)val2->data); return (v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0);}int BDB_ByteSwap_FloatCompare(DB*, const DBT* val1, const DBT* val2){ float v1, v2; v1 = CByteSwap::GetFloat((unsigned char*)val1->data); v2 = CByteSwap::GetFloat((unsigned char*)val2->data); return (v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0);}int BDB_ByteSwap_DoubleCompare(DB*, const DBT* val1, const DBT* val2){ double v1, v2; v1 = CByteSwap::GetDouble((unsigned char*)val1->data); v2 = CByteSwap::GetDouble((unsigned char*)val2->data); return (v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0);}} // extern "C"/////////////////////////////////////////////////////////////////////////////// IBDB_Field:://IBDB_Field::~IBDB_Field() {}/////////////////////////////////////////////////////////////////////////////// CBDB_Field:://CBDB_Field::CBDB_Field(ELengthType length_type): m_BufferManager(0), m_Buffer(0), m_BufferSize(0), m_BufferIdx(0){ m_Flags.VariableLength = (length_type == eFixedLength) ? 0 : 1; m_Flags.Attached = 0; m_Flags.Nullable = 0;}BDB_CompareFunction CBDB_Field::GetCompareFunction(bool /*byte_swapped*/) const{ return BDB_Compare; }/////////////////////////////////////////////////////////////////////////////// CBDB_BufferManager:://CBDB_BufferManager::CBDB_BufferManager() : m_Buffer(0), m_BufferSize(0), m_PackedSize(0), m_DBT_Size(0), m_Packable(false), m_ByteSwapped(false), m_Nullable(false), m_NullSetSize(0), m_CompareLimit(0), m_LegacyString(false){}CBDB_BufferManager::~CBDB_BufferManager(){ delete [] m_Buffer;}void CBDB_BufferManager::Bind(CBDB_Field* field, ENullable is_nullable){ m_Fields.push_back(field); m_Ptrs.push_back(0); unsigned field_idx = (unsigned)(m_Fields.size() - 1); field->SetBufferIdx(field_idx); if ( !m_Packable ) { // If we bind any var length field, then record becomes packable m_Packable = field->IsVariableLength(); } if (is_nullable == eNullable) field->SetNullable();}int CBDB_BufferManager::GetFieldIndex(const string& name) const{ for (size_t i = 0; i < m_Fields.size(); ++i) { const CBDB_Field& field = *m_Fields[i]; const string& fname = field.GetName(); if (NStr::CompareNocase(name, fname) == 0) { return i; } } return -1;}size_t CBDB_BufferManager::ComputeBufferSize() const{ size_t buf_len = 0; for (size_t i = 0; i < m_Fields.size(); ++i) { const CBDB_Field& field = *m_Fields[i]; buf_len += field.GetBufferSize(); } return buf_len;}void CBDB_BufferManager::CheckNullConstraint() const{ if ( !IsNullable() ) return; for (size_t i = 0; i < m_Fields.size(); ++i) { const CBDB_Field& fld = *m_Fields[i]; if (!fld.IsNullable() && TestNullBit((unsigned)i)) { string message("NULL field in database operation."); const string& field_name = fld.GetName(); if ( !field_name.empty() ) { message.append("(Field:"); message.append(field_name); message.append(")"); } BDB_THROW(eNull, message); } }}void CBDB_BufferManager::Construct(){ _ASSERT(m_Fields.size()); // Buffer construction: fields size calculation. m_BufferSize = ComputeBufferSize(); if ( IsNullable() ) { m_NullSetSize = ComputeNullSetSize(); m_BufferSize += m_NullSetSize; } delete [] m_Buffer; m_Buffer = 0; m_Buffer = new char[m_BufferSize]; ::memset(m_Buffer, 0, m_BufferSize); // Record construction: set element offsets(pointers) char* buf_ptr = (char*) m_Buffer; buf_ptr += m_NullSetSize; for (size_t i = 0; i < m_Fields.size(); ++i) { CBDB_Field& df = *m_Fields[i]; m_Ptrs[i] = buf_ptr; df.SetBufferManager(this); df.SetBuffer(buf_ptr); buf_ptr += df.GetBufferSize(); } m_PackedSize = 0; // not packed}BDB_CompareFunction CBDB_BufferManager::GetCompareFunction() const{ if (m_Fields.size() > 1) return BDB_Compare; bool byte_swapped = IsByteSwapped(); return m_Fields[0]->GetCompareFunction(byte_swapped);}void CBDB_BufferManager::ArrangePtrsPacked(){ _ASSERT(m_Fields.size()); if ( !IsPackable() ) { m_PackedSize = m_BufferSize; return; } char* buf_ptr = m_Buffer; buf_ptr += m_NullSetSize; m_PackedSize = m_NullSetSize; for (size_t i = 0; i < m_Fields.size(); ++i) { CBDB_Field& df = *m_Fields[i]; df.SetBuffer(buf_ptr); size_t len = df.GetDataLength(buf_ptr); buf_ptr += len; m_PackedSize += len; }}unsigned int CBDB_BufferManager::Pack(){ _ASSERT(m_Fields.size()); if (m_PackedSize != 0) return (unsigned)m_PackedSize; if ( !IsPackable() ) { m_PackedSize = m_BufferSize; return (unsigned)m_PackedSize; } char* new_ptr = m_Buffer; new_ptr += m_NullSetSize; m_PackedSize = m_NullSetSize; for (size_t i = 0; i < m_Fields.size(); ++i) { CBDB_Field& df = *m_Fields[i];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?