date indexing

ver3
acetone 2023-04-20 12:47:05 +03:00
parent 69b14e836a
commit 1ff86fe5a3
6 changed files with 110 additions and 10 deletions

View File

@ -22,6 +22,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "logger.h"
#include "versioninformation.h"
#include "fsconstants.h"
#include "ircloggerlist.h"
#include <QFile>
#include <QListIterator>
@ -217,6 +218,8 @@ bool Config::initFromJson(const QJsonObject &config, QString* errorString)
channel.push_front('#');
}
network->channels.push_back(channel);
IRCLoggerList::get(network->networkName, channel); // Create logger instanse for date indexing at start
}
if (network->channels.isEmpty())
{

View File

@ -32,10 +32,10 @@ HttpServer::HttpServer(QObject *parent) : QTcpServer(parent)
if (not listen(QHostAddress(Config::webUiAddress()), Config::webUiPort()))
{
qFatal("%s", QString("HTTP server not binded at " + Config::webUiAddress() + ":" + QString::number(Config::webUiPort())).toStdString().c_str());
qFatal("%s", QString("[WebUI] HTTP server not binded at " + Config::webUiAddress() + ":" + QString::number(Config::webUiPort())).toStdString().c_str());
}
qInfo().noquote() << "HTTP server started at" << Config::webUiAddress() + ":" + QString::number( Config::webUiPort() );
qInfo().noquote() << "HTTP server threads:" << m_pool->maxThreadCount();
qInfo().noquote() << "[WebUI] HTTP server started at" << Config::webUiAddress() + ":" + QString::number( Config::webUiPort() );
qInfo().noquote() << "[WebUI] HTTP server threads:" << m_pool->maxThreadCount();
}
HttpServer::~HttpServer()
@ -47,7 +47,7 @@ HttpServer::~HttpServer()
m_pool->clear();
if (not m_pool->waitForDone(100))
{
qWarning() << "Thread pool of HTTP server not finished at 100ms";
qWarning() << "[WebUI] Thread pool of HTTP server not finished at 100ms";
}
m_pool->deleteLater();
}

View File

