001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.mob;
019
020import org.apache.hadoop.hbase.util.MD5Hash;
021import org.apache.yetus.audience.InterfaceAudience;
022
023/**
024 * The mob file name. It consists of a md5 of a start key, a date, uuid and encoded region name. It
025 * looks like md5(start) + date + uuid+ "_" + encoded region name.
026 * <ol>
027 * <li>characters 0-31: md5 hex string of a start key. Since the length of the start key is not
028 * fixed, have to use the md5 instead which has a fix length.</li>
029 * <li>characters 32-39: a string of a date with format yyyymmdd. The date is the latest timestamp
030 * of cells in this file</li>
031 * <li>the remaining characters: the uuid.</li>
032 * </ol>
033 * Using md5 hex string of start key as the prefix of file name makes files with the same start key
034 * unique, they're different from the ones with other start keys The cells come from different
035 * regions might be in the same mob file by region split, this is allowed. Has the latest timestamp
036 * of cells in the file name in order to clean the expired mob files by TTL easily. If this
037 * timestamp is older than the TTL, it's regarded as expired.
038 */
039@InterfaceAudience.Private
040public final class MobFileName {
041  private final String date;
042  private final String startKey;
043  private final String uuid;
044  private final String fileName;
045  // Name of a region this MOB file belongs to
046  private final String regionName;
047
048  private static final int STARTKEY_END_INDEX = 32;
049  private static final int DATE_END_INDEX = 40;
050  private static final int UUID_END_INDEX = 72;
051  public static final String REGION_SEP = "_";
052
053  /**
054   * Creates an instance of MobFileName
055   * @param startKey   The start key.
056   * @param date       The string of the latest timestamp of cells in this file, the format is
057   *                   yyyymmdd.
058   * @param uuid       The uuid
059   * @param regionName name of a region, where this file was created during flush or compaction.
060   */
061  private MobFileName(byte[] startKey, String date, String uuid, String regionName) {
062    this.startKey = MD5Hash.getMD5AsHex(startKey, 0, startKey.length);
063    this.uuid = uuid;
064    this.date = date;
065    this.regionName = regionName;
066    this.fileName = this.startKey + this.date + this.uuid + REGION_SEP + this.regionName;
067  }
068
069  /**
070   * Creates an instance of MobFileName
071   * @param startKey   The md5 hex string of the start key.
072   * @param date       The string of the latest timestamp of cells in this file, the format is
073   *                   yyyymmdd.
074   * @param uuid       The uuid
075   * @param regionName name of a region, where this file was created during flush or compaction.
076   */
077  private MobFileName(String startKey, String date, String uuid, String regionName) {
078    this.startKey = startKey;
079    this.uuid = uuid;
080    this.date = date;
081    this.regionName = regionName;
082    this.fileName = this.startKey + this.date + this.uuid + REGION_SEP + this.regionName;
083  }
084
085  /**
086   * Creates an instance of MobFileName
087   * @param startKey   The md5 hex string of the start key.
088   * @param date       The string of the latest timestamp of cells in this file, the format is
089   *                   yyyymmdd.
090   * @param uuid       The uuid.
091   * @param regionName name of a region, where this file was created during flush or compaction.
092   * @return An instance of a MobFileName.
093   */
094  public static MobFileName create(byte[] startKey, String date, String uuid, String regionName) {
095    return new MobFileName(startKey, date, uuid, regionName);
096  }
097
098  /**
099   * Creates an instance of MobFileName
100   * @param startKey   The md5 hex string of the start key.
101   * @param date       The string of the latest timestamp of cells in this file, the format is
102   *                   yyyymmdd.
103   * @param uuid       The uuid.
104   * @param regionName name of a region, where this file was created during flush or compaction.
105   * @return An instance of a MobFileName.
106   */
107  public static MobFileName create(String startKey, String date, String uuid, String regionName) {
108    return new MobFileName(startKey, date, uuid, regionName);
109  }
110
111  /**
112   * Creates an instance of MobFileName.
113   * @param fileName The string format of a file name.
114   * @return An instance of a MobFileName.
115   */
116  public static MobFileName create(String fileName) {
117    // The format of a file name is md5HexString(0-31bytes) + date(32-39bytes) + UUID
118    // + "_" + region
119    // The date format is yyyyMMdd
120    String startKey = fileName.substring(0, STARTKEY_END_INDEX);
121    String date = fileName.substring(STARTKEY_END_INDEX, DATE_END_INDEX);
122    String uuid = fileName.substring(DATE_END_INDEX, UUID_END_INDEX);
123    String regionName = fileName.substring(UUID_END_INDEX + 1);
124    return new MobFileName(startKey, date, uuid, regionName);
125  }
126
127  public static boolean isOldMobFileName(String name) {
128    return name.indexOf(REGION_SEP) < 0;
129  }
130
131  /**
132   * get startKey from MobFileName.
133   * @param fileName file name.
134   */
135  public static String getStartKeyFromName(final String fileName) {
136    return fileName.substring(0, STARTKEY_END_INDEX);
137  }
138
139  /**
140   * get date from MobFileName.
141   * @param fileName file name.
142   */
143  public static String getDateFromName(final String fileName) {
144    return fileName.substring(STARTKEY_END_INDEX, DATE_END_INDEX);
145  }
146
147  /**
148   * Gets the hex string of the md5 for a start key.
149   * @return The hex string of the md5 for a start key.
150   */
151  public String getStartKey() {
152    return startKey;
153  }
154
155  /**
156   * Gets region name
157   * @return name of a region, where this file was created during flush or compaction.
158   */
159  public String getRegionName() {
160    return regionName;
161  }
162
163  /**
164   * Gets the date string. Its format is yyyymmdd.
165   * @return The date string.
166   */
167  public String getDate() {
168    return this.date;
169  }
170
171  @Override
172  public int hashCode() {
173    return fileName.hashCode();
174  }
175
176  @Override
177  public boolean equals(Object anObject) {
178    if (this == anObject) {
179      return true;
180    }
181    if (anObject instanceof MobFileName) {
182      MobFileName another = (MobFileName) anObject;
183      return this.getFileName().equals(another.getFileName());
184    }
185    return false;
186  }
187
188  /**
189   * Gets the file name.
190   * @return The file name.
191   */
192  public String getFileName() {
193    return this.fileName;
194  }
195}