~ubuntu-branches/ubuntu/quantal/kde-runtime/quantal

« back to all changes in this revision

Viewing changes to nepomuk/services/backupsync/service/logstorage.cpp

  • Committer: Package Import Robot
  • Author(s): Philip Muškovac
  • Date: 2012-06-03 21:50:00 UTC
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: package-import@ubuntu.com-20120603215000-vn7oarsq0ynrydj5
Tags: upstream-4.8.80
Import upstream version 4.8.80

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
    This file is part of the Nepomuk KDE project.
3
 
    Copyright (C) 2010  Vishesh Handa <handa.vish@gmail.com>
4
 
 
5
 
   This library is free software; you can redistribute it and/or
6
 
   modify it under the terms of the GNU Lesser General Public
7
 
   License as published by the Free Software Foundation; either
8
 
   version 2.1 of the License, or (at your option) version 3, or any
9
 
   later version accepted by the membership of KDE e.V. (or its
10
 
   successor approved by the membership of KDE e.V.), which shall
11
 
   act as a proxy defined in Section 6 of version 3 of the license.
12
 
 
13
 
   This library is distributed in the hope that it will be useful,
14
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 
   Lesser General Public License for more details.
17
 
 
18
 
   You should have received a copy of the GNU Lesser General Public
19
 
   License along with this library.  If not, see <http://www.gnu.org/licenses/>.
20
 
*/
21
 
 
22
 
 
23
 
#include "logstorage.h"
24
 
 
25
 
#include <QtCore/QDir>
26
 
 
27
 
#include "changelog.h"
28
 
#include "changelogrecord.h"
29
 
 
30
 
#include <KStandardDirs>
31
 
#include <KDebug>
32
 
 
33
 
Nepomuk::LogStorage::LogStorage()
34
 
{
35
 
    m_dirUrl = KStandardDirs::locateLocal( "data", "nepomuk/backupsync/log/" );
36
 
    m_locked = false;
37
 
}
38
 
 
39
 
 
40
 
Nepomuk::LogStorage::~LogStorage()
41
 
{
42
 
    // Always save all the records on exit
43
 
    saveRecords();
44
 
}
45
 
 
46
 
 
47
 
class Nepomuk::LogStorageHelper
48
 
{
49
 
public:
50
 
    Nepomuk::LogStorage q;
51
 
};
52
 
K_GLOBAL_STATIC(Nepomuk::LogStorageHelper, instanceHelper)
53
 
 
54
 
// static
55
 
Nepomuk::LogStorage* Nepomuk::LogStorage::instance()
56
 
{
57
 
    return &(instanceHelper->q);
58
 
}
59
 
 
60
 
 
61
 
Nepomuk::ChangeLog Nepomuk::LogStorage::getChangeLog(const QString& minDate)
62
 
{
63
 
    return getChangeLog( QDateTime::fromString( minDate, ChangeLog::dateTimeFormat() ) );
64
 
}
65
 
 
66
 
Nepomuk::ChangeLog Nepomuk::LogStorage::getChangeLog(const QDateTime& min)
67
 
{
68
 
    // Always save all the existing records before accessing them. It's like flushing the cache
69
 
    saveRecords();
70
 
 
71
 
    ChangeLog log;
72
 
 
73
 
    QDir dir( m_dirUrl );
74
 
    const QStringList& entries = dir.entryList( QDir::Files, QDir::Name );
75
 
    if( entries.empty() ) {
76
 
        kDebug() << "No enteries to generate a ChangeLog from";
77
 
        return ChangeLog();
78
 
    }
79
 
 
80
 
    foreach( const QString & fileName, entries ) {
81
 
        QDateTime dt = QDateTime::fromString( fileName, ChangeLog::dateTimeFormat() );
82
 
        if( dt < min )
83
 
            continue;
84
 
 
85
 
        //TODO: Optimize : Every record shouldn't be checked. Be smart!
86
 
        log += ChangeLog::fromUrl( QString( m_dirUrl + fileName ), min );
87
 
    }
88
 
 
89
 
    //TODO: Optimize this!
90
 
    if( m_locked )
91
 
        log.removeRecordsAfter( m_lockTime );
92
 
 
93
 
    return log;
94
 
}
95
 
 
96
 
 
97
 
void Nepomuk::LogStorage::addRecord(const Nepomuk::ChangeLogRecord& record)
98
 
