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 + -
显示快捷键?