0

我编写了一个 C++ 方法,可以重新索引键值对。我正在使用 DB 游标来获取数据并将其存储在一个结构中。将结构复制到另一个结构并修改内容并将其写回数据库(db.put())。这里的代码似乎进入了一个无限循环,当我按下 ctrl+C 时,它以分段错误结束。我是 C++ 和 Berkeley DB 的新手。任何帮助将不胜感激。

int BerkeleyDb::reindex(string dbFileName, string dbAttribName,string inputValue)
{
  BdbStruct findExistCmdbData;
  BdbStruct* insertCmdbData;
  Dbt tempKeyExist;
  Dbt tempDataExist;
  Dbt tempKeyAndIndex;
  Dbt tempDataAndIndex; 
  DbTxn *txn = NULL;
  int retVal = 0;
  int keyNotExist=0;
  Dbc *keyExistCursor = NULL;  
  Dbc *delCursor = NULL;
  int startIndex = 0;
  int newIndex = 0;
  int oldIndex = 0;
  int offSet = 0;

  try
  {
    // open the DB
    Db writedb(&dbenv, 0);
    // Begin Transactions
    //retVal = dbenv.txn_begin(NULL, &txn, 0);

    if(retVal != 0)
    {
      dbenv.err(retVal,"error in writeBDb::txn_begin");
    }

    // Open the DB file for writing
    writedb.open(NULL,StrtoCharConvert(dbFileName), NULL, DB_BTREE, DB_CREATE |DB_AUTO_COMMIT, DB_OPEN_PERMISSION);

    // Initiate cursors
    retVal = writedb.cursor(txn,&delCursor,0);
    if(retVal != 0)
    {
      writedb.err (retVal, "error while opening delete cursor");
    }

    retVal = writedb.cursor(txn,&keyExistCursor,0);

    if(retVal != 0)
    {
      writedb.err (retVal, "error while opening cursor");
    }

    //to find whether key exist 
    tempKeyExist.set_size(sizeof( findExistCmdbData.BdbKeyattribute));
    tempDataExist.set_size(sizeof(BdbStruct));
    while(!(retVal =  keyExistCursor->get(&tempKeyExist, &tempDataExist, DB_NEXT)))
    {
      findExistCmdbData = *(BdbStruct*)(tempDataExist.get_data());
      if(string(findExistCmdbData.BdbKeyattribute)== dbAttribName)
      {    
        keyNotExist=1;
      }
    }
    retVal = keyExistCursor->close();
    if(retVal != 0)
    {
      dbenv.err(retVal,"error while closing cursor");
    }

    if(keyNotExist==0)
    {
      cerr << "key not exist"<<endl;
      retVal = txn->commit(DB_DEFAULT_FLAG);
      if(retVal != 0)
      { 
        dbenv.err(retVal,"error while committing transaction");
      }
    }
    else
    {
      try
      {
        startIndex = BerkeleyDb::minIndex(dbFileName,dbAttribName);
      }
      catch (exception &e)
      {
        cerr << "minIndex failure exception" << e.what() << endl;
      }

      newIndex = atoi(inputValue.c_str());
      oldIndex = startIndex;
      offSet = newIndex - startIndex;

      tempKeyAndIndex.set_size(sizeof(findExistCmdbData.BdbKeyattribute));
      tempDataAndIndex.set_size(sizeof(BdbStruct));

      while(!(retVal =  delCursor->get(&tempKeyAndIndex, &tempDataAndIndex, DB_NEXT)))
      {
        findExistCmdbData = *(BdbStruct*)(tempDataAndIndex.get_data());
        if((string(findExistCmdbData.BdbKeyattribute)== dbAttribName))
        {
          insertCmdbData = new BdbStruct;
          strcpy(insertCmdbData->BdbKeyattribute, findExistCmdbData.BdbKeyattribute);
          insertCmdbData->BdbIndexattribute = findExistCmdbData.BdbIndexattribute + offSet;
          strcpy(insertCmdbData->BdbValueattribute, findExistCmdbData.BdbValueattribute);

          // writing Key attribute to the DB file
          Dbt key(insertCmdbData->BdbKeyattribute, sizeof(insertCmdbData->BdbKeyattribute));

          // Writing Value attribute to the DB file
          Dbt value((insertCmdbData), (sizeof(BdbStruct)));

          retVal = writedb.put(txn, &key, &value, 0);
          if (retVal !=0)
          {
            writedb.err(retVal, "Error while writing to Db");
          }
          oldIndex++;
          newIndex++;
          // Memory management for Key - Value and structure
          memset(&key, 0, sizeof(key));
          memset(&value, 0, sizeof(value));
          memset(insertCmdbData, 0, sizeof(BdbStruct));
          delete insertCmdbData;
        }
      retVal = txn->commit(DB_DEFAULT_FLAG);
      if(retVal != 0)
      { 
        dbenv.err(retVal,"error while committing transaction");
      }
      }

      retVal = delCursor->close();
      if(retVal != 0)
      {
        dbenv.err(retVal,"error while closing cursor");
      }

      retVal = txn->commit(DB_DEFAULT_FLAG);
      if(retVal != 0)
      {
        dbenv.err(retVal,"error while committing transaction");
      }
    }
    writedb.close(DB_DEFAULT_FLAG);
  }

  catch (DbException& dbex)
  {
    dbenv.err(dbex.get_errno(), "Db exception caught");
    return 1;
  }
  return 0;

} 
4

0 回答 0