File indexing completed on 2024-12-22 05:06:07

0001 /*
0002  * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org>
0003  *
0004  *   This program is free software; you can redistribute it and/or modify
0005  *   it under the terms of the GNU General Public License as published by
0006  *   the Free Software Foundation; either version 2 of the License, or
0007  *   (at your option) any later version.
0008  *
0009  *   This program is distributed in the hope that it will be useful,
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *   GNU General Public License for more details.
0013  *
0014  *   You should have received a copy of the GNU General Public License
0015  *   along with this program; if not, write to the
0016  *   Free Software Foundation, Inc.,
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
0018  */
0019 
0020 #include <QDebug>
0021 #include <QObject> // tr()
0022 #include <QTimer>
0023 #include <QDir>
0024 
0025 #include "common/resource.h"
0026 #include "common/storage.h"
0027 #include "common/resourceconfig.h"
0028 #include "common/log.h"
0029 #include "common/storage.h"
0030 #include "common/definitions.h"
0031 
0032 #include "sinksh_utils.h"
0033 #include "state.h"
0034 #include "syntaxtree.h"
0035 
0036 namespace SinkStat
0037 {
0038 
0039 void statResource(const QString &resource, const State &state)
0040 {
0041     state.printLine("Resource " + resource + ":");
0042     qint64 total = 0;
0043     Sink::Storage::DataStore storage(Sink::storageLocation(), resource, Sink::Storage::DataStore::ReadOnly);
0044     auto transaction = storage.createTransaction(Sink::Storage::DataStore::ReadOnly);
0045 
0046     QList<QByteArray> databases = transaction.getDatabaseNames();
0047     for (const auto &databaseName : databases) {
0048         auto db = transaction.openDatabase(databaseName);
0049         qint64 size = db.getSize() / 1024;
0050         state.printLine(QObject::tr("%1:\t%2 [kb]").arg(QString(databaseName)).arg(size), 1);
0051         total += size;
0052     }
0053     state.printLine();
0054     state.printLine(QObject::tr("Calculated named database sizes total of main database: %1 [kb]").arg(total), 1);
0055 
0056     auto stat = transaction.stat(false);
0057     state.printLine(QObject::tr("Total calculated free size [kb]: %1 from %2 pages").arg(stat.freePages * stat.pageSize / 1024).arg(stat.freePages), 1);
0058     state.printLine(QObject::tr("Write amplification of main database: %1").arg(double(storage.diskUsage() / 1024)/double(total)), 1);
0059     state.printLine();
0060 
0061     QDir dir(Sink::storageLocation());
0062     long long int diskUsage = 0;
0063     for (const auto &folder : dir.entryList(QStringList() << resource + "*")) {
0064         auto size = Sink::Storage::DataStore(Sink::storageLocation(), folder, Sink::Storage::DataStore::ReadOnly).diskUsage();
0065         diskUsage += size;
0066         state.printLine(QObject::tr("... accumulating %1: %2 [kb]").arg(folder).arg(size / 1024), 1);
0067     }
0068     auto size = diskUsage / 1024;
0069     state.printLine(QObject::tr("Actual database file sizes total: %1 [kb]").arg(size), 1);
0070 
0071     QDir dataDir{Sink::resourceStorageLocation(resource.toLatin1()) + "/fulltext/"};
0072     qint64 dataSize = 0;
0073     for (const auto &e : dataDir.entryInfoList(QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot)) {
0074         dataSize += e.size();
0075     }
0076     state.printLine(QObject::tr("Fulltext index size [kb]: %1").arg(dataSize / 1024), 1);
0077 
0078     state.printLine();
0079 }
0080 
0081 bool statAllResources(State &state)
0082 {
0083     Sink::Query query;
0084     for (const auto &r : SinkshUtils::getStore("resource").read(query)) {
0085         statResource(SinkshUtils::parseUid(r.identifier()), state);
0086     }
0087     return false;
0088 }
0089 
0090 bool stat(const QStringList &args, State &state)
0091 {
0092     if (args.isEmpty()) {
0093         return statAllResources(state);
0094     }
0095 
0096     for (const auto &r : args) {
0097         statResource(SinkshUtils::parseUid(r.toUtf8()), state);
0098     }
0099     return false;
0100 }
0101 
0102 Syntax::List syntax()
0103 {
0104     Syntax state("stat", QObject::tr("Shows database usage for the resources requested"), &SinkStat::stat, Syntax::NotInteractive);
0105     state.addPositionalArgument({"resourceId", "Show statistics of the given resource(s). If no resource is provided, show statistics of all resources", false, true});
0106     state.completer = &SinkshUtils::resourceCompleter;
0107     return Syntax::List() << state;
0108 }
0109 
0110 REGISTER_SYNTAX(SinkStat)
0111 
0112 }