blob: c870041f48a58e8a7481d653c30d19d26cfdb7fe [file] [log] [blame]
/*
* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
*
* Distributable under the terms of either the Apache License (Version 2.0) or
* the GNU Lesser General Public License, as specified in the COPYING file.
*
* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
*/
#ifndef _lucene_store_FSDirectory_
#define _lucene_store_FSDirectory_
#if defined(_LUCENE_PRAGMA_ONCE)
# pragma once
#endif
#include <QtCore/QFile>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include "Directory.h"
#include "Lock.h"
#include "CLucene/util/VoidMap.h"
#include "CLucene/util/StringBuffer.h"
CL_NS_DEF(store)
/**
* Straightforward implementation of {@link Directory} as a directory of files.
* <p>If the system property 'disableLuceneLocks' has the String value of
* "true", lock creation will be disabled.
*
* @see Directory
*/
class FSDirectory : public Directory
{
public:
// Destructor - only call this if you are sure the directory
// is not being used anymore. Otherwise use the ref-counting
// facilities of _CLDECDELETE
~FSDirectory();
// Get a list of strings, one for each file in the directory.
QStringList list() const;
// Returns true iff a file with the given name exists.
bool fileExists(const QString& name) const;
// Returns the text name of the directory
QString getDirName() const; ///<returns reference
/**
Returns the directory instance for the named location.
Do not delete this instance, only use close, otherwise other instances
will lose this instance.
<p>Directories are cached, so that, for a given canonical path, the same
FSDirectory instance will always be returned. This permits
synchronization on directories.
@param file the path to the directory.
@param create if true, create, or erase any existing contents.
@return the FSDirectory for the named file.
*/
static FSDirectory* getDirectory(const QString& file, const bool create);
// Returns the time the named file was last modified.
int64_t fileModified(const QString& name) const;
//static
// Returns the time the named file was last modified.
static int64_t fileModified(const QString& dir, const QString& name);
// static
// Returns the length in bytes of a file in the directory.
int64_t fileLength(const QString& name) const;
// Returns a stream reading an existing file.
IndexInput* openInput(const QString& name);
IndexInput* openInput(const QString& name, int32_t bufferSize);
// Renames an existing file in the directory.
void renameFile(const QString& from, const QString& to);
// Set the modified time of an existing file to now.
void touchFile(const QString& name);
// Creates a new, empty file in the directory with the given name.
// Returns a stream writing this file.
IndexOutput* createOutput(const QString& name);
// Construct a {@link Lock}.
// @param name the name of the lock file
LuceneLock* makeLock(const QString& name);
// Decrease the ref-count to the directory by one. If the object is no
// longer needed, then the object is removed from the directory pool.
void close();
// If MMap is available, this can disable use of mmap reading.
void setUseMMap(bool value) { useMMap = value; }
// Gets whether the directory is using MMap for inputstreams.
bool getUseMMap() const { return useMMap; }
QString toString() const;
static QString DirectoryType() { return QLatin1String("FS"); }
QString getDirectoryType() const { return QLatin1String("FS"); }
// Set whether Lucene's use of lock files is disabled. By default,
// lock files are enabled. They should only be disabled if the index
// is on a read-only medium like a CD-ROM.
static void setDisableLocks(bool doDisableLocks)
{ disableLocks = doDisableLocks; }
// Returns whether Lucene's use of lock files is disabled.
// @return true if locks are disabled, false if locks are enabled.
static bool getDisableLocks() { return disableLocks; }
protected:
FSDirectory(const QString& path, const bool createDir);
// Removes an existing file in the directory.
bool doDeleteFile(const QString& name);
private:
class FSLock : public LuceneLock {
public:
FSLock (const QString& lockDir, const QString& name);
~FSLock();
bool obtain();
void release();
bool isLocked();
QString toString() const;
QString lockDir;
QString lockFile;
};
friend class FSDirectory::FSLock;
class FSIndexInput : public BufferedIndexInput {
public:
FSIndexInput(const QString& path, int32_t bufferSize =
CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE);
~FSIndexInput();
void close();
IndexInput* clone() const;
int64_t length()
{ return handle->_length; }
QString getDirectoryType() const
{ return FSDirectory::DirectoryType(); }
protected:
FSIndexInput(const FSIndexInput& clone);
// Random-access methods
void seekInternal(const int64_t position);
// IndexInput methods
void readInternal(uint8_t* b, const int32_t len);
private:
// We used a shared handle between all the fsindexinput clones.
// This reduces number of file handles we need, and it means
// we dont have to use file tell (which is slow) before doing a read.
class SharedHandle : LUCENE_REFBASE {
public:
SharedHandle();
~SharedHandle();
int64_t _fpos;
int64_t _length;
QFile fhandle;
DEFINE_MUTEX(*THIS_LOCK)
};
SharedHandle* handle;
int64_t _pos;
};
friend class FSDirectory::FSIndexInput;
class FSIndexOutput : public BufferedIndexOutput {
public:
FSIndexOutput(const QString& path);
~FSIndexOutput();
void close();
int64_t length();
void seek(const int64_t pos);
protected:
void flushBuffer(const uint8_t* b, const int32_t size);
private:
QFile fhandle;
};
friend class FSDirectory::FSIndexOutput;
private:
QString directory;
int refCount;
void create();
QString lockDir;
QString getLockPrefix() const;
static bool disableLocks;
void priv_getFN(QString& buffer, const QString& name) const;
bool useMMap;
};
CL_NS_END
#endif