• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.14
  • kdeedu
  • marble
  • src
  • lib
  • marble
DiscCache.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2007 Tobias Koenig <tokoe@kde.org>
9 //
10 
11 
12 // Own
13 #include "DiscCache.h"
14 
15 // Qt
16 #include <QtGlobal>
17 #include <QFile>
18 #include <QDirIterator>
19 
20 using namespace Marble;
21 
22 static QString indexFileName( const QString &cacheDirectory )
23 {
24  return cacheDirectory + "/cache_index.idx";
25 }
26 
27 DiscCache::DiscCache( const QString &cacheDirectory )
28  : m_CacheDirectory( cacheDirectory ),
29  m_CacheLimit( 300 * 1024 * 1024 ),
30  m_CurrentCacheSize( 0 )
31 {
32  Q_ASSERT( !m_CacheDirectory.isEmpty() && "Passed empty cache directory!" );
33 
34  QFile file( indexFileName( m_CacheDirectory ) );
35 
36  if ( file.exists() ) {
37  if ( file.open( QIODevice::ReadOnly ) ) {
38  QDataStream s( &file );
39  s.setVersion( 8 );
40 
41  s >> m_CacheLimit;
42  s >> m_CurrentCacheSize;
43  s >> m_Entries;
44 
45  } else {
46  qWarning( "Unable to open cache directory %s", qPrintable( m_CacheDirectory ) );
47  }
48  }
49 }
50 
51 DiscCache::~DiscCache()
52 {
53  QFile file( indexFileName( m_CacheDirectory ) );
54 
55  if ( file.open( QIODevice::WriteOnly ) ) {
56  QDataStream s( &file );
57  s.setVersion( 8 );
58 
59  s << m_CacheLimit;
60  s << m_CurrentCacheSize;
61  s << m_Entries;
62  }
63 
64  file.close();
65 }
66 
67 quint64 DiscCache::cacheLimit() const
68 {
69  return m_CacheLimit;
70 }
71 
72 void DiscCache::clear()
73 {
74  QDirIterator it( m_CacheDirectory );
75 
76  // Remove all files from cache directory
77  while ( it.hasNext() ) {
78  it.next();
79 
80  if ( it.fileName() == indexFileName( m_CacheDirectory ) ) // skip index file
81  continue;
82 
83  QFile::remove( it.fileName() );
84  }
85 
86  // Delete entries
87  m_Entries.clear();
88 
89  // Reset current cache size
90  m_CurrentCacheSize = 0;
91 }
92 
93 bool DiscCache::exists( const QString &key ) const
94 {
95  return m_Entries.contains( key );
96 }
97 
98 bool DiscCache::find( const QString &key, QByteArray &data )
99 {
100  // Return error if we don't know this key
101  if ( !m_Entries.contains( key ) )
102  return false;
103 
104  // If we can open the file, load all data and update access timestamp
105  QFile file( keyToFileName( key ) );
106  if ( file.open( QIODevice::ReadOnly ) ) {
107  data = file.readAll();
108 
109  m_Entries[ key ].first = QDateTime::currentDateTime();
110  return true;
111  }
112 
113  return false;
114 }
115 
116 bool DiscCache::insert( const QString &key, const QByteArray &data )
117 {
118  // If we can't open/create a file for this entry signal an error
119  QFile file( keyToFileName( key ) );
120  if ( !file.open( QIODevice::WriteOnly ) )
121  return false;
122 
123  // If we overwrite an existing entry, subtract the size first
124  if ( m_Entries.contains( key ) )
125  m_CurrentCacheSize -= m_Entries.value( key ).second;
126 
127  // Store the data on disc
128  file.write( data );
129 
130  // Create/Overwrite with a new entry
131  m_Entries.insert( key, QPair<QDateTime, quint64>(QDateTime::currentDateTime(), data.length()) );
132 
133  // Add the size of the new entry
134  m_CurrentCacheSize += data.length();
135 
136  cleanup();
137 
138  return true;
139 }
140 
141 void DiscCache::remove( const QString &key )
142 {
143  // Do nothing if we don't know the key
144  if ( !m_Entries.contains( key ) )
145  return;
146 
147  // If we can't remove the file we don't remove
148  // the entry to prevent inconsistency
149  if ( !QFile::remove( keyToFileName( key ) ) )
150  return;
151 
152  // Subtract from current size
153  m_CurrentCacheSize -= m_Entries.value( key ).second;
154 
155  // Finally remove entry
156  m_Entries.remove( key );
157 }
158 
159 void DiscCache::setCacheLimit( quint64 n )
160 {
161  m_CacheLimit = n;
162 
163  cleanup();
164 }
165 
166 QString DiscCache::keyToFileName( const QString &key ) const
167 {
168  QString fileName( key );
169  fileName.replace( '/', '_' );
170 
171  return m_CacheDirectory + '/' + fileName;
172 }
173 
174 void DiscCache::cleanup()
175 {
176  // Calculate 5% of our current cache limit
177  quint64 fivePercent = quint64( m_CacheLimit * 0.05 );
178 
179  while ( m_CurrentCacheSize > (m_CacheLimit - fivePercent) ) {
180  QDateTime oldestDate( QDateTime::currentDateTime() );
181  QString oldestKey;
182 
183  QMapIterator<QString, QPair<QDateTime, quint64> > it( m_Entries );
184  while ( it.hasNext() ) {
185  it.next();
186 
187  if ( it.value().first < oldestDate ) {
188  oldestDate = it.value().first;
189  oldestKey = it.key();
190  }
191  }
192 
193  if ( !oldestKey.isEmpty() ) {
194  // We found the oldest key, so using remove() to
195  // remove it from cache
196  remove( oldestKey );
197  }
198  }
199 }
QDirIterator::next
QString next()
QByteArray
QFile::remove
bool remove()
QDataStream
Marble::DiscCache::cacheLimit
quint64 cacheLimit() const
Definition: DiscCache.cpp:67
QDirIterator::fileName
QString fileName() const
DiscCache.h
QByteArray::length
int length() const
QFile
QMapIterator
Marble::DiscCache::DiscCache
DiscCache(const QString &cacheDirectory)
Definition: DiscCache.cpp:27
Marble::DiscCache::remove
void remove(const QString &key)
Definition: DiscCache.cpp:141
QString::isEmpty
bool isEmpty() const
QIODevice::readAll
QByteArray readAll()
QString
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QPair
QDataStream::setVersion
void setVersion(int v)
QDirIterator
indexFileName
static QString indexFileName(const QString &cacheDirectory)
Definition: DiscCache.cpp:22
QFile::close
virtual void close()
Marble::DiscCache::setCacheLimit
void setCacheLimit(quint64 n)
Definition: DiscCache.cpp:159
Marble::DiscCache::find
bool find(const QString &key, QByteArray &data)
Definition: DiscCache.cpp:98
Marble::DiscCache::clear
void clear()
Definition: DiscCache.cpp:72
QDateTime::currentDateTime
QDateTime currentDateTime()
Marble::DiscCache::exists
bool exists(const QString &key) const
Definition: DiscCache.cpp:93
Marble::DiscCache::insert
bool insert(const QString &key, const QByteArray &data)
Definition: DiscCache.cpp:116
QIODevice::write
qint64 write(const char *data, qint64 maxSize)
Marble::DiscCache::~DiscCache
~DiscCache()
Definition: DiscCache.cpp:51
QDirIterator::hasNext
bool hasNext() const
QDateTime
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:38 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal