View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.regionserver;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.Iterator;
26  import java.util.List;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.hadoop.hbase.classification.InterfaceAudience;
31  import org.apache.hadoop.conf.Configuration;
32  import org.apache.hadoop.hbase.Cell;
33  import org.apache.hadoop.hbase.KeyValue;
34  import org.apache.hadoop.hbase.KeyValue.KVComparator;
35  
36  import com.google.common.collect.ImmutableCollection;
37  import com.google.common.collect.ImmutableList;
38  import com.google.common.collect.Lists;
39  
40  /**
41   * Default implementation of StoreFileManager. Not thread-safe.
42   */
43  @InterfaceAudience.Private
44  class DefaultStoreFileManager implements StoreFileManager {
45    static final Log LOG = LogFactory.getLog(DefaultStoreFileManager.class);
46  
47    private final KVComparator kvComparator;
48    private final Configuration conf;
49  
50    /**
51     * List of store files inside this store. This is an immutable list that
52     * is atomically replaced when its contents change.
53     */
54    private volatile ImmutableList<StoreFile> storefiles = null;
55  
56    public DefaultStoreFileManager(KVComparator kvComparator, Configuration conf) {
57      this.kvComparator = kvComparator;
58      this.conf = conf;
59    }
60  
61    @Override
62    public void loadFiles(List<StoreFile> storeFiles) {
63      sortAndSetStoreFiles(storeFiles);
64    }
65  
66    @Override
67    public final Collection<StoreFile> getStorefiles() {
68      return storefiles;
69    }
70  
71    @Override
72    public void insertNewFiles(Collection<StoreFile> sfs) throws IOException {
73      ArrayList<StoreFile> newFiles = new ArrayList<StoreFile>(storefiles);
74      newFiles.addAll(sfs);
75      sortAndSetStoreFiles(newFiles);
76    }
77  
78    @Override
79    public ImmutableCollection<StoreFile> clearFiles() {
80      ImmutableList<StoreFile> result = storefiles;
81      storefiles = ImmutableList.of();
82      return result;
83    }
84  
85    @Override
86    public final int getStorefileCount() {
87      return storefiles.size();
88    }
89  
90    @Override
91    public void addCompactionResults(
92      Collection<StoreFile> compactedFiles, Collection<StoreFile> results) {
93      ArrayList<StoreFile> newStoreFiles = Lists.newArrayList(storefiles);
94      newStoreFiles.removeAll(compactedFiles);
95      if (!results.isEmpty()) {
96        newStoreFiles.addAll(results);
97      }
98      sortAndSetStoreFiles(newStoreFiles);
99    }
100 
101   @Override
102   public final Iterator<StoreFile> getCandidateFilesForRowKeyBefore(final KeyValue targetKey) {
103     return new ArrayList<StoreFile>(Lists.reverse(this.storefiles)).iterator();
104   }
105 
106   @Override
107   public Iterator<StoreFile> updateCandidateFilesForRowKeyBefore(
108       Iterator<StoreFile> candidateFiles, final KeyValue targetKey, final Cell candidate) {
109     // Default store has nothing useful to do here.
110     // TODO: move this comment when implementing Level:
111     // Level store can trim the list by range, removing all the files which cannot have
112     // any useful candidates less than "candidate".
113     return candidateFiles;
114   }
115 
116   @Override
117   public final byte[] getSplitPoint() throws IOException {
118     if (this.storefiles.isEmpty()) {
119       return null;
120     }
121     return StoreUtils.getLargestFile(this.storefiles).getFileSplitPoint(this.kvComparator);
122   }
123 
124   @Override
125   public final Collection<StoreFile> getFilesForScanOrGet(boolean isGet,
126       byte[] startRow, byte[] stopRow) {
127     // We cannot provide any useful input and already have the files sorted by seqNum.
128     return getStorefiles();
129   }
130 
131   @Override
132   public int getStoreCompactionPriority() {
133     int blockingFileCount = conf.getInt(
134         HStore.BLOCKING_STOREFILES_KEY, HStore.DEFAULT_BLOCKING_STOREFILE_COUNT);
135     int priority = blockingFileCount - storefiles.size();
136     return (priority == HStore.PRIORITY_USER) ? priority + 1 : priority;
137   }
138 
139   @Override
140   public Collection<StoreFile> getUnneededFiles(long maxTs, List<StoreFile> filesCompacting) {
141     Collection<StoreFile> expiredStoreFiles = null;
142     ImmutableList<StoreFile> files = storefiles;
143     // 1) We can never get rid of the last file which has the maximum seqid.
144     // 2) Files that are not the latest can't become one due to (1), so the rest are fair game.
145     for (int i = 0; i < files.size() - 1; ++i) {
146       StoreFile sf = files.get(i);
147       long fileTs = sf.getReader().getMaxTimestamp();
148       if (fileTs < maxTs && !filesCompacting.contains(sf)) {
149         LOG.info("Found an expired store file: " + sf.getPath()
150             + " whose maxTimeStamp is " + fileTs + ", which is below " + maxTs);
151         if (expiredStoreFiles == null) {
152           expiredStoreFiles = new ArrayList<StoreFile>();
153         }
154         expiredStoreFiles.add(sf);
155       }
156     }
157     return expiredStoreFiles;
158   }
159 
160   private void sortAndSetStoreFiles(List<StoreFile> storeFiles) {
161     Collections.sort(storeFiles, StoreFile.Comparators.SEQ_ID);
162     storefiles = ImmutableList.copyOf(storeFiles);
163   }
164 
165 }
166