@@ -64,11 +64,7 @@ public Directory newDirectory(IndexSettings indexSettings, ShardPath path) throw
64
64
final Path location = path .resolveIndex ();
65
65
final LockFactory lockFactory = indexSettings .getValue (INDEX_LOCK_FACTOR_SETTING );
66
66
Files .createDirectories (location );
67
- Directory wrapped = newFSDirectory (location , lockFactory , indexSettings );
68
- Set <String > preLoadExtensions = new HashSet <>(
69
- indexSettings .getValue (IndexModule .INDEX_STORE_PRE_LOAD_SETTING ));
70
- wrapped = setPreload (wrapped , location , lockFactory , preLoadExtensions );
71
- return wrapped ;
67
+ return newFSDirectory (location , lockFactory , indexSettings );
72
68
}
73
69
74
70
protected Directory newFSDirectory (Path location , LockFactory lockFactory , IndexSettings indexSettings ) throws IOException {
@@ -80,17 +76,20 @@ protected Directory newFSDirectory(Path location, LockFactory lockFactory, Index
80
76
} else {
81
77
type = IndexModule .Type .fromSettingsKey (storeType );
82
78
}
79
+ Set <String > preLoadExtensions = new HashSet <>(
80
+ indexSettings .getValue (IndexModule .INDEX_STORE_PRE_LOAD_SETTING ));
83
81
switch (type ) {
84
82
case HYBRIDFS :
85
83
// Use Lucene defaults
86
84
final FSDirectory primaryDirectory = FSDirectory .open (location , lockFactory );
87
85
if (primaryDirectory instanceof MMapDirectory ) {
88
- return new HybridDirectory (location , lockFactory , primaryDirectory );
86
+ MMapDirectory mMapDirectory = (MMapDirectory ) primaryDirectory ;
87
+ return new HybridDirectory (lockFactory , setPreload (mMapDirectory , lockFactory , preLoadExtensions ));
89
88
} else {
90
89
return primaryDirectory ;
91
90
}
92
91
case MMAPFS :
93
- return new MMapDirectory (location , lockFactory );
92
+ return setPreload ( new MMapDirectory (location , lockFactory ), lockFactory , preLoadExtensions );
94
93
case SIMPLEFS :
95
94
return new SimpleFSDirectory (location , lockFactory );
96
95
case NIOFS :
@@ -100,26 +99,17 @@ protected Directory newFSDirectory(Path location, LockFactory lockFactory, Index
100
99
}
101
100
}
102
101
103
- private static Directory setPreload (Directory directory , Path location , LockFactory lockFactory ,
102
+ public static MMapDirectory setPreload (MMapDirectory mMapDirectory , LockFactory lockFactory ,
104
103
Set <String > preLoadExtensions ) throws IOException {
105
- if (preLoadExtensions .isEmpty () == false
106
- && directory instanceof MMapDirectory
107
- && ((MMapDirectory ) directory ).getPreload () == false ) {
104
+ assert mMapDirectory .getPreload () == false ;
105
+ if (preLoadExtensions .isEmpty () == false ) {
108
106
if (preLoadExtensions .contains ("*" )) {
109
- ((MMapDirectory ) directory ).setPreload (true );
110
- return directory ;
107
+ mMapDirectory .setPreload (true );
108
+ } else {
109
+ return new PreLoadMMapDirectory (mMapDirectory , lockFactory , preLoadExtensions );
111
110
}
112
- MMapDirectory primary = new MMapDirectory (location , lockFactory );
113
- primary .setPreload (true );
114
- return new FileSwitchDirectory (preLoadExtensions , primary , directory , true ) {
115
- @ Override
116
- public String [] listAll () throws IOException {
117
- // avoid listing twice
118
- return primary .listAll ();
119
- }
120
- };
121
111
}
122
- return directory ;
112
+ return mMapDirectory ;
123
113
}
124
114
125
115
/**
@@ -131,15 +121,35 @@ public static boolean isHybridFs(Directory directory) {
131
121
}
132
122
133
123
static final class HybridDirectory extends NIOFSDirectory {
134
- private final FSDirectory randomAccessDirectory ;
124
+ private final MMapDirectory delegate ;
135
125
136
- HybridDirectory (Path location , LockFactory lockFactory , FSDirectory randomAccessDirectory ) throws IOException {
137
- super (location , lockFactory );
138
- this .randomAccessDirectory = randomAccessDirectory ;
126
+ HybridDirectory (LockFactory lockFactory , MMapDirectory delegate ) throws IOException {
127
+ super (delegate . getDirectory () , lockFactory );
128
+ this .delegate = delegate ;
139
129
}
140
130
141
131
@ Override
142
132
public IndexInput openInput (String name , IOContext context ) throws IOException {
133
+ if (useDelegate (name )) {
134
+ // we need to do these checks on the outer directory since the inner doesn't know about pending deletes
135
+ ensureOpen ();
136
+ ensureCanRead (name );
137
+ // we only use the mmap to open inputs. Everything else is managed by the NIOFSDirectory otherwise
138
+ // we might run into trouble with files that are pendingDelete in one directory but still
139
+ // listed in listAll() from the other. We on the other hand don't want to list files from both dirs
140
+ // and intersect for perf reasons.
141
+ return delegate .openInput (name , context );
142
+ } else {
143
+ return super .openInput (name , context );
144
+ }
145
+ }
146
+
147
+ @ Override
148
+ public void close () throws IOException {
149
+ IOUtils .close (super ::close , delegate );
150
+ }
151
+
152
+ boolean useDelegate (String name ) {
143
153
String extension = FileSwitchDirectory .getExtension (name );
144
154
switch (extension ) {
145
155
// We are mmapping norms, docvalues as well as term dictionaries, all other files are served through NIOFS
@@ -148,26 +158,59 @@ public IndexInput openInput(String name, IOContext context) throws IOException {
148
158
case "dvd" :
149
159
case "tim" :
150
160
case "cfs" :
151
- // we need to do these checks on the outer directory since the inner doesn't know about pending deletes
152
- ensureOpen ();
153
- ensureCanRead (name );
154
- // we only use the mmap to open inputs. Everything else is managed by the NIOFSDirectory otherwise
155
- // we might run into trouble with files that are pendingDelete in one directory but still
156
- // listed in listAll() from the other. We on the other hand don't want to list files from both dirs
157
- // and intersect for perf reasons.
158
- return randomAccessDirectory .openInput (name , context );
161
+ return true ;
159
162
default :
160
- return super .openInput (name , context );
163
+ return false ;
164
+ }
165
+ }
166
+
167
+ MMapDirectory getDelegate () {
168
+ return delegate ;
169
+ }
170
+ }
171
+ // TODO it would be nice to share code between PreLoadMMapDirectory and HybridDirectory but due to the nesting aspect of
172
+ // directories here makes it tricky. It would be nice to allow MMAPDirectory to pre-load on a per IndexInput basis.
173
+ static final class PreLoadMMapDirectory extends MMapDirectory {
174
+ private final MMapDirectory delegate ;
175
+ private final Set <String > preloadExtensions ;
176
+
177
+ PreLoadMMapDirectory (MMapDirectory delegate , LockFactory lockFactory , Set <String > preload ) throws IOException {
178
+ super (delegate .getDirectory (), lockFactory );
179
+ super .setPreload (false );
180
+ this .delegate = delegate ;
181
+ this .delegate .setPreload (true );
182
+ this .preloadExtensions = preload ;
183
+ assert getPreload () == false ;
184
+ }
185
+
186
+ @ Override
187
+ public void setPreload (boolean preload ) {
188
+ throw new IllegalArgumentException ("can't set preload on a preload-wrapper" );
189
+ }
190
+
191
+ @ Override
192
+ public IndexInput openInput (String name , IOContext context ) throws IOException {
193
+ if (useDelegate (name )) {
194
+ // we need to do these checks on the outer directory since the inner doesn't know about pending deletes
195
+ ensureOpen ();
196
+ ensureCanRead (name );
197
+ return delegate .openInput (name , context );
161
198
}
199
+ return super .openInput (name , context );
162
200
}
163
201
164
202
@ Override
165
- public void close () throws IOException {
166
- IOUtils .close (super ::close , randomAccessDirectory );
203
+ public synchronized void close () throws IOException {
204
+ IOUtils .close (super ::close , delegate );
205
+ }
206
+
207
+ boolean useDelegate (String name ) {
208
+ final String extension = FileSwitchDirectory .getExtension (name );
209
+ return preloadExtensions .contains (extension );
167
210
}
168
211
169
- Directory getRandomAccessDirectory () {
170
- return randomAccessDirectory ;
212
+ MMapDirectory getDelegate () {
213
+ return delegate ;
171
214
}
172
215
}
173
216
}
0 commit comments