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
25CL_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*/
34class FSDirectory : public Directory
35{
36public:
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
121protected:
122 FSDirectory(const QString& path, const bool createDir);
123 // Removes an existing file in the directory.
124 bool doDeleteFile(const QString& name);
125
126private:
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
201private:
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
214CL_NS_END
215
216#endif
217