1 /*
2     This file is part of the KDE libraries
3     SPDX-FileCopyrightText: 1999 Waldo Bastian <bastian@kde.org>
4 
5     SPDX-License-Identifier: LGPL-2.0-only
6 */
7 
8 #ifndef KSYCOCADICT_H
9 #define KSYCOCADICT_H
10 
11 #include "ksycocaentry.h"
12 #include <kservice_export.h>
13 
14 #include <QList>
15 
16 #include <memory>
17 
18 class KSycocaDictPrivate;
19 
20 class QString;
21 class QDataStream;
22 
23 /**
24  * @internal
25  * Hash table implementation for the sycoca database file
26  *
27  * Only exported for the unit test
28  */
29 class KSERVICE_EXPORT KSycocaDict // krazy:exclude=dpointer (not const because it gets deleted by clear())
30 {
31 public:
32     /**
33      * Create an empty dict, for building the database
34      */
35     KSycocaDict();
36     /**
37      * Create a dict from an existing database
38      */
39     KSycocaDict(QDataStream *str, int offset);
40 
41     ~KSycocaDict();
42 
43     /**
44      * Adds a 'payload' to the dictionary with key 'key'.
45      *
46      * 'payload' should have a valid offset by the time
47      * the dictionary gets saved.
48      **/
49     void add(const QString &key, const KSycocaEntry::Ptr &payload);
50 
51     /**
52      * Removes the 'payload' from the dictionary with key 'key'.
53      *
54      * Not very fast, use with care O(N)
55      **/
56     void remove(const QString &key);
57 
58     /**
59      * Looks up an entry identified by 'key'.
60      *
61      * If 0 is returned, no matching entry exists.
62      * Otherwise, the offset of the entry is returned.
63      *
64      * NOTE: It is not guaranteed that this entry is
65      * indeed the one you were looking for.
66      * After loading the entry you should check that it
67      * indeed matches the search key. If it doesn't
68      * then no matching entry exists.
69      */
70     int find_string(const QString &key) const;
71 
72     /**
73      * Looks up all entries identified by 'key'.
74      * This is useful when the dict is used as a multi-hash.
75      *
76      * If an empty list is returned, no matching entry exists.
77      * Otherwise, the offset of the matching entries are returned.
78      *
79      * NOTE: It is not guaranteed that each entry is
80      * indeed among the ones you were looking for.
81      * After loading each entry you should check that it
82      * indeed matches the search key.
83      */
84     QList<int> findMultiString(const QString &key) const;
85 
86     /**
87      * The number of entries in the dictionary.
88      *
89      * Only valid when building the database.
90      */
91     uint count() const;
92 
93     /**
94      * Reset the dictionary.
95      *
96      * Only valid when building the database.
97      */
98     void clear();
99 
100     /**
101      * Save the dictionary to the stream
102      * A reasonable fast hash algorithm will be created.
103      *
104      * Typically this will find 90% of the entries directly.
105      * Average hash table size: nrOfItems * 20 bytes.
106      * Average duplicate list size: nrOfItms * avgKeyLength / 5.
107      *
108      * Unknown keys have an average 20% chance to give a false hit.
109      * (That's why your program should check the result)
110      *
111      * Example:
112      *   Assume 1000 items with an average key length of 60 bytes.
113      *
114      *   Approx. 900 items will hash directly to the right entry.
115      *   Approx. 100 items require a lookup in the duplicate list.
116      *
117      *   The hash table size will be approx. 20Kb.
118      *   The duplicate list size will be approx. 12Kb.
119      **/
120     void save(QDataStream &str);
121 
122 private:
123     Q_DISABLE_COPY(KSycocaDict)
124     std::unique_ptr<KSycocaDictPrivate> d;
125 };
126 
127 #endif
128