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 }