View Javadoc

1   /**
2    * Copyright 2007 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.regionserver.wal;
21  
22  import java.io.DataInput;
23  import java.io.DataOutput;
24  import java.io.EOFException;
25  import java.io.IOException;
26  
27  import org.apache.hadoop.hbase.HConstants;
28  import org.apache.hadoop.hbase.util.Bytes;
29  import org.apache.hadoop.io.WritableComparable;
30  
31  /**
32   * A Key for an entry in the change log.
33   *
34   * The log intermingles edits to many tables and rows, so each log entry
35   * identifies the appropriate table and row.  Within a table and row, they're
36   * also sorted.
37   *
38   * <p>Some Transactional edits (START, COMMIT, ABORT) will not have an
39   * associated row.
40   */
41  public class HLogKey implements WritableComparable<HLogKey> {
42    private byte [] regionName;
43    private byte [] tablename;
44    private long logSeqNum;
45    // Time at which this edit was written.
46    private long writeTime;
47  
48    private byte clusterId;
49    private int scope;
50  
51    /** Writable Consructor -- Do not use. */
52    public HLogKey() {
53      this(null, null, 0L, HConstants.LATEST_TIMESTAMP);
54    }
55  
56    /**
57     * Create the log key!
58     * We maintain the tablename mainly for debugging purposes.
59     * A regionName is always a sub-table object.
60     *
61     * @param regionName  - name of region
62     * @param tablename   - name of table
63     * @param logSeqNum   - log sequence number
64     * @param now Time at which this edit was written.
65     */
66    public HLogKey(final byte [] regionName, final byte [] tablename,
67        long logSeqNum, final long now) {
68      this.regionName = regionName;
69      this.tablename = tablename;
70      this.logSeqNum = logSeqNum;
71      this.writeTime = now;
72      this.clusterId = HConstants.DEFAULT_CLUSTER_ID;
73      this.scope = HConstants.REPLICATION_SCOPE_LOCAL;
74    }
75  
76    //////////////////////////////////////////////////////////////////////////////
77    // A bunch of accessors
78    //////////////////////////////////////////////////////////////////////////////
79  
80    /** @return region name */
81    public byte [] getRegionName() {
82      return regionName;
83    }
84  
85    /** @return table name */
86    public byte [] getTablename() {
87      return tablename;
88    }
89  
90    /** @return log sequence number */
91    public long getLogSeqNum() {
92      return logSeqNum;
93    }
94  
95    void setLogSeqNum(long logSeqNum) {
96      this.logSeqNum = logSeqNum;
97    }
98  
99    /**
100    * @return the write time
101    */
102   public long getWriteTime() {
103     return this.writeTime;
104   }
105 
106   /**
107    * Get the id of the original cluster
108    * @return
109    */
110   public byte getClusterId() {
111     return clusterId;
112   }
113 
114   /**
115    * Set the cluster id of this key
116    * @param clusterId
117    */
118   public void setClusterId(byte clusterId) {
119     this.clusterId = clusterId;
120   }
121 
122   /**
123    * Get the replication scope of this key
124    * @return replication scope
125    */
126   public int getScope() {
127     return this.scope;
128   }
129 
130   /**
131    * Set the replication scope of this key
132    * @param scope The new scope
133    */
134   public void setScope(int scope) {
135     this.scope = scope;
136   }
137 
138   @Override
139   public String toString() {
140     return Bytes.toString(tablename) + "/" + Bytes.toString(regionName) + "/" +
141       logSeqNum;
142   }
143 
144   @Override
145   public boolean equals(Object obj) {
146     if (this == obj) {
147       return true;
148     }
149     if (obj == null || getClass() != obj.getClass()) {
150       return false;
151     }
152     return compareTo((HLogKey)obj) == 0;
153   }
154 
155   @Override
156   public int hashCode() {
157     int result = Bytes.hashCode(this.regionName);
158     result ^= this.logSeqNum;
159     result ^= this.writeTime;
160     result ^= this.clusterId;
161     result ^= this.scope;
162     return result;
163   }
164 
165   public int compareTo(HLogKey o) {
166     int result = Bytes.compareTo(this.regionName, o.regionName);
167     if (result == 0) {
168       if (this.logSeqNum < o.logSeqNum) {
169         result = -1;
170       } else if (this.logSeqNum > o.logSeqNum) {
171         result = 1;
172       }
173       if (result == 0) {
174         if (this.writeTime < o.writeTime) {
175           result = -1;
176         } else if (this.writeTime > o.writeTime) {
177           return 1;
178         }
179       }
180     }
181     return result;
182   }
183 
184   public void write(DataOutput out) throws IOException {
185     Bytes.writeByteArray(out, this.regionName);
186     Bytes.writeByteArray(out, this.tablename);
187     out.writeLong(this.logSeqNum);
188     out.writeLong(this.writeTime);
189     out.writeByte(this.clusterId);
190     out.writeInt(this.scope);
191   }
192 
193   public void readFields(DataInput in) throws IOException {
194     this.regionName = Bytes.readByteArray(in);
195     this.tablename = Bytes.readByteArray(in);
196     this.logSeqNum = in.readLong();
197     this.writeTime = in.readLong();
198     try {
199       this.clusterId = in.readByte();
200       this.scope = in.readInt();
201     } catch(EOFException e) {
202       // Means it's an old key, just continue
203     }
204   }
205 
206 }