View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.regionserver.wal;
19  
20  
21  import java.io.IOException;
22  import java.util.List;
23  import java.util.concurrent.atomic.AtomicLong;
24  import org.apache.hadoop.hbase.classification.InterfaceAudience;
25  import org.apache.hadoop.hbase.Cell;
26  import org.apache.hadoop.hbase.CellUtil;
27  import org.apache.hadoop.hbase.HRegionInfo;
28  import org.apache.hadoop.hbase.HTableDescriptor;
29  
30  import org.apache.hadoop.hbase.wal.WAL.Entry;
31  import org.apache.hadoop.hbase.wal.WALKey;
32  
33  /**
34   * A WAL Entry for {@link FSHLog} implementation.  Immutable.
35   * A subclass of {@link Entry} that carries extra info across the ring buffer such as
36   * region sequence id (we want to use this later, just before we write the WAL to ensure region
37   * edits maintain order).  The extra info added here is not 'serialized' as part of the WALEdit
38   * hence marked 'transient' to underline this fact.  It also adds mechanism so we can wait on
39   * the assign of the region sequence id.  See {@link #stampRegionSequenceId()}.
40   */
41  @InterfaceAudience.Private
42  class FSWALEntry extends Entry {
43    // The below data members are denoted 'transient' just to highlight these are not persisted;
44    // they are only in memory and held here while passing over the ring buffer.
45    private final transient long sequence;
46    private final transient AtomicLong regionSequenceIdReference;
47    private final transient boolean inMemstore;
48    private final transient HTableDescriptor htd;
49    private final transient HRegionInfo hri;
50    private final transient List<Cell> memstoreCells;
51  
52    FSWALEntry(final long sequence, final WALKey key, final WALEdit edit,
53        final AtomicLong referenceToRegionSequenceId, final boolean inMemstore,
54        final HTableDescriptor htd, final HRegionInfo hri, List<Cell> memstoreCells) {
55      super(key, edit);
56      this.regionSequenceIdReference = referenceToRegionSequenceId;
57      this.inMemstore = inMemstore;
58      this.htd = htd;
59      this.hri = hri;
60      this.sequence = sequence;
61      this.memstoreCells = memstoreCells;
62    }
63  
64    public String toString() {
65      return "sequence=" + this.sequence + ", " + super.toString();
66    };
67  
68    boolean isInMemstore() {
69      return this.inMemstore;
70    }
71  
72    HTableDescriptor getHTableDescriptor() {
73      return this.htd;
74    }
75  
76    HRegionInfo getHRegionInfo() {
77      return this.hri;
78    }
79  
80    /**
81     * @return The sequence on the ring buffer when this edit was added.
82     */
83    long getSequence() {
84      return this.sequence;
85    }
86  
87    /**
88     * Stamp this edit with a region edit/sequence id.
89     * Call when safe to do so: i.e. the context is such that the increment on the passed in
90     * {@link #regionSequenceIdReference} is guaranteed aligned w/ how appends are going into the
91     * WAL.  This method works with {@link #getRegionSequenceId()}.  It will block waiting on this
92     * method to be called.
93     * @return The region edit/sequence id we set for this edit.
94     * @throws IOException
95     * @see #getRegionSequenceId()
96     */
97    long stampRegionSequenceId() throws IOException {
98      long regionSequenceId = this.regionSequenceIdReference.incrementAndGet();
99      if (!this.getEdit().isReplay() && memstoreCells != null && !memstoreCells.isEmpty()) {
100       for (Cell cell : this.memstoreCells) {
101         CellUtil.setSequenceId(cell, regionSequenceId);
102       }
103     }
104     WALKey key = getKey();
105     key.setLogSeqNum(regionSequenceId);
106     return regionSequenceId;
107   }
108 }