3

レコードを1つずつ250万回挿入する空間ライブラリを使用してR*ツリーを正常に構築した後、バルクロードを使用してR*ツリーを作成しようとしました。データをBulkLoaderに繰り返し提供するためにDBStreamクラスを実装しました。基本的に、次のメソッドを呼び出し、バルクローダー用のData(コード内のd変数)オブジェクトを準備しました。

void DBStream::retrieveTuple() {
if (query.next()) {
    hasNextBool = true;

    int gid = query.value(0).toInt();

            // allocate memory for bounding box
            // this streets[gid].first returns bbox[4]
    double* bbox = streets[gid].first;

            // filling the bounding box values
    bbox[0] = query.value(1).toDouble();
    bbox[1] = query.value(2).toDouble();
    bbox[2] = query.value(3).toDouble();
    bbox[3] = query.value(4).toDouble();

    rowId++;

    r = new SpatialIndex::Region();
    d = new SpatialIndex::RTree::Data((size_t) 0, (byte*) 0, *r, gid);
    r->m_dimension = 2;
    d->m_pData = 0;
    d->m_dataLength = 0;

    r->m_pLow = bbox;
    r->m_pHigh = bbox + 2;
    d->m_id = gid;
} else {
    d = 0;
    hasNextBool = false;
    cout << "stream is finished d:" << d << endl;
}
}

DBStreamオブジェクトを初期化し、次の方法で一括読み込みを呼び出します。

// creating a main memory RTree
memStorage = StorageManager::createNewMemoryStorageManager();

size_t capacity = 1000;
bool bWriteThrough = false;
fileInMem = StorageManager
   ::createNewRandomEvictionsBuffer(*memStorage, capacity, bWriteThrough);

double fillFactor = 0.7;
size_t indexCapacity = 100;
size_t leafCapacity = 100;
size_t dimension = 2;
RTree::RTreeVariant rv = RTree::RV_RSTAR;

DBStream dstream();

tree = RTree::createAndBulkLoadNewRTree(SpatialIndex::RTree::BLM_STR, dstream,
   *fileInMem,
   fillFactor, indexCapacity,
   leafCapacity, dimension, rv, indexIdentifier);

cout << "BulkLoading done" << endl;

一括読み込みでは、next()関数とhasNext()関数を呼び出し、データを取得して並べ替えてから、構築フェーズで障害をセグメント化します。手がかりはありますか?ええ、エラーは次のとおりです。

    RTree::BulkLoader: Building level 0
    terminate called after throwing an instance of 'Tools::IllegalArgumentException'
4

1 に答える 1

1

問題はおそらくメモリ割り当てとコードのいくつかのバグにあります(メモリ割り当てにもある程度関連しています)。まず、Data変数のプロパティを適切に割り当てる必要があります。

memcpy(data->m_region.m_pLow, bbox, 2 * sizeof(double));
memcpy(data->m_region.m_pHigh, bbox + 2, 2 * sizeof(double));
data->m_id = gid;

2番目(そして最も重要なこと)のgetNextは、すべての値を持つ新しいオブジェクトを返す必要があります。

RTree::Data *p = new RTree::Data(returnData->m_dataLength, returnData->m_pData,
returnData->m_region, returnData->m_id);
return returnData;

メモリの割り当て解除はRTreeによって行われるため、ここで注意を払う必要はありません。

于 2012-10-30T13:49:57.837 に答える