Berkeley DB에서 Dbt::get_data() 호출 시 오류가 발생합니다.

조회수 1811회

현재 Berkeley DB C++ API를 사용 중입니다.

DB에서 key 값이 있는지 확인하고 없으면 새 값을, 있으면 업데이트하는 프로그램입니다. 해당 key 값의 data 크기를 알 수 없습니다. 그래서 data의 flag를 DB_DBT_MALLOC으로 설정한 뒤, 해당 data를 data.get_data(); 으로 읽어 캐스팅하여 사용하려고 합니다. 그런데, 캐스팅하는 과정 (2)에서 실행 도중 오류가 발생하는데, 감을 잡을 수가 없습니다. DB_DBT_MALLOC 이나 Dbt::get_data() 함수를 제대로 사용한 것인지도 궁금합니다.

void MyDb::insertTerm(char* term, int doc_id)
{
    Dbt key, data;

    pair_int putData;  // std::vector<std::pair<int,int>>

    key.set_data(term);
    key.set_size(strlen(term) + 1);
    key.set_flags(DB_DBT_USERMEM);

    int ret = getDb().get(NULL, &key, &data, 0); 

    if (ret < 0) // key가 존재 하지 않을 때
    {
        putData.push_back(std::make_pair(doc_id, 1));

        // data를 저장할 땐, putData의 크기를 알기에 아래와 같이 설정.
        data.set_data(&putData);
        data.set_size(sizeof(putData) + (sizeof(std::pair<int, int>) * putData.capacity()));
        data.set_flags(DB_DBT_USERMEM);

        ret = getDb().put(NULL, &key, &data, DB_NOOVERWRITE);
    }
    else
    {

        data.set_flags(DB_DBT_MALLOC); // (1)

        putData = *((pair_int*)data.get_data());   // (2)

        bool c = false;
        auto it = putData.begin();
        for (; it != putData.end(); it++) 
        {
            if (it->first == doc_id) 
            {
                it->second++;
                c = true;
                break;
            }
        }

        // key값이 존재하지만, doc_id는 새로운 값일 경우.
        if (c != true)
            putData.push_back(std::make_pair(doc_id, 1));

        data.set_data(&putData);
        ret = getDb().put(NULL, &key, &data, 0); //데이터 쓰기
    }


}

  • berkeley db 버전이 어떻게 되나요?^^ 알 수 없는 사용자 2016.5.20 13:35
  • berkeley db 의 버전은 12cR1 6.2.23 입니다. 현재, DB에 Put하는 Data의 타입이 char*, int* 과 같이 기본형 타입은 제대로 동작합니다. 찾아보니, vector와 같은 컨테이너는 sequence of bytes 형태로 저장해야 한다더군요. 아무래도 vector를 그대로 Put해서 무리가 있었나 봅니다. Chocolate 2016.5.20 15:36
  • 빠진 코드가 있어서 수정하였습니다. Chocolate 2016.5.20 15:57
  • 오류 메시지가 어떻게 되나요?^^ 알 수 없는 사용자 2016.5.20 16:02
  • std::bad_alloc 예외가 발생하면서 동작이 멈춥니다. Chocolate 2016.5.20 16:11
  • 제가 실행해서 확인해 보진 못했지만, flags가 DB_DBT_MALLOC과 DB_DBT_USERMEM이 같이 설정되면 에러가 발생될 수 있다고 합니다^^ 알 수 없는 사용자 2016.5.20 16:34
  • 조건에 따라 flags를 다르게 설정하기 때문에 문제되지 않는다고 생각됩니다만, 다시 검토해봐야겠습니다. 답변 감사합니다 :) Chocolate 2016.5.20 16:48
  • 도움이 되면 좋겠습니다^^ 알 수 없는 사용자 2016.5.20 17:05

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)