/
FDBTransactionContext.java
183 lines (161 loc) · 5.62 KB
/
FDBTransactionContext.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
* FDBTransactionContext.java
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2015-2018 Apple Inc. and the FoundationDB project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.apple.foundationdb.record.provider.foundationdb;
import com.apple.foundationdb.annotation.API;
import com.apple.foundationdb.Transaction;
import com.apple.foundationdb.record.RecordCursor;
import com.apple.foundationdb.record.provider.common.StoreTimer;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
/**
* Wrapper class for an open FDB {@link Transaction}.
*
* @see FDBRecordContext
*/
@API(API.Status.STABLE)
public class FDBTransactionContext {
private final Executor executor;
@Nonnull
protected final FDBDatabase database;
@Nullable
protected Transaction transaction;
@Nullable
protected FDBStoreTimer timer;
protected FDBTransactionContext(@Nonnull FDBDatabase database, @Nonnull Transaction transaction, @Nullable FDBStoreTimer timer) {
this.database = database;
this.transaction = transaction;
this.executor = transaction.getExecutor();
this.timer = timer;
if (timer != null) {
timer.increment(FDBStoreTimer.Counts.OPEN_CONTEXT);
}
}
@Nonnull
public FDBDatabase getDatabase() {
return database;
}
@Nonnull
public Transaction ensureActive() {
return transaction;
}
@Nonnull
public Executor getExecutor() {
return executor;
}
@Nonnull
public CompletableFuture<Long> getApproximateTransactionSize() {
return transaction.getApproximateSize();
}
/**
* Get the FDB API version associated with this transaction. This is an internal
* method that should be used within the Record Layer to accommodate changes in
* underlying FDB behavior that are dictated by the API version.
*
* @return the transaction's associated FDB API version
* @see APIVersion
*/
@API(API.Status.INTERNAL)
public APIVersion getAPIVersion() {
return database.getAPIVersion();
}
/**
* Determine whether the API version of this transaction is at least as new as
* the provided API version. This is an internal method that should be used
* to gate features requiring certain FDB API versions for support from the database.
*
* @param apiVersion the FDB API version to compare against
* @return whether the transaction's API version is at least as new as the provided API version
* @see #getAPIVersion()
* @see APIVersion
*/
@API(API.Status.INTERNAL)
public boolean isAPIVersionAtLeast(@Nonnull APIVersion apiVersion) {
return getAPIVersion().isAtLeast(apiVersion);
}
@Nullable
public FDBStoreTimer getTimer() {
return timer;
}
public void setTimer(@Nullable FDBStoreTimer timer) {
this.timer = timer;
}
public <T> CompletableFuture<T> instrument(StoreTimer.Event event, CompletableFuture<T> future) {
if (timer != null) {
future = timer.instrument(event, future, getExecutor());
}
return future;
}
public <T> CompletableFuture<T> instrument(Set<StoreTimer.Event> event, CompletableFuture<T> future) {
if (timer != null) {
future = timer.instrument(event, future, getExecutor());
}
return future;
}
public <T> CompletableFuture<T> instrument(StoreTimer.Event event, CompletableFuture<T> future, long startTime) {
if (timer != null) {
future = timer.instrument(event, future, getExecutor(), startTime);
}
return future;
}
public <T> RecordCursor<T> instrument(StoreTimer.Event event, RecordCursor<T> inner) {
if (timer != null) {
inner = timer.instrument(event, inner);
}
return inner;
}
/**
* Record the amount of time an event took to run.
*
* @param event the event being recorded
* @param timeDelta the time the event took to complete
* @see StoreTimer#record(StoreTimer.Event, long) StoreTimer.record()
*/
public void record(@Nonnull StoreTimer.Event event, long timeDelta) {
if (timer != null) {
timer.record(event, timeDelta);
}
}
/**
* Record that an event occurred one time.
*
* @param count the event being recorded
* @see StoreTimer#increment(StoreTimer.Count) StoreTimer.increment()
*/
public void increment(@Nonnull StoreTimer.Count count) {
if (timer != null) {
timer.increment(count);
}
}
/**
* Record that an event occurred one or more times.
*
* @param count the event being recorded
* @param amount the amount to increment the event
* @see StoreTimer#increment(StoreTimer.Count, int) StoreTimer.increment()
*/
public void increment(@Nonnull StoreTimer.Count count, int amount) {
if (timer != null) {
timer.increment(count, amount);
}
}
}