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.hbase.classification.InterfaceAudience;
22 import org.apache.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 }