diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/bufferfragment_p.h | 22 | ||||
| -rw-r--r-- | src/core/kconfigini.cpp | 21 | ||||
| -rw-r--r-- | src/core/kconfigini_p.h | 4 | 
3 files changed, 43 insertions, 4 deletions
| diff --git a/src/core/bufferfragment_p.h b/src/core/bufferfragment_p.h index e2154a59..a86e2922 100644 --- a/src/core/bufferfragment_p.h +++ b/src/core/bufferfragment_p.h @@ -150,6 +150,11 @@ public:          return (other.size() != (int)len || memcmp(d, other.constData(), len) != 0);      } +    bool operator==(const BufferFragment &other) const +    { +        return other.len == len && !memcmp(d, other.d, len); +    } +      int indexOf(char c, unsigned int from = 0) const      {          const char *cursor = d + from - 1; @@ -190,4 +195,21 @@ private:      unsigned int len;  }; +uint qHash(const KConfigIniBackend::BufferFragment &fragment) +{ +    const uchar *p = reinterpret_cast<const uchar*>(fragment.constData()); +    const int len = fragment.length(); + +    // This algorithm is copied from qhash.cpp (Qt5 version). +    // Sadly this code is not accessible from the outside without going through abstraction +    // layers. Even QByteArray::fromRawData would do an allocation internally... +    uint h = 0; + +    for (int i = 0; i < len; ++i) { +        h = 31 * h + p[i]; +    } + +    return h; +} +  #endif diff --git a/src/core/kconfigini.cpp b/src/core/kconfigini.cpp index a882ee31..f4ce9410 100644 --- a/src/core/kconfigini.cpp +++ b/src/core/kconfigini.cpp @@ -44,6 +44,15 @@  KCONFIGCORE_EXPORT bool kde_kiosk_exception = false; // flag to disable kiosk restrictions +static QByteArray lookup(const KConfigIniBackend::BufferFragment &fragment, QHash<KConfigIniBackend::BufferFragment, QByteArray> *cache) +{ +    QHash<KConfigIniBackend::BufferFragment, QByteArray>::iterator it = cache->find(fragment); +    if (it == cache->end()) { +        it = cache->insert(fragment, fragment.toByteArray()); +    } +    return it.value(); +} +  QString KConfigIniBackend::warningProlog(const QFile &file, int line)  {      return QString::fromLatin1("KConfigIni: In file %2, line %1: ") @@ -100,6 +109,14 @@ KConfigIniBackend::parseConfig(const QByteArray ¤tLocale, KEntryMap &entry      unsigned int len = contents.length();      unsigned int startOfLine = 0; +    // Reduce memory overhead by making use of implicit sharing +    // This assumes that config files contain only a small amount of +    // different fragments which are repeated often. +    // This is often the case, especially sub groups will all have +    // the same list of keys and similar values as well. +    QHash<BufferFragment, QByteArray> cache; +    cache.reserve(4096); +      while (startOfLine < len) {          BufferFragment line = contents.split('\n', &startOfLine);          line.trim(); @@ -265,9 +282,9 @@ KConfigIniBackend::parseConfig(const QByteArray ¤tLocale, KEntryMap &entry                  rawKey.reserve(aKey.length() + locale.length() + 2);                  rawKey.append(aKey.toVolatileByteArray());                  rawKey.append('[').append(locale.toVolatileByteArray()).append(']'); -                entryMap.setEntry(currentGroup, rawKey, line.toByteArray(), entryOptions); +                entryMap.setEntry(currentGroup, rawKey, lookup(line, &cache), entryOptions);              } else { -                entryMap.setEntry(currentGroup, aKey.toByteArray(), line.toByteArray(), entryOptions); +                entryMap.setEntry(currentGroup, lookup(aKey, &cache), lookup(line, &cache), entryOptions);              }          }      next_line: diff --git a/src/core/kconfigini_p.h b/src/core/kconfigini_p.h index 492e1956..29f61090 100644 --- a/src/core/kconfigini_p.h +++ b/src/core/kconfigini_p.h @@ -33,10 +33,10 @@ class KConfigIniBackend : public KConfigBackend  {  Q_OBJECT  private: -    class BufferFragment; -      QLockFile *lockFile; +  public: +    class BufferFragment;      KConfigIniBackend();      ~KConfigIniBackend(); | 
