1 | /* |
2 | * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team |
3 | * |
4 | * Distributable under the terms of either the Apache License (Version 2.0) or |
5 | * the GNU Lesser General Public License, as specified in the COPYING file. |
6 | * |
7 | * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
8 | */ |
9 | #ifndef _lucene_store_FSDirectory_ |
10 | #define _lucene_store_FSDirectory_ |
11 | |
12 | #if defined(_LUCENE_PRAGMA_ONCE) |
13 | # pragma once |
14 | #endif |
15 | |
16 | #include <QtCore/QFile> |
17 | #include <QtCore/QString> |
18 | #include <QtCore/QStringList> |
19 | |
20 | #include "Directory.h" |
21 | #include "Lock.h" |
22 | #include "CLucene/util/VoidMap.h" |
23 | #include "CLucene/util/StringBuffer.h" |
24 | |
25 | CL_NS_DEF(store) |
26 | |
27 | /** |
28 | * Straightforward implementation of {@link Directory} as a directory of files. |
29 | * <p>If the system property 'disableLuceneLocks' has the String value of |
30 | * "true", lock creation will be disabled. |
31 | * |
32 | * @see Directory |
33 | */ |
34 | class FSDirectory : public Directory |
35 | { |
36 | public: |
37 | // Destructor - only call this if you are sure the directory |
38 | // is not being used anymore. Otherwise use the ref-counting |
39 | // facilities of _CLDECDELETE |
40 | ~FSDirectory(); |
41 | |
42 | // Get a list of strings, one for each file in the directory. |
43 | QStringList list() const; |
44 | |
45 | // Returns true iff a file with the given name exists. |
46 | bool fileExists(const QString& name) const; |
47 | |
48 | // Returns the text name of the directory |
49 | QString getDirName() const; ///<returns reference |
50 | |
51 | /** |
52 | Returns the directory instance for the named location. |
53 | |
54 | Do not delete this instance, only use close, otherwise other instances |
55 | will lose this instance. |
56 | |
57 | <p>Directories are cached, so that, for a given canonical path, the same |
58 | FSDirectory instance will always be returned. This permits |
59 | synchronization on directories. |
60 | |
61 | @param file the path to the directory. |
62 | @param create if true, create, or erase any existing contents. |
63 | @return the FSDirectory for the named file. |
64 | */ |
65 | static FSDirectory* getDirectory(const QString& file, const bool create); |
66 | |
67 | // Returns the time the named file was last modified. |
68 | int64_t fileModified(const QString& name) const; |
69 | |
70 | //static |
71 | // Returns the time the named file was last modified. |
72 | static int64_t fileModified(const QString& dir, const QString& name); |
73 | |
74 | // static |
75 | // Returns the length in bytes of a file in the directory. |
76 | int64_t fileLength(const QString& name) const; |
77 | |
78 | // Returns a stream reading an existing file. |
79 | IndexInput* openInput(const QString& name); |
80 | IndexInput* openInput(const QString& name, int32_t bufferSize); |
81 | |
82 | // Renames an existing file in the directory. |
83 | void renameFile(const QString& from, const QString& to); |
84 | |
85 | // Set the modified time of an existing file to now. |
86 | void touchFile(const QString& name); |
87 | |
88 | // Creates a new, empty file in the directory with the given name. |
89 | // Returns a stream writing this file. |
90 | IndexOutput* createOutput(const QString& name); |
91 | |
92 | // Construct a {@link Lock}. |
93 | // @param name the name of the lock file |
94 | LuceneLock* makeLock(const QString& name); |
95 | |
96 | // Decrease the ref-count to the directory by one. If the object is no |
97 | // longer needed, then the object is removed from the directory pool. |
98 | void close(); |
99 | |
100 | // If MMap is available, this can disable use of mmap reading. |
101 | void setUseMMap(bool value) { useMMap = value; } |
102 | |
103 | // Gets whether the directory is using MMap for inputstreams. |
104 | bool getUseMMap() const { return useMMap; } |
105 | |
106 | QString toString() const; |
107 | |
108 | static QString DirectoryType() { return QLatin1String("FS" ); } |
109 | QString getDirectoryType() const { return QLatin1String("FS" ); } |
110 | |
111 | // Set whether Lucene's use of lock files is disabled. By default, |
112 | // lock files are enabled. They should only be disabled if the index |
113 | // is on a read-only medium like a CD-ROM. |
114 | static void setDisableLocks(bool doDisableLocks) |
115 | { disableLocks = doDisableLocks; } |
116 | |
117 | // Returns whether Lucene's use of lock files is disabled. |
118 | // @return true if locks are disabled, false if locks are enabled. |
119 | static bool getDisableLocks() { return disableLocks; } |
120 | |
121 | protected: |
122 | FSDirectory(const QString& path, const bool createDir); |
123 | // Removes an existing file in the directory. |
124 | bool doDeleteFile(const QString& name); |
125 | |
126 | private: |
127 | class FSLock : public LuceneLock { |
128 | public: |
129 | FSLock (const QString& lockDir, const QString& name); |
130 | ~FSLock(); |
131 | |
132 | bool obtain(); |
133 | void release(); |
134 | bool isLocked(); |
135 | QString toString() const; |
136 | |
137 | QString lockDir; |
138 | QString lockFile; |
139 | }; |
140 | friend class FSDirectory::FSLock; |
141 | |
142 | class FSIndexInput : public BufferedIndexInput { |
143 | public: |
144 | FSIndexInput(const QString& path, int32_t bufferSize = |
145 | CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE); |
146 | ~FSIndexInput(); |
147 | |
148 | void close(); |
149 | IndexInput* clone() const; |
150 | |
151 | int64_t length() |
152 | { return handle->_length; } |
153 | |
154 | QString getDirectoryType() const |
155 | { return FSDirectory::DirectoryType(); } |
156 | |
157 | protected: |
158 | FSIndexInput(const FSIndexInput& clone); |
159 | // Random-access methods |
160 | void seekInternal(const int64_t position); |
161 | // IndexInput methods |
162 | void readInternal(uint8_t* b, const int32_t len); |
163 | |
164 | private: |
165 | // We used a shared handle between all the fsindexinput clones. |
166 | // This reduces number of file handles we need, and it means |
167 | // we dont have to use file tell (which is slow) before doing a read. |
168 | class SharedHandle : LUCENE_REFBASE { |
169 | public: |
170 | SharedHandle(); |
171 | ~SharedHandle(); |
172 | |
173 | int64_t _fpos; |
174 | int64_t _length; |
175 | |
176 | QFile fhandle; |
177 | DEFINE_MUTEX(*THIS_LOCK) |
178 | }; |
179 | SharedHandle* handle; |
180 | int64_t _pos; |
181 | }; |
182 | friend class FSDirectory::FSIndexInput; |
183 | |
184 | class FSIndexOutput : public BufferedIndexOutput { |
185 | public: |
186 | FSIndexOutput(const QString& path); |
187 | ~FSIndexOutput(); |
188 | |
189 | void close(); |
190 | int64_t length(); |
191 | void seek(const int64_t pos); |
192 | |
193 | protected: |
194 | void flushBuffer(const uint8_t* b, const int32_t size); |
195 | |
196 | private: |
197 | QFile fhandle; |
198 | }; |
199 | friend class FSDirectory::FSIndexOutput; |
200 | |
201 | private: |
202 | QString directory; |
203 | int refCount; |
204 | void create(); |
205 | |
206 | QString lockDir; |
207 | QString getLockPrefix() const; |
208 | static bool disableLocks; |
209 | |
210 | void priv_getFN(QString& buffer, const QString& name) const; |
211 | bool useMMap; |
212 | }; |
213 | |
214 | CL_NS_END |
215 | |
216 | #endif |
217 | |