File indexing completed on 2024-04-21 03:51:40

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 "mtimedb.h"
0009 #include "enginedebug.h"
0010 #include "vectorpostingiterator.h"
0011 #include <algorithm>
0012 
0013 using namespace Baloo;
0014 
0015 MTimeDB::MTimeDB(MDB_dbi dbi, MDB_txn* txn)
0016     : m_txn(txn)
0017     , m_dbi(dbi)
0018 {
0019     Q_ASSERT(txn != nullptr);
0020     Q_ASSERT(dbi != 0);
0021 }
0022 
0023 MTimeDB::~MTimeDB()
0024 {
0025 }
0026 
0027 MDB_dbi MTimeDB::create(MDB_txn* txn)
0028 {
0029     MDB_dbi dbi = 0;
0030     int rc = mdb_dbi_open(txn, "mtimedb", MDB_CREATE | MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED | MDB_INTEGERDUP, &dbi);
0031     if (rc) {
0032         qCWarning(ENGINE) << "MTimeDB::create" << mdb_strerror(rc);
0033         return 0;
0034     }
0035 
0036     return dbi;
0037 }
0038 
0039 MDB_dbi MTimeDB::open(MDB_txn* txn)
0040 {
0041     MDB_dbi dbi = 0;
0042     int rc = mdb_dbi_open(txn, "mtimedb", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED | MDB_INTEGERDUP, &dbi);
0043     if (rc) {
0044         qCWarning(ENGINE) << "MTimeDB::open" << mdb_strerror(rc);
0045         return 0;
0046     }
0047 
0048     return dbi;
0049 }
0050 
0051 void MTimeDB::put(quint32 mtime, quint64 docId)
0052 {
0053     if (!docId) {
0054         qCWarning(ENGINE) << "MTimeDB::put - docId == 0";
0055         return;
0056     }
0057 
0058     MDB_val key;
0059     key.mv_size = sizeof(quint32);
0060     key.mv_data = static_cast<void*>(&mtime);
0061 
0062     MDB_val val;
0063     val.mv_size = sizeof(quint64);
0064     val.mv_data = static_cast<void*>(&docId);
0065 
0066     int rc = mdb_put(m_txn, m_dbi, &key, &val, 0);
0067     if (rc) {
0068         qCWarning(ENGINE) << "MTimeDB::put" << mdb_strerror(rc);
0069     }
0070 }
0071 
0072 QVector<quint64> MTimeDB::get(quint32 mtime)
0073 {
0074     MDB_val key;
0075     key.mv_size = sizeof(quint32);
0076     key.mv_data = static_cast<void*>(&mtime);
0077 
0078     QVector<quint64> values;
0079 
0080     MDB_cursor* cursor;
0081     mdb_cursor_open(m_txn, m_dbi, &cursor);
0082 
0083     MDB_val val{0, nullptr};
0084     int rc = mdb_cursor_get(cursor, &key, &val, MDB_SET);
0085     if (rc) {
0086         if (rc != MDB_NOTFOUND) {
0087             qCWarning(ENGINE) << "MTimeDB::get" << mtime << mdb_strerror(rc);
0088         }
0089         mdb_cursor_close(cursor);
0090         return values;
0091     }
0092 
0093     values << *static_cast<quint64*>(val.mv_data);
0094 
0095     while (1) {
0096         rc = mdb_cursor_get(cursor, &key, &val, MDB_NEXT_DUP);
0097         if (rc) {
0098             if (rc != MDB_NOTFOUND) {
0099                 qCWarning(ENGINE) << "MTimeDB::get (loop)" << mtime << mdb_strerror(rc);
0100             }
0101             break;
0102         }
0103         values << *static_cast<quint64*>(val.mv_data);
0104     }
0105 
0106     mdb_cursor_close(cursor);
0107     std::sort(values.begin(), values.end());
0108     values.erase(std::unique(values.begin(), values.end()), values.end());
0109     return values;
0110 }
0111 
0112 void MTimeDB::del(quint32 mtime, quint64 docId)
0113 {
0114     MDB_val key;
0115     key.mv_size = sizeof(quint32);
0116     key.mv_data = static_cast<void*>(&mtime);
0117 
0118     MDB_val val;
0119     val.mv_size = sizeof(quint64);
0120     val.mv_data = static_cast<void*>(&docId);
0121 
0122     int rc = mdb_del(m_txn, m_dbi, &key, &val);
0123     if (rc != 0 && rc != MDB_NOTFOUND) {
0124         qCWarning(ENGINE) << "MTimeDB::del" << mtime << docId << mdb_strerror(rc);
0125     }
0126 }
0127 
0128 //
0129 // Posting Iterator
0130 //
0131 PostingIterator* MTimeDB::iterRange(quint32 beginTime, quint32 endTime)
0132 {
0133     if (endTime < beginTime) {
0134         return nullptr;
0135     }
0136 
0137     MDB_val key;
0138     key.mv_size = sizeof(quint32);
0139     key.mv_data = &beginTime;
0140 
0141     MDB_cursor* cursor;
0142     mdb_cursor_open(m_txn, m_dbi, &cursor);
0143 
0144     MDB_val val{0, nullptr};
0145     int rc = mdb_cursor_get(cursor, &key, &val, MDB_SET_RANGE);
0146     if (rc) {
0147         if (rc != MDB_NOTFOUND) {
0148             qCWarning(ENGINE) << "MTimeDB::iterRange" << beginTime << endTime << mdb_strerror(rc);
0149         }
0150         mdb_cursor_close(cursor);
0151         return nullptr;
0152     }
0153 
0154     QVector<quint64> results;
0155 
0156     while (1) {
0157         quint32 time = *static_cast<quint32*>(key.mv_data);
0158         if (time > endTime) {
0159             break;
0160         }
0161         results << *static_cast<quint64*>(val.mv_data);
0162 
0163         rc = mdb_cursor_get(cursor, &key, &val, MDB_NEXT);
0164         if (rc) {
0165             if (rc != MDB_NOTFOUND) {
0166                 qCWarning(ENGINE) << "MTimeDB::iterRange (loop)" << beginTime << endTime << mdb_strerror(rc);
0167             }
0168             break;
0169         }
0170     }
0171 
0172     mdb_cursor_close(cursor);
0173 
0174     if (results.isEmpty()) {
0175         return nullptr;
0176     }
0177     std::sort(results.begin(), results.end());
0178     results.erase(std::unique(results.begin(), results.end()), results.end());
0179     return new VectorPostingIterator(results);
0180 }
0181 
0182 QMap<quint32, quint64> MTimeDB::toTestMap() const
0183 {
0184     MDB_cursor* cursor;
0185     mdb_cursor_open(m_txn, m_dbi, &cursor);
0186 
0187     MDB_val key = {0, nullptr};
0188     MDB_val val;
0189 
0190     QMap<quint32, quint64> map;
0191     while (1) {
0192         int rc = mdb_cursor_get(cursor, &key, &val, MDB_NEXT);
0193         if (rc) {
0194             qCDebug(ENGINE) << "MTimeDB::toTestMap" << mdb_strerror(rc);
0195             break;
0196         }
0197 
0198         const quint32 time = *(static_cast<quint32*>(key.mv_data));
0199         const quint64 id = *(static_cast<quint64*>(val.mv_data));
0200         map.insert(time, id);
0201     }
0202 
0203     mdb_cursor_close(cursor);
0204     return map;
0205 }