@ -27,8 +27,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <QDebug>
#define LOG_WARN qWarning().noquote() << "HttpServerSocket:"
#define LOG_DEBUG qDebug().noquote() << "HttpServerSocket:"
#define LOG_CRIT qCritical().noquote() << "[WebUI] HttpServerSocket:"
#define LOG_WARN qWarning().noquote() << "[WebUI] HttpServerSocket:"
#define LOG_INFO qInfo().noquote() << "[WebUI] HttpServerSocket:"
#define LOG_DEBUG qDebug().noquote() << "[WebUI] HttpServerSocket:"
constexpr const int VALUE_BEFORE_SPACE_MAX_SIZE = 300;
constexpr const int HEADERS_MAX_SIZE = 1000;
@ -55,7 +57,7 @@ void HttpServerSocket::run()
{
if (not m_socketDescriptor)
{
qCritical() << "HttpServerSocket::run() called with invalid socket descriptor";
LOG_CRIT << "run() called with invalid socket descriptor";
return;
}

View File

@ -24,6 +24,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <QDir>
#include <QDebug>
#include <QDirIterator>
#include <QFileInfo>
constexpr const int CACHE_SIZE = 64;
@ -40,6 +42,16 @@ IRCLogger::IRCLogger(const QString &network, const QString &channel) :
qCritical() << "Can't create chat log directory:" << m_rootDir;
}
}
else
{
doDateIndex();
}
}
QList<IRCLogger::Year> IRCLogger::dateIndex() const
{
QMutexLocker lock (&m_dateIndexMtx);
return m_dateIndex;
}
void IRCLogger::addMessage(const QString &sender, const QString &message)
@ -59,6 +71,7 @@ void IRCLogger::addMessage(const QString &sender, const QString &message)
qCritical() << "IRCLogger::addMessage can't create directory:" << dir;
return;
}
doDateIndex();
}
QFile file (datePath(currentDate));
@ -135,6 +148,78 @@ QList<QSharedPointer<IRCLogger::Message>> IRCLogger::getMessages(const QDateTime
return result;
}
void IRCLogger::doDateIndex()
{
QMutexLocker lock (&m_dateIndexMtx);
qDebug().noquote() << "["+m_network+"] ["+m_channel+"]" << "Indexing log dates in" << m_rootDir;
m_dateIndex.clear();
quint64 yearsCounter = 0;
quint64 monthCounter = 0;
quint64 daysCounter = 0;
QDirIterator yearIterator(m_rootDir);
while (yearIterator.hasNext())
{
auto year = QFileInfo(yearIterator.next());
if (year.fileName() == "." or year.fileName() == ".." or not year.isDir()) continue;
bool converted = false;
int16_t yearNumber = year.fileName().toShort(&converted);
if (not converted) continue;
m_dateIndex.push_front({yearNumber, {}});
yearsCounter++;
}
std::sort(m_dateIndex.begin(), m_dateIndex.end());
for (auto indexIterator = m_dateIndex.begin(); indexIterator != m_dateIndex.end(); indexIterator++)
{
QDirIterator monthIterator(m_rootDir + "/" + QString::number(indexIterator->first));
while (monthIterator.hasNext())
{
auto month = QFileInfo(monthIterator.next());
if (month.fileName() == "." or month.fileName() == ".." or not month.isDir()) continue;
bool converted = false;
int8_t monthNumber = month.fileName().toShort(&converted);
if (not converted) continue;
indexIterator->second.push_back({monthNumber, {}});
monthCounter++;
}
std::sort(indexIterator->second.begin(), indexIterator->second.end());
}
for (auto indexIterator = m_dateIndex.begin(); indexIterator != m_dateIndex.end(); indexIterator++)
{
for (auto monthIterator = indexIterator->second.begin(); monthIterator != indexIterator->second.end(); monthIterator++)
{
QString monthFolder = QString::number(monthIterator->first);
if (monthFolder.size() < 2) monthFolder.push_front('0');
QDirIterator dayIterator(m_rootDir + "/" + QString::number(indexIterator->first) + "/" + monthFolder);
while (dayIterator.hasNext())
{
auto day = QFileInfo(dayIterator.next());
if (not day.fileName().endsWith(".txt") or not day.isFile()) continue;
QString fileName = day.fileName();
static const QRegularExpression rgxOnlyNumbers("[^0-9]");
fileName.remove(rgxOnlyNumbers);
bool converted = false;
int8_t dayNumber = fileName.toShort(&converted);
if (not converted) continue;
monthIterator->second.push_back(dayNumber);
daysCounter++;
}
std::sort(monthIterator->second.begin(), monthIterator->second.end());
}
}
qInfo().noquote() << "["+m_network+"] ["+m_channel+"]" << "Log contains" << yearsCounter << "years," << monthCounter << "months and" << daysCounter << "days";
}
QString IRCLogger::dateDir(const QDateTime &date)
{
return m_rootDir + "/" + date.toString("yyyy/MM");

View File

@ -114,22 +114,32 @@ public:
};
struct DateIndex
{
};
using Month = QPair<int8_t, QList<int8_t>>; // Month number, days list
using Year = QPair<int16_t, QList<Month>>; // Year number, months list
IRCLogger(const QString& network, const QString& channel);
QString network() const { return m_network; }
QString channel() const { return m_channel; }
QList<Year> dateIndex() const;
void addMessage(const QString& sender, const QString& message);
QList<QSharedPointer<Message>> getMessages(const QDateTime& date, const quint64* beginId = nullptr, const quint64* endId = nullptr);
private:
void doDateIndex();
QString dateDir(const QDateTime& date);
QString datePath(const QDateTime& date);
mutable QMutex m_dateIndexMtx;
QList<Year> m_dateIndex;
Cache m_cache;
QMutex m_fileIOmtx;
const QString m_network;
const QString m_channel;
const QString m_rootDir;
};

View File

@ -34,6 +34,6 @@ QSharedPointer<IRCLogger> IRCLoggerList::get(const QString &network, const QStri
QSharedPointer<IRCLogger> newLogger (new IRCLogger(network, channel));
m_data.insert(ident, newLogger);
qDebug().noquote() << "["+network+"]" << "Logger for" << channel << "initialized. Global total loggers count:" << m_data.size();
qDebug().noquote() << "["+network+"] ["+channel+"] Logger initialized. Global loggers count:" << m_data.size();
return newLogger;
}