1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
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
|