File indexing completed on 2024-04-14 03:49:42

0001 /*
0002     This file is part of the KDE Baloo project.
0003     SPDX-FileCopyrightText: 2015 Vishesh Handa <vhanda@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-or-later
0006 */
0007 
0008 #include "enginedebug.h"
0009 #include "positiondb.h"
0010 #include "positioncodec.h"
0011 #include "positioninfo.h"
0012 #include "postingiterator.h"
0013 #include "vectorpositioninfoiterator.h"
0014 
0015 using namespace Baloo;
0016 
0017 PositionDB::PositionDB(MDB_dbi dbi, MDB_txn* txn)
0018     : m_txn(txn)
0019     , m_dbi(dbi)
0020 {
0021     Q_ASSERT(txn != nullptr);
0022     Q_ASSERT(dbi != 0);
0023 }
0024 
0025 PositionDB::~PositionDB()
0026 {
0027 }
0028 
0029 MDB_dbi PositionDB::create(MDB_txn* txn)
0030 {
0031     MDB_dbi dbi = 0;
0032     int rc = mdb_dbi_open(txn, "positiondb", MDB_CREATE, &dbi);
0033     if (rc) {
0034         qCWarning(ENGINE) << "PositionDB::create" << mdb_strerror(rc);
0035         return 0;
0036     }
0037 
0038     return dbi;
0039 }
0040 
0041 MDB_dbi PositionDB::open(MDB_txn* txn)
0042 {
0043     MDB_dbi dbi = 0;
0044     int rc = mdb_dbi_open(txn, "positiondb", 0, &dbi);
0045     if (rc) {
0046         qCWarning(ENGINE) << "PositionDB::open" << mdb_strerror(rc);
0047         return 0;
0048     }
0049 
0050     return dbi;
0051 }
0052 
0053 void PositionDB::put(const QByteArray& term, const QVector<PositionInfo>& list)
0054 {
0055     Q_ASSERT(!term.isEmpty());
0056     Q_ASSERT(!list.isEmpty());
0057 
0058     MDB_val key;
0059     key.mv_size = term.size();
0060     key.mv_data = static_cast<void*>(const_cast<char*>(term.constData()));
0061 
0062     QByteArray data = PositionCodec::encode(list);
0063 
0064     MDB_val val;
0065     val.mv_size = data.size();
0066     val.mv_data = static_cast<void*>(data.data());
0067 
0068     int rc = mdb_put(m_txn, m_dbi, &key, &val, 0);
0069     if (rc) {
0070         qCWarning(ENGINE) << "PositionDB::put" << mdb_strerror(rc);
0071     }
0072 }
0073 
0074 QVector<PositionInfo> PositionDB::get(const QByteArray& term)
0075 {
0076     Q_ASSERT(!term.isEmpty());
0077 
0078     MDB_val key;
0079     key.mv_size = term.size();
0080     key.mv_data = static_cast<void*>(const_cast<char*>(term.constData()));
0081 
0082     MDB_val val{0, nullptr};
0083     int rc = mdb_get(m_txn, m_dbi, &key, &val);
0084     if (rc) {
0085         if (rc != MDB_NOTFOUND) {
0086             qCDebug(ENGINE) << "PositionDB::get" << term << mdb_strerror(rc);
0087         }
0088         return QVector<PositionInfo>();
0089     }
0090 
0091     QByteArray data = QByteArray::fromRawData(static_cast<char*>(val.mv_data), val.mv_size);
0092 
0093     return PositionCodec::decode(data);
0094 }
0095 
0096 void PositionDB::del(const QByteArray& term)
0097 {
0098     Q_ASSERT(!term.isEmpty());
0099 
0100     MDB_val key;
0101     key.mv_size = term.size();
0102     key.mv_data = static_cast<void*>(const_cast<char*>(term.constData()));
0103 
0104     int rc = mdb_del(m_txn, m_dbi, &key, nullptr);
0105     if (rc != 0 && rc != MDB_NOTFOUND) {
0106         qCDebug(ENGINE) << "PositionDB::del" << term << mdb_strerror(rc);
0107     }
0108 }
0109 
0110 //
0111 // Query
0112 //
0113 
0114 VectorPositionInfoIterator* PositionDB::iter(const QByteArray& term)
0115 {
0116     Q_ASSERT(!term.isEmpty());
0117 
0118     MDB_val key;
0119     key.mv_size = term.size();
0120     key.mv_data = static_cast<void*>(const_cast<char*>(term.constData()));
0121 
0122     MDB_val val{0, nullptr};
0123     int rc = mdb_get(m_txn, m_dbi, &key, &val);
0124     if (rc) {
0125         qCDebug(ENGINE) << "PositionDB::iter" << term << mdb_strerror(rc);
0126         return nullptr;
0127     }
0128 
0129     QByteArray ba(static_cast<char*>(val.mv_data), val.mv_size);
0130     return new VectorPositionInfoIterator(PositionCodec::decode(ba));
0131 }
0132 
0133 QMap<QByteArray, QVector<PositionInfo>> PositionDB::toTestMap() const
0134 {
0135     MDB_cursor* cursor;
0136     mdb_cursor_open(m_txn, m_dbi, &cursor);
0137 
0138     MDB_val key = {0, nullptr};
0139     MDB_val val;
0140 
0141     QMap<QByteArray, QVector<PositionInfo>> map;
0142     while (1) {
0143         int rc = mdb_cursor_get(cursor, &key, &val, MDB_NEXT);
0144         if (rc == MDB_NOTFOUND) {
0145             break;
0146         }
0147         if (rc) {
0148             qCDebug(ENGINE) << "PositionDB::toTestMap" << mdb_strerror(rc);
0149             break;
0150         }
0151 
0152         const QByteArray ba(static_cast<char*>(key.mv_data), key.mv_size);
0153         const QByteArray data(static_cast<char*>(val.mv_data), val.mv_size);
0154         const QVector<PositionInfo> vinfo = PositionCodec().decode(data);
0155         map.insert(ba, vinfo);
0156     }
0157 
0158     mdb_cursor_close(cursor);
0159     return map;
0160 }