ukui-search/libsearch/index/inotify-index.cpp

403 lines
17 KiB
C++
Raw Normal View History

#include "inotify-index.h"
InotifyIndex::InotifyIndex(const QString& path) : Traverse_BFS(path)
{
/*-------------ukuisearchdbus Test start-----------------*/
qDebug() << "setInotifyMaxUserWatches start";
UkuiSearchQDBus usQDBus;
usQDBus.setInotifyMaxUserWatches();
qDebug() << "setInotifyMaxUserWatches end";
/*-------------ukuisearchdbus Test End-----------------*/
m_fd = inotify_init();
qDebug() << "m_fd----------->" <<m_fd;
this->AddWatch(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
this->setPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
this->Traverse();
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "0");
}
InotifyIndex::~InotifyIndex()
{
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "2");
IndexGenerator::getInstance()->~IndexGenerator();
}
void InotifyIndex::DoSomething(const QFileInfo& fileInfo){
if(fileInfo.isDir()){
this->AddWatch(fileInfo.absoluteFilePath());
}
}
bool InotifyIndex::AddWatch(const QString &path){
int ret = inotify_add_watch(m_fd, path.toStdString().c_str(), (IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE | IN_DELETE | IN_MODIFY));
if (ret == -1) {
qDebug() << "AddWatch error:" << path;
return false;
}
// Q_ASSERT(ret != -1);
assert(ret != -1);
currentPath[ret] = path;
//qDebug() << "Watch:" << path;
return true;
}
bool InotifyIndex::RemoveWatch(const QString &path){
int ret = inotify_rm_watch(m_fd, currentPath.key(path));
if (ret){
qDebug() << "remove path error";
return false;
}
// Q_ASSERT(ret == 0);
assert(ret == 0);
for (QMap<int, QString>::Iterator i = currentPath.begin(); i != currentPath.end();){
if (i.value().length() > path.length()){
if (i.value().mid(0, path.length()) == path){
qDebug() << "remove path: " << i.value();
ret = inotify_rm_watch(m_fd, currentPath.key(path));
if (ret){
qDebug() << "remove path error";
// return false;
}
// Q_ASSERT(ret == 0);
// assert(ret == 0);
/*--------------------------------*/
//在此调用删除索引
IndexGenerator::getInstance()->deleteAllIndex(new QStringList(i.value()));
/*--------------------------------*/
currentPath.erase(i++);
}
else{
i++;
}
}
else{
i++;
}
}
// qDebug() << path;
//这个貌似不用删先mark一下
//currentPath.remove(currentPath.key(path));
return true;
}
void InotifyIndex::eventProcess(const char* buf, ssize_t tmp){
// qDebug() << "Read " << numRead << " bytes from inotify fd";
/* Process all of the events in buffer returned by read() */
QQueue<QVector<QString>>* indexQueue = new QQueue<QVector<QString>>();
QQueue<QString>* contentIndexQueue = new QQueue<QString>();
ssize_t numRead = 0;
numRead = tmp;
char * p = const_cast<char*>(buf);
for (; p < buf + numRead;) {
struct inotify_event * event = reinterpret_cast<inotify_event *>(p);
// qDebug() << "Read Event: " << currentPath[event->wd] << QString(event->name) << event->cookie << event->wd << event->mask;
if(event->name[0] != '.'){
qDebug() << QString(currentPath[event->wd] + '/' + event->name);
// switch (event->mask) {
if (event->mask & IN_CREATE){
if (event->mask & IN_ISDIR){
AddWatch(currentPath[event->wd] + '/' + event->name);
setPath(currentPath[event->wd] + '/' + event->name);
Traverse();
}
/*--------------------------------*/
// IndexGenerator::getInstance()->creatAllIndex(QQueue<QVector<QString>>(QVector<QString>() << fileInfo.fileName() << fileInfo.absoluteFilePath() << QString(fileInfo.isDir() ? "1" : "0")));
indexQueue->enqueue(QVector<QString>() << QString(event->name) << QString(currentPath[event->wd] + '/' + event->name) << QString((event->mask & IN_ISDIR) ? "1" : "0"));
IndexGenerator::getInstance()->creatAllIndex(indexQueue);
indexQueue->clear();
for (auto i : this->targetFileTypeVec){
if (QString(currentPath[event->wd] + '/' + event->name).endsWith(i)){
contentIndexQueue->enqueue(QString(currentPath[event->wd] + '/' + event->name));
IndexGenerator::getInstance()->creatAllIndex(contentIndexQueue);
contentIndexQueue->clear();
break;
}
}
goto next;
}
if ((event->mask & IN_DELETE) | (event->mask & IN_MOVED_FROM)){
if (event->mask & IN_ISDIR){
RemoveWatch(currentPath[event->wd] + '/' + event->name);
}
//delete once more
IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
goto next;
}
if (event->mask & IN_MODIFY){
if (!(event->mask & IN_ISDIR)){
IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
indexQueue->enqueue(QVector<QString>() << QString(event->name) << QString(currentPath[event->wd] + '/' + event->name) << QString((event->mask & IN_ISDIR) ? "1" : "0"));
IndexGenerator::getInstance()->creatAllIndex(indexQueue);
indexQueue->clear();
for (auto i : this->targetFileTypeVec){
if (QString(currentPath[event->wd] + '/' + event->name).endsWith(i)){
contentIndexQueue->enqueue(QString(currentPath[event->wd] + '/' + event->name));
IndexGenerator::getInstance()->creatAllIndex(contentIndexQueue);
contentIndexQueue->clear();
break;
}
}
}
goto next;
}
if (event->mask & IN_MOVED_TO){
if (event->mask & IN_ISDIR){
RemoveWatch(currentPath[event->wd] + '/' + event->name);
IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
AddWatch(currentPath[event->wd] + '/' + event->name);
setPath(currentPath[event->wd] + '/' + event->name);
Traverse();
indexQueue->enqueue(QVector<QString>() << QString(event->name) << QString(currentPath[event->wd] + '/' + event->name) << QString((event->mask & IN_ISDIR) ? "1" : "0"));
IndexGenerator::getInstance()->creatAllIndex(indexQueue);
indexQueue->clear();
for (auto i : this->targetFileTypeVec){
if (QString(currentPath[event->wd] + '/' + event->name).endsWith(i)){
contentIndexQueue->enqueue(QString(currentPath[event->wd] + '/' + event->name));
IndexGenerator::getInstance()->creatAllIndex(contentIndexQueue);
contentIndexQueue->clear();
break;
}
}
}
else {
IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
indexQueue->enqueue(QVector<QString>() << QString(event->name) << QString(currentPath[event->wd] + '/' + event->name) << QString((event->mask & IN_ISDIR) ? "1" : "0"));
IndexGenerator::getInstance()->creatAllIndex(indexQueue);
indexQueue->clear();
for (auto i : this->targetFileTypeVec){
if (QString(currentPath[event->wd] + '/' + event->name).endsWith(i)){
contentIndexQueue->enqueue(QString(currentPath[event->wd] + '/' + event->name));
IndexGenerator::getInstance()->creatAllIndex(contentIndexQueue);
contentIndexQueue->clear();
break;
}
}
}
goto next;
}
// }
// //传创建或移动过来的文件路径
// if((event->mask & IN_CREATE)){
// //添加监视要先序遍历先添加top节点
// if (event->mask & IN_ISDIR){
// AddWatch(currentPath[event->wd] + '/' + event->name);
// this->setPath(currentPath[event->wd] + '/' + event->name);
// Traverse();
// }
// /*--------------------------------*/
//// IndexGenerator::getInstance()->creatAllIndex(QQueue<QVector<QString>>(QVector<QString>() << fileInfo.fileName() << fileInfo.absoluteFilePath() << QString(fileInfo.isDir() ? "1" : "0")));
// indexQueue->enqueue(QVector<QString>() << QString(event->name) << QString(currentPath[event->wd] + '/' + event->name) << QString((event->mask & IN_ISDIR) ? "1" : "0"));
// IndexGenerator::getInstance()->creatAllIndex(indexQueue);
// indexQueue->clear();
// for (auto i : this->targetFileTypeVec){
// if (QString(currentPath[event->wd] + '/' + event->name).endsWith(i)){
// contentIndexQueue->enqueue(QString(currentPath[event->wd] + '/' + event->name));
// IndexGenerator::getInstance()->creatAllIndex(contentIndexQueue);
// contentIndexQueue->clear();
// break;
// }
// }
// /*--------------------------------*/
// }
// else if((event->mask & IN_DELETE) | (event->mask & IN_MOVED_FROM)){
// if (event->mask & IN_ISDIR){
// RemoveWatch(currentPath[event->wd] + '/' + event->name);
// }
// IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
// }
// else if((event->mask & IN_MODIFY) | (event->mask & IN_MOVED_TO)){
// if (!(event->mask & IN_ISDIR)){
// IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
// indexQueue->enqueue(QVector<QString>() << QString(event->name) << QString(currentPath[event->wd] + '/' + event->name) << QString((event->mask & IN_ISDIR) ? "1" : "0"));
// IndexGenerator::getInstance()->creatAllIndex(indexQueue);
// indexQueue->clear();
// for (auto i : this->targetFileTypeVec){
// if (QString(currentPath[event->wd] + '/' + event->name).endsWith(i)){
// contentIndexQueue->enqueue(QString(currentPath[event->wd] + '/' + event->name));
// IndexGenerator::getInstance()->creatAllIndex(contentIndexQueue);
// contentIndexQueue->clear();
// break;
// }
// }
// }
// }
/*--------------------------------*/
}
next:
p += sizeof(struct inotify_event) + event->len;
}
delete indexQueue;
indexQueue = nullptr;
delete contentIndexQueue;
contentIndexQueue = nullptr;
}
/*
* Symbolic Link!!!!!!!!!!!!!!!!!!
* Sysmbolic link to database dir will make a Infinite loop !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* MouseZhangZh
*/
void InotifyIndex::run(){
int fifo_fd;
char buffer[2];
memset(buffer, 0, sizeof(buffer));
fifo_fd = open(UKUI_SEARCH_PIPE_PATH, O_RDWR);
if(fifo_fd == -1)
{
perror("open fifo error\n");
assert(false);
}
int retval = read(fifo_fd, buffer, sizeof(buffer));
if(retval == -1)
{
perror("read error\n");
assert(false);
}
printf("read fifo=[%s]\n", buffer);
printf("read data ok\n");
close(fifo_fd);
if (buffer[0] & 0x1){
printf("data confirmed\n");
}
unlink(UKUI_SEARCH_PIPE_PATH);
char buf[BUF_LEN] __attribute__((aligned(8)));
ssize_t numRead;
for (;;) { /* Read events forever */
read:
numRead = read(m_fd, buf, BUF_LEN);
if (numRead == -1){
printf("\033[1;31;40mread event error\033[0m\n");
fflush(stdout);
assert(false);
}
char * tmp = const_cast<char*>(buf);
for (; tmp < buf + numRead;) {
struct inotify_event * event = reinterpret_cast<inotify_event *>(tmp);
// qDebug() << "Read Event: " << currentPath[event->wd] << QString(event->name) << event->cookie << event->wd << event->mask;
if(event->name[0] != '.'){
goto fork;
}
tmp += sizeof(struct inotify_event) + event->len;
}
goto read;
fork:
++FileUtils::_index_status;
pid_t pid;
pid = fork();
if(pid == 0)
{
prctl(PR_SET_PDEATHSIG, SIGTERM);
prctl(PR_SET_NAME,"inotify-index");
if (numRead == 0) {
qDebug() << "read() from inotify fd returned 0!";
}
if (numRead == -1) {
qDebug() << "read";
}
eventProcess(buf, numRead);
fd_set read_fds;
int rc;
timeval* read_timeout = (timeval*)malloc(sizeof(timeval));
read_timeout->tv_sec = 60;
read_timeout->tv_usec = 0;
for(;;)
{
FD_ZERO(&read_fds);
FD_SET(m_fd, &read_fds);
qDebug() << read_timeout->tv_sec;
rc = select(m_fd + 1, &read_fds, NULL, NULL, read_timeout);
if ( rc < 0 ) {
// error
qWarning() << "select result < 0, error!";
assert(false);
}
else if ( rc == 0 ) {
qDebug() << "select timeout!";
2021-01-23 11:32:18 +08:00
::exit(0);
}else{
numRead = read(m_fd, buf, BUF_LEN);
if (numRead == -1){
printf("\033[1;31;40mread event error\033[0m\n");
fflush(stdout);
assert(false);
}
this->eventProcess(buf, numRead);
}
}
// QTimer* liveTime = new QTimer();
// //restart inotify-index proccess per minute
// liveTime->setInterval(60000);
// liveTime->start();
//I don't know how to use QTimer, wish someone can fix it!
//MouseZhangZh
// connect(liveTime, &QTimer::timeout, [ = ](){
2021-01-23 11:32:18 +08:00
//// ::exit(0);
// *b_timeout = 1;
// });
// for (;;){
// qDebug() << "liveTime->remainingTime():" << liveTime->remainingTime();
// numRead = read(m_fd, buf, BUF_LEN);
// this->eventProcess(buf, numRead);
// if (liveTime->remainingTime() < 1){
// qDebug() << "liveTime->remainingTime():" << liveTime->remainingTime();
2021-01-23 11:32:18 +08:00
// ::exit(0);
// }
// }
}
else if (pid > 0){
memset(buf, 0x00, BUF_LEN);
waitpid(pid, NULL, 0);
--FileUtils::_index_status;
}
else{
assert(false);
}
}
}