{
99
 
    //kDebug() << record.st();
100
 
    m_records.append( record );
101
 
 
102
 
    if( m_records.size() >= m_maxFileRecords ) {
103
 
        kDebug() << "Saving Records .. " << m_records.size();
104
 
        saveRecords();
105
 
        m_records.clear();
106
 
    }
107
 
}
108
 
 
109
 
 
110
 
//IMPORTANT: This function doesn't actually remove ALL the records less than min
111
 
// This has been done purposely, as otherwise one would need to read the entire contents
112
 
// of at least one LogFile.
113
 
void Nepomuk::LogStorage::removeRecords(const QDateTime& min)
114
 
{
115
 
    QDir dir( m_dirUrl );
116
 
    const QStringList& entries = dir.entryList( QDir::Files, QDir::Name );
117
 
 
118
 
    foreach( const QString fileName, entries ) {
119
 
        QDateTime dt = QDateTime::fromString(fileName, ChangeLog::dateTimeFormat());
120
 
        if( dt < min ) {
121
 
            QFile file( m_dirUrl + fileName );
122
 
            file.remove();
123
 
        }
124
 
    }
125
 
}
126
 
 
127
 
 
128
 
namespace {
129
 
 
130
 
    //TODO: Optimize : Currently O(n)
131
 
    int countRecords( const QString & url ) {
132
 
        int count = 0;
133
 
 
134
 
        QFile file( url );
135
 
        file.open( QIODevice::ReadOnly | QIODevice::Text );
136
 
 
137
 
        QTextStream in( &file );
138
 
 
139
 
        while( !in.atEnd() )
140
 
        {
141
 
            QString line = in.readLine();
142
 
            count++;
143
 
        }
144
 
        return count;
145
 
    }
146
 
}
147
 
 
148
 
 
149
 
//FIXME: The code is too complicated and POSSIBLY buggy. It's buggy in the way that it makes
150
 
// the service usage skyrocket to 50%+ for large amounts of time.
151
 
bool Nepomuk::LogStorage::saveRecords()
152
 
{
153
 
    if( m_records.empty() )
154
 
        return false;
155
 
 
156
 
    kDebug();
157
 
 
158
 
    // Always sort them not mattter what. I don't know why I get weird results otherwise.
159
 
    qSort( m_records );
160
 
 
161
 
    QDir dir( m_dirUrl );
162
 
    const QStringList& entries = dir.entryList( QDir::Files, QDir::Reversed );
163
 
 
164
 
    QDateTime max = m_records.last().dateTime();
165
 
 
166
 
    // First time
167
 
    if( entries.empty() ) {
168
 
        QString path = m_dirUrl + max.toString( ChangeLog::dateTimeFormat() );
169
 
        ChangeLogRecord::saveRecords( m_records, path );;
170
 
        return true;
171
 
    }
172
 
 
173
 
    QString fileName = entries.first();
174
 
 
175
 
    int begin = 0;
176
 
    const int end = m_records.size() - 1;
177
 
 
178
 
    while( 1 ) {
179
 
        QString filePath = m_dirUrl + fileName;
180
 
 
181
 
        int alreadyPresent = countRecords( filePath );
182
 
        int numRecords = end - begin + 1;
183
 
        int availSize = m_maxFileRecords - alreadyPresent;
184
 
 
185
 
        int numToSave = availSize > numRecords ? numRecords : availSize;
186
 
 
187
 
        if( numToSave > 0 ) {
188
 
            ChangeLogRecord::saveRecords( m_records.mid( begin, numToSave ), filePath );
189
 
            QString newName = m_records[ begin + numToSave -1 ].dateTime().toString( ChangeLog::dateTimeFormat() );
190
 
            QFile file( filePath );
191
 
            file.rename( m_dirUrl + newName );
192
 
 
193
 
            begin += numToSave;
194
 
 
195
 
            if( begin > end )
196
 
                break;
197
 
        }
198
 
 
199
 
        fileName = m_records.last().dateTime().toString( ChangeLog::dateTimeFormat() );
200
 
    }
201
 
 
202
 
    kDebug() << "Saved!";
203
 
    return true;
204
 
}
205
 
 
206
 
 
207
 
void Nepomuk::LogStorage::lock()
208
 
{
209
 
    m_locked = true;
210
 
    m_lockTime = QDateTime::currentDateTime();
211
 
}
212
 
 
213
 
void Nepomuk::LogStorage::unlock()
214
 
{
215
 
    m_locked = false;
216
 
}
217