summaryrefslogtreecommitdiffstats
path: root/3rdparty/clucene/src/CLucene/store/MMapInput.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/clucene/src/CLucene/store/MMapInput.cpp')
-rw-r--r--3rdparty/clucene/src/CLucene/store/MMapInput.cpp203
1 files changed, 203 insertions, 0 deletions
diff --git a/3rdparty/clucene/src/CLucene/store/MMapInput.cpp b/3rdparty/clucene/src/CLucene/store/MMapInput.cpp
new file mode 100644
index 000000000..d660032c6
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/MMapInput.cpp
@@ -0,0 +1,203 @@
+/*------------------------------------------------------------------------------
+* 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.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#if defined(LUCENE_FS_MMAP)
+
+#include "FSDirectory.h"
+#include "CLucene/util/Misc.h"
+#include "CLucene/debug/condition.h"
+
+#ifndef _CLCOMPILER_MSVC
+ #include <sys/mman.h>
+#endif
+
+CL_NS_DEF(store)
+CL_NS_USE(util)
+
+ FSDirectory::MMapIndexInput::MMapIndexInput(const char* path):
+ pos(0),
+ data(NULL),
+ _length(0),
+ isClone(false)
+ {
+ //Func - Constructor.
+ // Opens the file named path
+ //Pre - path != NULL
+ //Post - if the file could not be opened an exception is thrown.
+
+ CND_PRECONDITION(path != NULL, "path is NULL");
+
+#ifdef _CLCOMPILER_MSVC
+ mmaphandle = NULL;
+ fhandle = CreateFileA(path,GENERIC_READ,FILE_SHARE_READ, 0,OPEN_EXISTING,0,0);
+
+ //Check if a valid fhandle was retrieved
+ if (fhandle < 0){
+ DWORD err = GetLastError();
+ if ( err == ERROR_FILE_NOT_FOUND )
+ _CLTHROWA(CL_ERR_IO, "File does not exist");
+ else if ( err == EACCES )
+ _CLTHROWA(ERROR_ACCESS_DENIED, "File Access denied");
+ else if ( err == ERROR_TOO_MANY_OPEN_FILES )
+ _CLTHROWA(CL_ERR_IO, "Too many open files");
+ else
+ _CLTHROWA(CL_ERR_IO, "File IO Error");
+ }
+
+ DWORD dummy=0;
+ _length = GetFileSize(fhandle,&dummy);
+
+ if ( _length > 0 ){
+ mmaphandle = CreateFileMappingA(fhandle,NULL,PAGE_READONLY,0,0,NULL);
+ if ( mmaphandle != NULL ){
+ void* address = MapViewOfFile(mmaphandle,FILE_MAP_READ,0,0,0);
+ if ( address != NULL ){
+ data = (uint8_t*)address;
+ return; //SUCCESS!
+ }
+ }
+ CloseHandle(mmaphandle);
+
+ char* lpMsgBuf=0;
+ DWORD dw = GetLastError();
+
+ FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ dw,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ lpMsgBuf,
+ 0, NULL );
+
+ char* errstr = _CL_NEWARRAY(char, strlen(lpMsgBuf)+40);
+ sprintf(errstr, "MMapIndexInput::MMapIndexInput failed with error %d: %s", dw, lpMsgBuf);
+ LocalFree(lpMsgBuf);
+
+ _CLTHROWA_DEL(CL_ERR_IO,errstr);
+ }
+
+#else //_CLCOMPILER_MSVC
+ fhandle = ::open (path, O_RDONLY);
+ if (fhandle < 0){
+ _CLTHROWA(CL_ERR_IO,strerror(errno));
+ }else{
+ // stat it
+ struct stat sb;
+ if (::fstat (fhandle, &sb)){
+ _CLTHROWA(CL_ERR_IO,strerror(errno));
+ }else{
+ // get length from stat
+ _length = sb.st_size;
+
+ // mmap the file
+ void* address = ::mmap(0, _length, PROT_READ, MAP_SHARED, fhandle, 0);
+ if (address == MAP_FAILED){
+ _CLTHROWA(CL_ERR_IO,strerror(errno));
+ }else{
+ data = (uint8_t*)address;
+ }
+ }
+ }
+#endif
+ }
+
+ FSDirectory::MMapIndexInput::MMapIndexInput(const MMapIndexInput& clone): IndexInput(clone){
+ //Func - Constructor
+ // Uses clone for its initialization
+ //Pre - clone is a valide instance of FSIndexInput
+ //Post - The instance has been created and initialized by clone
+
+#ifdef _CLCOMPILER_MSVC
+ mmaphandle = NULL;
+ fhandle = NULL;
+#endif
+
+ data = clone.data;
+ pos = clone.pos;
+
+ //clone the file length
+ _length = clone._length;
+ //Keep in mind that this instance is a clone
+ isClone = true;
+ }
+
+ uint8_t FSDirectory::MMapIndexInput::readByte(){
+ return *(data+(pos++));
+ }
+
+ void FSDirectory::MMapIndexInput::readBytes(uint8_t* b, const int32_t len){
+ memcpy(b, data+pos, len);
+ pos+=len;
+ }
+ int32_t FSDirectory::MMapIndexInput::readVInt(){
+ uint8_t b = *(data+(pos++));
+ int32_t i = b & 0x7F;
+ for (int shift = 7; (b & 0x80) != 0; shift += 7) {
+ b = *(data+(pos++));
+ i |= (b & 0x7F) << shift;
+ }
+ return i;
+ }
+ int64_t FSDirectory::MMapIndexInput::getFilePointer() const{
+ return pos;
+ }
+ void FSDirectory::MMapIndexInput::seek(const int64_t pos){
+ this->pos=pos;
+ }
+
+ FSDirectory::MMapIndexInput::~MMapIndexInput(){
+ //Func - Destructor
+ //Pre - True
+ //Post - The file for which this instance is responsible has been closed.
+ // The instance has been destroyed
+
+ close();
+ }
+
+ IndexInput* FSDirectory::MMapIndexInput::clone() const
+ {
+ return _CLNEW FSDirectory::MMapIndexInput(*this);
+ }
+ void FSDirectory::MMapIndexInput::close() {
+ //IndexInput::close();
+
+ if ( !isClone ){
+#ifdef _CLCOMPILER_MSVC
+ if ( data != NULL ){
+ if ( ! UnmapViewOfFile(data) ){
+ CND_PRECONDITION( false, "UnmapViewOfFile(data) failed"); //todo: change to rich error
+ }
+ }
+
+ if ( mmaphandle != NULL ){
+ if ( ! CloseHandle(mmaphandle) ){
+ CND_PRECONDITION( false, "CloseHandle(mmaphandle) failed");
+ }
+ }
+ if ( fhandle != NULL ){
+ if ( !CloseHandle(fhandle) ){
+ CND_PRECONDITION( false, "CloseHandle(fhandle) failed");
+ }
+ }
+ mmaphandle = NULL;
+ fhandle = NULL;
+#else
+ if ( data != NULL )
+ ::munmap(data, _length);
+ if ( fhandle > 0 )
+ ::close(fhandle);
+ fhandle = 0;
+#endif
+ }
+ data = NULL;
+ pos = 0;
+ }
+
+
+CL_NS_END
+#endif