View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.regionserver.wal;
21  
22  import java.io.IOException;
23  
24  import org.apache.hadoop.classification.InterfaceAudience;
25  import org.apache.hadoop.conf.Configuration;
26  import org.apache.hadoop.fs.FSDataInputStream;
27  import org.apache.hadoop.fs.FileSystem;
28  import org.apache.hadoop.fs.Path;
29  import org.apache.hadoop.hbase.protobuf.generated.WALProtos.WALTrailer;
30  import org.apache.hadoop.hbase.util.FSUtils;
31  
32  @InterfaceAudience.Private
33  public abstract class ReaderBase implements HLog.Reader {
34    protected Configuration conf;
35    protected FileSystem fs;
36    protected Path path;
37    protected long edit = 0;
38    protected long fileLength;
39    protected WALTrailer trailer;
40    // maximum size of the wal Trailer in bytes. If a user writes/reads a trailer with size larger
41    // than this size, it is written/read respectively, with a WARN message in the log.
42    protected int trailerWarnSize;
43    /**
44     * Compression context to use reading.  Can be null if no compression.
45     */
46    protected CompressionContext compressionContext = null;
47    protected boolean emptyCompressionContext = true;
48  
49    /**
50     * Default constructor.
51     */
52    public ReaderBase() {
53    }
54  
55    @Override
56    public void init(FileSystem fs, Path path, Configuration conf, FSDataInputStream stream)
57        throws IOException {
58      this.conf = conf;
59      this.path = path;
60      this.fs = fs;
61      this.fileLength = this.fs.getFileStatus(path).getLen();
62      this.trailerWarnSize = conf.getInt(HLog.WAL_TRAILER_WARN_SIZE,
63        HLog.DEFAULT_WAL_TRAILER_WARN_SIZE);
64      initReader(stream);
65  
66      boolean compression = hasCompression();
67      if (compression) {
68        // If compression is enabled, new dictionaries are created here.
69        try {
70          if (compressionContext == null) {
71            compressionContext = new CompressionContext(LRUDictionary.class,
72                FSUtils.isRecoveredEdits(path));
73          } else {
74            compressionContext.clear();
75          }
76        } catch (Exception e) {
77          throw new IOException("Failed to initialize CompressionContext", e);
78        }
79      }
80      initAfterCompression();
81    }
82  
83    @Override
84    public HLog.Entry next() throws IOException {
85      return next(null);
86    }
87  
88    @Override
89    public HLog.Entry next(HLog.Entry reuse) throws IOException {
90      HLog.Entry e = reuse;
91      if (e == null) {
92        e = new HLog.Entry(new HLogKey(), new WALEdit());
93      }
94      if (compressionContext != null) {
95        e.setCompressionContext(compressionContext);
96      }
97  
98      boolean hasEntry = readNext(e);
99      edit++;
100     if (compressionContext != null && emptyCompressionContext) {
101       emptyCompressionContext = false;
102     }
103     return hasEntry ? e : null;
104   }
105 
106 
107   @Override
108   public void seek(long pos) throws IOException {
109     if (compressionContext != null && emptyCompressionContext) {
110       while (next() != null) {
111         if (getPosition() == pos) {
112           emptyCompressionContext = false;
113           break;
114         }
115       }
116     }
117     seekOnFs(pos);
118   }
119 
120   /**
121    * Initializes the log reader with a particular stream (may be null).
122    * Reader assumes ownership of the stream if not null and may use it. Called once.
123    */
124   protected abstract void initReader(FSDataInputStream stream) throws IOException;
125 
126   /**
127    * Initializes the compression after the shared stuff has been initialized. Called once.
128    */
129   protected abstract void initAfterCompression() throws IOException;
130   /**
131    * @return Whether compression is enabled for this log.
132    */
133   protected abstract boolean hasCompression();
134 
135   /**
136    * Read next entry.
137    * @param e The entry to read into.
138    * @return Whether there was anything to read.
139    */
140   protected abstract boolean readNext(HLog.Entry e) throws IOException;
141 
142   /**
143    * Performs a filesystem-level seek to a certain position in an underlying file.
144    */
145   protected abstract void seekOnFs(long pos) throws IOException;
146 
147   @Override
148   public WALTrailer getWALTrailer() {
149     return null;
150   }
151 }