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  package org.apache.hadoop.hbase.regionserver.wal;
20  
21  import org.apache.hadoop.classification.InterfaceAudience;
22  import org.htrace.Span;
23  
24  import com.lmax.disruptor.EventFactory;
25  
26  /**
27   * A 'truck' to carry a payload across the {@link FSHLog} ring buffer from Handler to WAL.
28   * Has EITHER a {@link FSWALEntry} for making an append OR it has a {@link SyncFuture} to
29   * represent a 'sync' invocation. Truck instances are reused by the disruptor when it gets
30   * around to it so their payload references must be discarded on consumption to release them
31   * to GC.
32   */
33  @InterfaceAudience.Private
34  class RingBufferTruck {
35    /**
36     * Either this syncFuture is set or entry is set, but not both.
37     */
38    private SyncFuture syncFuture;
39    private FSWALEntry entry;
40  
41    /**
42     * The tracing span for this entry.  Can be null.
43     * TODO: Fix up tracing.
44     */
45    private Span span;
46  
47    /**
48     * Load the truck with a {@link FSWALEntry} and associated {@link Span}.
49     */
50    void loadPayload(final FSWALEntry entry, final Span span) {
51      this.entry = entry;
52      this.span = span;
53      this.syncFuture = null;
54    }
55  
56    /**
57     * Load the truck with a {@link SyncFuture}.
58     */
59    void loadPayload(final SyncFuture syncFuture) {
60      this.syncFuture = syncFuture;
61      this.entry = null;
62      this.span = null;
63    }
64  
65    /**
66     * return {@code true} when this truck is carrying a {@link FSWALEntry},
67     * {@code false} otherwise.
68     */
69    boolean hasFSWALEntryPayload() {
70      return this.entry != null;
71    }
72  
73    /**
74     * return {@code true} when this truck is carrying a {@link SyncFuture},
75     * {@code false} otherwise.
76     */
77    boolean hasSyncFuturePayload() {
78      return this.syncFuture != null;
79    }
80  
81    /**
82     * Unload the truck of its {@link FSWALEntry} payload. The internal refernce is released.
83     */
84    FSWALEntry unloadFSWALEntryPayload() {
85      FSWALEntry ret = this.entry;
86      this.entry = null;
87      return ret;
88    }
89  
90    /**
91     * Unload the truck of its {@link SyncFuture} payload. The internal refernce is released.
92     */
93    SyncFuture unloadSyncFuturePayload() {
94      SyncFuture ret = this.syncFuture;
95      this.syncFuture = null;
96      return ret;
97    }
98  
99    /**
100    * Unload the truck of its {@link Span} payload. The internal reference is released.
101    */
102   Span unloadSpanPayload() {
103     Span ret = this.span;
104     this.span = null;
105     return ret;
106   }
107 
108   /**
109    * Factory for making a bunch of these.  Needed by the ringbuffer/disruptor.
110    */
111   final static EventFactory<RingBufferTruck> EVENT_FACTORY = new EventFactory<RingBufferTruck>() {
112     public RingBufferTruck newInstance() {
113       return new RingBufferTruck();
114     }
115   };
116 }