17
17
*/
18
18
package org .apache .hadoop .hbase .regionserver ;
19
19
20
+ import static org .apache .hadoop .hbase .regionserver .StoreFileWriter .shouldEnableHistoricalCompactionFiles ;
21
+
22
+ import edu .umd .cs .findbugs .annotations .Nullable ;
20
23
import java .io .IOException ;
24
+ import java .util .ArrayList ;
21
25
import java .util .Collection ;
22
26
import java .util .Comparator ;
23
27
import java .util .Iterator ;
@@ -48,36 +52,71 @@ class DefaultStoreFileManager implements StoreFileManager {
48
52
private final CompactionConfiguration comConf ;
49
53
private final int blockingFileCount ;
50
54
private final Comparator <HStoreFile > storeFileComparator ;
51
- /**
52
- * List of store files inside this store. This is an immutable list that is atomically replaced
53
- * when its contents change.
54
- */
55
- private volatile ImmutableList <HStoreFile > storefiles = ImmutableList .of ();
55
+
56
+ static class StoreFileList {
57
+ /**
58
+ * List of store files inside this store. This is an immutable list that is atomically replaced
59
+ * when its contents change.
60
+ */
61
+ final ImmutableList <HStoreFile > all ;
62
+ /**
63
+ * List of store files that include the latest cells inside this store. This is an immutable
64
+ * list that is atomically replaced when its contents change.
65
+ */
66
+ @ Nullable
67
+ final ImmutableList <HStoreFile > live ;
68
+
69
+ StoreFileList (ImmutableList <HStoreFile > storeFiles , ImmutableList <HStoreFile > liveStoreFiles ) {
70
+ this .all = storeFiles ;
71
+ this .live = liveStoreFiles ;
72
+ }
73
+ }
74
+
75
+ private volatile StoreFileList storeFiles ;
76
+
56
77
/**
57
78
* List of compacted files inside this store that needs to be excluded in reads because further
58
79
* new reads will be using only the newly created files out of compaction. These compacted files
59
80
* will be deleted/cleared once all the existing readers on these compacted files are done.
60
81
*/
61
82
private volatile ImmutableList <HStoreFile > compactedfiles = ImmutableList .of ();
83
+ private final boolean enableLiveFileTracking ;
62
84
63
85
public DefaultStoreFileManager (CellComparator cellComparator ,
64
86
Comparator <HStoreFile > storeFileComparator , Configuration conf ,
65
87
CompactionConfiguration comConf ) {
66
88
this .cellComparator = cellComparator ;
67
89
this .storeFileComparator = storeFileComparator ;
68
90
this .comConf = comConf ;
69
- this . blockingFileCount =
91
+ blockingFileCount =
70
92
conf .getInt (HStore .BLOCKING_STOREFILES_KEY , HStore .DEFAULT_BLOCKING_STOREFILE_COUNT );
93
+ enableLiveFileTracking = shouldEnableHistoricalCompactionFiles (conf );
94
+ storeFiles =
95
+ new StoreFileList (ImmutableList .of (), enableLiveFileTracking ? ImmutableList .of () : null );
96
+ }
97
+
98
+ private List <HStoreFile > getLiveFiles (Collection <HStoreFile > storeFiles ) throws IOException {
99
+ List <HStoreFile > liveFiles = new ArrayList <>(storeFiles .size ());
100
+ for (HStoreFile file : storeFiles ) {
101
+ file .initReader ();
102
+ if (!file .isHistorical ()) {
103
+ liveFiles .add (file );
104
+ }
105
+ }
106
+ return liveFiles ;
71
107
}
72
108
73
109
@ Override
74
- public void loadFiles (List <HStoreFile > storeFiles ) {
75
- this .storefiles = ImmutableList .sortedCopyOf (storeFileComparator , storeFiles );
110
+ public void loadFiles (List <HStoreFile > storeFiles ) throws IOException {
111
+ this .storeFiles = new StoreFileList (ImmutableList .sortedCopyOf (storeFileComparator , storeFiles ),
112
+ enableLiveFileTracking
113
+ ? ImmutableList .sortedCopyOf (storeFileComparator , getLiveFiles (storeFiles ))
114
+ : null );
76
115
}
77
116
78
117
@ Override
79
- public final Collection <HStoreFile > getStorefiles () {
80
- return storefiles ;
118
+ public final Collection <HStoreFile > getStoreFiles () {
119
+ return storeFiles . all ;
81
120
}
82
121
83
122
@ Override
@@ -86,15 +125,20 @@ public Collection<HStoreFile> getCompactedfiles() {
86
125
}
87
126
88
127
@ Override
89
- public void insertNewFiles (Collection <HStoreFile > sfs ) {
90
- this .storefiles =
91
- ImmutableList .sortedCopyOf (storeFileComparator , Iterables .concat (this .storefiles , sfs ));
128
+ public void insertNewFiles (Collection <HStoreFile > sfs ) throws IOException {
129
+ storeFiles = new StoreFileList (
130
+ ImmutableList .sortedCopyOf (storeFileComparator , Iterables .concat (storeFiles .all , sfs )),
131
+ enableLiveFileTracking
132
+ ? ImmutableList .sortedCopyOf (storeFileComparator ,
133
+ Iterables .concat (storeFiles .live , getLiveFiles (sfs )))
134
+ : null );
92
135
}
93
136
94
137
@ Override
95
138
public ImmutableCollection <HStoreFile > clearFiles () {
96
- ImmutableList <HStoreFile > result = storefiles ;
97
- storefiles = ImmutableList .of ();
139
+ ImmutableList <HStoreFile > result = storeFiles .all ;
140
+ storeFiles =
141
+ new StoreFileList (ImmutableList .of (), enableLiveFileTracking ? ImmutableList .of () : null );
98
142
return result ;
99
143
}
100
144
@@ -107,7 +151,7 @@ public Collection<HStoreFile> clearCompactedFiles() {
107
151
108
152
@ Override
109
153
public final int getStorefileCount () {
110
- return storefiles .size ();
154
+ return storeFiles . all .size ();
111
155
}
112
156
113
157
@ Override
@@ -117,28 +161,38 @@ public final int getCompactedFilesCount() {
117
161
118
162
@ Override
119
163
public void addCompactionResults (Collection <HStoreFile > newCompactedfiles ,
120
- Collection <HStoreFile > results ) {
121
- this .storefiles = ImmutableList .sortedCopyOf (storeFileComparator , Iterables
122
- .concat (Iterables .filter (storefiles , sf -> !newCompactedfiles .contains (sf )), results ));
164
+ Collection <HStoreFile > results ) throws IOException {
165
+ ImmutableList <HStoreFile > liveStoreFiles = null ;
166
+ if (enableLiveFileTracking ) {
167
+ liveStoreFiles = ImmutableList .sortedCopyOf (storeFileComparator ,
168
+ Iterables .concat (Iterables .filter (storeFiles .live , sf -> !newCompactedfiles .contains (sf )),
169
+ getLiveFiles (results )));
170
+ }
171
+ storeFiles =
172
+ new StoreFileList (
173
+ ImmutableList
174
+ .sortedCopyOf (storeFileComparator ,
175
+ Iterables .concat (
176
+ Iterables .filter (storeFiles .all , sf -> !newCompactedfiles .contains (sf )), results )),
177
+ liveStoreFiles );
123
178
// Mark the files as compactedAway once the storefiles and compactedfiles list is finalized
124
179
// Let a background thread close the actual reader on these compacted files and also
125
180
// ensure to evict the blocks from block cache so that they are no longer in
126
181
// cache
127
182
newCompactedfiles .forEach (HStoreFile ::markCompactedAway );
128
- this . compactedfiles = ImmutableList .sortedCopyOf (storeFileComparator ,
129
- Iterables .concat (this . compactedfiles , newCompactedfiles ));
183
+ compactedfiles = ImmutableList .sortedCopyOf (storeFileComparator ,
184
+ Iterables .concat (compactedfiles , newCompactedfiles ));
130
185
}
131
186
132
187
@ Override
133
188
public void removeCompactedFiles (Collection <HStoreFile > removedCompactedfiles ) {
134
- this .compactedfiles =
135
- this .compactedfiles .stream ().filter (sf -> !removedCompactedfiles .contains (sf ))
136
- .sorted (storeFileComparator ).collect (ImmutableList .toImmutableList ());
189
+ compactedfiles = compactedfiles .stream ().filter (sf -> !removedCompactedfiles .contains (sf ))
190
+ .sorted (storeFileComparator ).collect (ImmutableList .toImmutableList ());
137
191
}
138
192
139
193
@ Override
140
194
public final Iterator <HStoreFile > getCandidateFilesForRowKeyBefore (KeyValue targetKey ) {
141
- return this . storefiles .reverse ().iterator ();
195
+ return storeFiles . all .reverse ().iterator ();
142
196
}
143
197
144
198
@ Override
@@ -153,25 +207,28 @@ public Iterator<HStoreFile> updateCandidateFilesForRowKeyBefore(
153
207
154
208
@ Override
155
209
public final Optional <byte []> getSplitPoint () throws IOException {
156
- return StoreUtils .getSplitPoint (storefiles , cellComparator );
210
+ return StoreUtils .getSplitPoint (storeFiles . all , cellComparator );
157
211
}
158
212
159
213
@ Override
160
- public final Collection <HStoreFile > getFilesForScan (byte [] startRow , boolean includeStartRow ,
161
- byte [] stopRow , boolean includeStopRow ) {
214
+ public Collection <HStoreFile > getFilesForScan (byte [] startRow , boolean includeStartRow ,
215
+ byte [] stopRow , boolean includeStopRow , boolean onlyLatestVersion ) {
216
+ if (onlyLatestVersion && enableLiveFileTracking ) {
217
+ return storeFiles .live ;
218
+ }
162
219
// We cannot provide any useful input and already have the files sorted by seqNum.
163
- return getStorefiles ();
220
+ return getStoreFiles ();
164
221
}
165
222
166
223
@ Override
167
224
public int getStoreCompactionPriority () {
168
- int priority = blockingFileCount - storefiles .size ();
225
+ int priority = blockingFileCount - storeFiles . all .size ();
169
226
return (priority == HStore .PRIORITY_USER ) ? priority + 1 : priority ;
170
227
}
171
228
172
229
@ Override
173
230
public Collection <HStoreFile > getUnneededFiles (long maxTs , List <HStoreFile > filesCompacting ) {
174
- ImmutableList <HStoreFile > files = storefiles ;
231
+ ImmutableList <HStoreFile > files = storeFiles . all ;
175
232
// 1) We can never get rid of the last file which has the maximum seqid.
176
233
// 2) Files that are not the latest can't become one due to (1), so the rest are fair game.
177
234
return files .stream ().limit (Math .max (0 , files .size () - 1 )).filter (sf -> {
0 commit comments