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;
020
021import org.apache.yetus.audience.InterfaceAudience;
022import org.apache.hadoop.hbase.util.MD5Hash;
023
024/**
025 * The mob file name.
026 * It consists of a md5 of a start key, a date, uuid and encoded region name.
027 * It looks like md5(start) + date + uuid+ "_" + encoded region name.
028 * <ol>
029 * <li>characters 0-31: md5 hex string of a start key. Since the length of the start key is not
030 * fixed, have to use the md5 instead which has a fix length.</li>
031 * <li>characters 32-39: a string of a date with format yyyymmdd. The date is the latest timestamp
032 * of cells in this file</li>
033 * <li>the remaining characters: the uuid.</li>
034 * </ol>
035 * Using md5 hex string of start key as the prefix of file name makes files with the same start
036 * key unique, they're different from the ones with other start keys
037 * The cells come from different regions might be in the same mob file by region split,
038 * this is allowed.
039 * Has the latest timestamp of cells in the file name in order to clean the expired mob files by
040 * TTL easily. If this timestamp is older than the TTL, it's regarded as expired.
041 */
042@InterfaceAudience.Private
043public final class MobFileName{
044  private final String date;
045  private final String startKey;
046  private final String uuid;
047  private final String fileName;
048  // Name of a region this MOB file belongs to
049  private final String regionName;
050
051  private static final int STARTKEY_END_INDEX = 32;
052  private static final int DATE_END_INDEX = 40;
053  private static final int UUID_END_INDEX = 72;
054  public static final String REGION_SEP = "_";
055
056  /**
057   * @param startKey
058   *          The start key.
059   * @param date
060   *          The string of the latest timestamp of cells in this file, the format is yyyymmdd.
061   * @param uuid
062   *          The uuid
063   * @param regionName name of a region, where this file was created during flush or compaction.
064   */
065  private MobFileName(byte[] startKey, String date, String uuid, String regionName) {
066    this.startKey = MD5Hash.getMD5AsHex(startKey, 0, startKey.length);
067    this.uuid = uuid;
068    this.date = date;
069    this.regionName = regionName;
070    this.fileName = this.startKey + this.date + this.uuid + REGION_SEP + this.regionName;
071  }
072
073  /**
074   * @param startKey
075   *          The md5 hex string of the start key.
076   * @param date
077   *          The string of the latest timestamp of cells in this file, the format is yyyymmdd.
078   * @param uuid
079   *          The uuid
080   * @param regionName name of a region, where this file was created during flush or compaction.
081   */
082  private MobFileName(String startKey, String date, String uuid, String regionName) {
083    this.startKey = startKey;
084    this.uuid = uuid;
085    this.date = date;
086    this.regionName = regionName;
087    this.fileName = this.startKey + this.date + this.uuid + REGION_SEP + this.regionName;
088  }
089
090  /**
091   * Creates an instance of MobFileName
092   *
093   * @param startKey
094   *          The md5 hex string of the start key.
095   * @param date
096   *          The string of the latest timestamp of cells in this file, the format is yyyymmdd.
097   * @param uuid The uuid.
098   * @param regionName name of a region, where this file was created during flush or compaction.
099   * @return An instance of a MobFileName.
100   */
101  public static MobFileName create(byte[] startKey, String date, String uuid, String regionName) {
102    return new MobFileName(startKey, date, uuid, regionName);
103  }
104
105  /**
106   * Creates an instance of MobFileName
107   *
108   * @param startKey
109   *          The md5 hex string of the start key.
110   * @param date
111   *          The string of the latest timestamp of cells in this file, the format is yyyymmdd.
112   * @param uuid The uuid.
113   * @param regionName name of a region, where this file was created during flush or compaction.
114   * @return An instance of a MobFileName.
115   */
116  public static MobFileName create(String startKey, String date, String uuid, String regionName) {
117    return new MobFileName(startKey, date, uuid, regionName);
118  }
119
120  /**
121   * Creates an instance of MobFileName.
122   * @param fileName The string format of a file name.
123   * @return An instance of a MobFileName.
124   */
125  public static MobFileName create(String fileName) {
126    // The format of a file name is md5HexString(0-31bytes) + date(32-39bytes) + UUID
127    // + "_" + region
128    // The date format is yyyyMMdd
129    String startKey = fileName.substring(0, STARTKEY_END_INDEX);
130    String date = fileName.substring(STARTKEY_END_INDEX, DATE_END_INDEX);
131    String uuid = fileName.substring(DATE_END_INDEX, UUID_END_INDEX);
132    String regionName = fileName.substring(UUID_END_INDEX+1);
133    return new MobFileName(startKey, date, uuid, regionName);
134  }
135
136  public static boolean isOldMobFileName(String name) {
137    return name.indexOf(REGION_SEP) < 0;
138  }
139
140  /**
141   * get startKey from MobFileName.
142   * @param fileName file name.
143   * @return startKey
144   */
145  public static String getStartKeyFromName(final String fileName) {
146    return fileName.substring(0, STARTKEY_END_INDEX);
147  }
148
149  /**
150   * get date from MobFileName.
151   * @param fileName file name.
152   * @return date
153   */
154  public static String getDateFromName(final String fileName) {
155    return fileName.substring(STARTKEY_END_INDEX, DATE_END_INDEX);
156  }
157
158  /**
159   * Gets the hex string of the md5 for a start key.
160   * @return The hex string of the md5 for a start key.
161   */
162  public String getStartKey() {
163    return startKey;
164  }
165
166  /**
167   * Gets region name
168   * @return name of a region, where this file was created during flush or compaction.
169   */
170  public String getRegionName() {
171    return regionName;
172  }
173  /**
174   * Gets the date string. Its format is yyyymmdd.
175   * @return The date string.
176   */
177  public String getDate() {
178    return this.date;
179  }
180
181  @Override
182  public int hashCode() {
183    return fileName.hashCode();
184  }
185
186  @Override
187  public boolean equals(Object anObject) {
188    if (this == anObject) {
189      return true;
190    }
191    if (anObject instanceof MobFileName) {
192      MobFileName another = (MobFileName) anObject;
193      return this.getFileName().equals(another.getFileName());
194    }
195    return false;
196  }
197
198  /**
199   * Gets the file name.
200   * @return The file name.
201   */
202  public String getFileName() {
203    return this.fileName;
204  }
205}