001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.mob.compactions; 020 021import java.util.ArrayList; 022import java.util.Collection; 023import java.util.Collections; 024import java.util.List; 025 026import org.apache.hadoop.fs.FileStatus; 027import org.apache.hadoop.fs.Path; 028import org.apache.hadoop.hbase.regionserver.HStoreFile; 029import org.apache.hadoop.hbase.util.Bytes; 030import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 031import org.apache.yetus.audience.InterfaceAudience; 032 033/** 034 * An implementation of {@link MobCompactionRequest} that is used in 035 * {@link PartitionedMobCompactor}. 036 * The mob files that have the same start key and date in their names belong to 037 * the same partition. 038 */ 039@InterfaceAudience.Private 040public class PartitionedMobCompactionRequest extends MobCompactionRequest { 041 042 protected List<CompactionDelPartition> delPartitions; 043 protected Collection<CompactionPartition> compactionPartitions; 044 045 public PartitionedMobCompactionRequest(Collection<CompactionPartition> compactionPartitions, 046 List<CompactionDelPartition> delPartitions) { 047 this.selectionTime = EnvironmentEdgeManager.currentTime(); 048 this.compactionPartitions = compactionPartitions; 049 this.delPartitions = delPartitions; 050 } 051 052 /** 053 * Gets the compaction partitions. 054 * @return The compaction partitions. 055 */ 056 public Collection<CompactionPartition> getCompactionPartitions() { 057 return this.compactionPartitions; 058 } 059 060 /** 061 * Gets the del files. 062 * @return The del files. 063 */ 064 public List<CompactionDelPartition> getDelPartitions() { 065 return this.delPartitions; 066 } 067 068 /** 069 * The partition in the mob compaction. 070 * The mob files that have the same start key and date in their names belong to 071 * the same partition. 072 */ 073 protected static class CompactionPartition { 074 private List<FileStatus> files = new ArrayList<>(); 075 private CompactionPartitionId partitionId; 076 077 // The startKey and endKey of this partition, both are inclusive. 078 private byte[] startKey; 079 private byte[] endKey; 080 081 public CompactionPartition(CompactionPartitionId partitionId) { 082 this.partitionId = partitionId; 083 } 084 085 public CompactionPartitionId getPartitionId() { 086 return this.partitionId; 087 } 088 089 public void addFile(FileStatus file) { 090 files.add(file); 091 } 092 093 public List<FileStatus> listFiles() { 094 return Collections.unmodifiableList(files); 095 } 096 097 public int getFileCount () { 098 return files.size(); 099 } 100 101 public byte[] getStartKey() { 102 return startKey; 103 } 104 105 /** 106 * Set start key of this partition, only if the input startKey is less than 107 * the current start key. 108 */ 109 public void setStartKey(final byte[] startKey) { 110 if ((this.startKey == null) || (Bytes.compareTo(startKey, this.startKey) < 0)) { 111 this.startKey = startKey; 112 } 113 } 114 115 public byte[] getEndKey() { 116 return endKey; 117 } 118 119 /** 120 * Set end key of this partition, only if the input endKey is greater than 121 * the current end key. 122 */ 123 public void setEndKey(final byte[] endKey) { 124 if ((this.endKey == null) || (Bytes.compareTo(endKey, this.endKey) > 0)) { 125 this.endKey = endKey; 126 } 127 } 128 } 129 130 /** 131 * The partition id that consists of start key and date of the mob file name. 132 */ 133 public static class CompactionPartitionId { 134 private String startKey; 135 private String date; 136 private String latestDate; 137 private long threshold; 138 139 public CompactionPartitionId() { 140 // initialize these fields to empty string 141 this.startKey = ""; 142 this.date = ""; 143 this.latestDate = ""; 144 this.threshold = 0; 145 } 146 147 public CompactionPartitionId(String startKey, String date) { 148 if (startKey == null || date == null) { 149 throw new IllegalArgumentException("Neither of start key and date could be null"); 150 } 151 this.startKey = startKey; 152 this.date = date; 153 this.latestDate = ""; 154 this.threshold = 0; 155 } 156 157 public void setThreshold (final long threshold) { 158 this.threshold = threshold; 159 } 160 161 public long getThreshold () { 162 return this.threshold; 163 } 164 165 public String getStartKey() { 166 return this.startKey; 167 } 168 169 public void setStartKey(final String startKey) { 170 this.startKey = startKey; 171 } 172 173 public String getDate() { 174 return this.date; 175 } 176 177 public void setDate(final String date) { 178 this.date = date; 179 } 180 181 public String getLatestDate () { return this.latestDate; } 182 183 public void updateLatestDate(final String latestDate) { 184 if (this.latestDate.compareTo(latestDate) < 0) { 185 this.latestDate = latestDate; 186 } 187 } 188 189 @Override 190 public int hashCode() { 191 int result = 17; 192 result = 31 * result + startKey.hashCode(); 193 result = 31 * result + date.hashCode(); 194 return result; 195 } 196 197 @Override 198 public boolean equals(Object obj) { 199 if (this == obj) { 200 return true; 201 } 202 if (!(obj instanceof CompactionPartitionId)) { 203 return false; 204 } 205 CompactionPartitionId another = (CompactionPartitionId) obj; 206 if (!this.startKey.equals(another.startKey)) { 207 return false; 208 } 209 if (!this.date.equals(another.date)) { 210 return false; 211 } 212 return true; 213 } 214 215 @Override 216 public String toString() { 217 return new StringBuilder(startKey).append(date).toString(); 218 } 219 } 220 221 /** 222 * The delete file partition in the mob compaction. 223 * The delete partition is defined as [startKey, endKey] pair. 224 * The mob delete files that have the same start key and end key belong to 225 * the same partition. 226 */ 227 protected static class CompactionDelPartition { 228 private List<Path> delFiles = new ArrayList<Path>(); 229 private List<HStoreFile> storeFiles = new ArrayList<>(); 230 private CompactionDelPartitionId id; 231 232 public CompactionDelPartition(CompactionDelPartitionId id) { 233 this.id = id; 234 } 235 236 public CompactionDelPartitionId getId() { 237 return this.id; 238 } 239 240 void addDelFile(FileStatus file) { 241 delFiles.add(file.getPath()); 242 } 243 public void addStoreFile(HStoreFile file) { 244 storeFiles.add(file); 245 } 246 247 public List<HStoreFile> getStoreFiles() { 248 return storeFiles; 249 } 250 251 List<Path> listDelFiles() { 252 return Collections.unmodifiableList(delFiles); 253 } 254 255 void addDelFileList(final Collection<Path> list) { 256 delFiles.addAll(list); 257 } 258 259 int getDelFileCount () { 260 return delFiles.size(); 261 } 262 263 void cleanDelFiles() { 264 delFiles.clear(); 265 } 266 } 267 268 /** 269 * The delete partition id that consists of start key and end key 270 */ 271 public static class CompactionDelPartitionId implements Comparable<CompactionDelPartitionId> { 272 private byte[] startKey; 273 private byte[] endKey; 274 275 public CompactionDelPartitionId() { 276 } 277 278 public CompactionDelPartitionId(final byte[] startKey, final byte[] endKey) { 279 this.startKey = startKey; 280 this.endKey = endKey; 281 } 282 283 public byte[] getStartKey() { 284 return this.startKey; 285 } 286 public void setStartKey(final byte[] startKey) { 287 this.startKey = startKey; 288 } 289 290 public byte[] getEndKey() { 291 return this.endKey; 292 } 293 public void setEndKey(final byte[] endKey) { 294 this.endKey = endKey; 295 } 296 297 @Override 298 public int compareTo(CompactionDelPartitionId o) { 299 /* 300 * 1). Compare the start key, if the k1 < k2, then k1 is less 301 * 2). If start Key is same, check endKey, k1 < k2, k1 is less 302 * If both are same, then they are equal. 303 */ 304 int result = Bytes.compareTo(this.startKey, o.getStartKey()); 305 if (result != 0) { 306 return result; 307 } 308 309 return Bytes.compareTo(this.endKey, o.getEndKey()); 310 } 311 312 @Override 313 public int hashCode() { 314 int result = 17; 315 result = 31 * result + java.util.Arrays.hashCode(startKey); 316 result = 31 * result + java.util.Arrays.hashCode(endKey); 317 return result; 318 } 319 320 @Override 321 public boolean equals(Object obj) { 322 if (this == obj) { 323 return true; 324 } 325 if (!(obj instanceof CompactionDelPartitionId)) { 326 return false; 327 } 328 CompactionDelPartitionId another = (CompactionDelPartitionId) obj; 329 330 return (this.compareTo(another) == 0); 331 } 332 } 333}