recursive bucket scan - we're crashing when passing a slice to go code

This commit is contained in:
mappu 2017-05-21 13:31:28 +12:00
parent 60d71104e8
commit 679d1140cc
5 changed files with 73 additions and 42 deletions

43
main.go
View File

@ -160,38 +160,29 @@ func Bolt_ListBuckets(b ObjectReference, browse []string) ObjectReference {
pNC_Ref := gms.Put(pNC)
go func() {
err := withBoltDBReference(b, func(db *bolt.DB) error {
return db.View(func(tx *bolt.Tx) error {
var err error
if len(browse) == 0 {
// Root-mode
if len(browse) == 0 {
// root mode
err = withBoltDBReference(b, func(db *bolt.DB) error {
return db.View(func(tx *bolt.Tx) error {
return tx.ForEach(func(k []byte, _ *bolt.Bucket) error {
pNC.content <- CallResponse{s: string(k)}
return nil
})
} else {
// Nested-mode
bucket := tx.Bucket([]byte(browse[0]))
if bucket == nil {
return errors.New("Unknown bucket")
}
for i := 1; i < len(browse); i += 1 {
bucket = bucket.Bucket([]byte(browse[i]))
if bucket == nil {
return errors.New("Unknown bucket")
}
}
return bucket.ForEach(func(k, v []byte) error {
pNC.content <- CallResponse{s: string(k)}
return nil
})
}
})
})
})
} else {
// Nested-mode
err = withBrowse_ReadOnly(b, browse, func(db *bolt.DB, tx *bolt.Tx, bucket *bolt.Bucket) error {
return bucket.ForEach(func(k, v []byte) error {
pNC.content <- CallResponse{s: string(k)}
return nil
})
})
}
if err != nil {
pNC.content <- CallResponse{e: err}

View File

@ -32,11 +32,26 @@ static const int REAL_MESSAGE = 103;
bool BoltDB::listBucketsAtRoot(QString& errorOut, NameReciever cb)
{
auto listJob = ::Bolt_ListBucketsAtRoot(this->gmsDbRef);
return pumpNext(listJob, errorOut, cb);
}
bool BoltDB::listBuckets(QStringList bucketPath, QString& errorOut, NameReciever cb)
{
if (bucketPath.size() == 0) {
return listBucketsAtRoot(errorOut, cb);
}
GoSliceManagedWrapper browse(&bucketPath);
auto listJob = ::Bolt_ListBuckets(this->gmsDbRef, browse.slice);
return pumpNext(listJob, errorOut, cb);
}
bool BoltDB::pumpNext(GoInt64 jobRef, QString& errorOut, NameReciever cb)
{
errorOut.clear();
for(;;) {
auto gnr = ::GetNext(listJob);
auto gnr = ::GetNext(jobRef);
if (gnr.r0 == ERROR_AND_STOP_CALLING) {
errorOut.append(QString::fromUtf8(gnr.r1, gnr.r2)); // log error

View File

@ -18,11 +18,17 @@ public:
bool listBucketsAtRoot(QString& errorOut, NameReciever cb);
bool listBuckets(QStringList bucketPath, QString& errorOut, NameReciever cb);
bool getStatsJSON(std::function<void(QString)> onSuccess, std::function<void(QString)> onError);
bool getBucketStatsJSON(QStringList bucketPath, std::function<void(QString)> onSuccess, std::function<void(QString)> onError);
~BoltDB();
protected:
bool pumpNext(GoInt64 jobRef, QString& errorOut, NameReciever cb);
};
#endif // BOLTDB_H

View File

@ -22,12 +22,14 @@ GoSliceManagedWrapper::GoSliceManagedWrapper(QStringList *qsl) :
strings(),
slice()
{
rawStrings.reserve(qsl->size());
strings.reserve(qsl->size());
for (int i = 0; i < qsl->size(); ++i) {
rawStrings.push_back( qsl->at(i).toUtf8() );
strings.push_back(GoString{ rawStrings[i].data(), rawStrings[i].size() });
}
slice.data = static_cast<void*>( & strings.first() );
slice.data = static_cast<void*>( & strings[0] );
slice.len = strings.size(); // * sizeof(GoString);
slice.cap = slice.len;
}

View File

@ -65,26 +65,43 @@ void MainWindow::on_actionOpen_database_triggered()
ui->bucketTree->addTopLevelItem(top);
refreshBucketTree(top);
ui->bucketTree->setCurrentItem(top);
}
void MainWindow::refreshBucketTree(QTreeWidgetItem* top)
void MainWindow::refreshBucketTree(QTreeWidgetItem* itm)
{
ui->bucketTree->clearSelection();
//top->setSelected(true);
ui->bucketTree->setCurrentItem(top);
auto *bdb = GET_BDB(top);
for (int i = top->childCount(); i --> 0;) {
delete top->takeChild(i);
// ui->bucketTree->clearSelection();
QTreeWidgetItem *top = itm;
QStringList browsePath;
while(top->parent() != nullptr) {
browsePath.push_front(top->text(0));
top = top->parent();
}
// Remove existing children
for (int i = itm->childCount(); i --> 0;) {
delete itm->takeChild(i);
}
if (browsePath.size() > 1) {
return; // only go one level deep
}
auto *bdb = GET_BDB(top);
QString error;
bool ok = bdb->listBucketsAtRoot(error, [=](QByteArray qba){
QTreeWidgetItem *child = new QTreeWidgetItem();
child->setText(0, QString::fromUtf8(qba));
child->setIcon(0, QIcon(":/rsrc/table.png"));
top->addChild(child);
});
bool ok = bdb->listBuckets(
browsePath,
error,
[=](QByteArray qba){
QTreeWidgetItem *child = new QTreeWidgetItem();
child->setText(0, QString::fromUtf8(qba));
child->setIcon(0, QIcon(":/rsrc/table.png"));
itm->addChild(child);
refreshBucketTree(child);
}
);
if (!ok) {
QMessageBox qmb;