9
9
import com .scalar .db .api .Get ;
10
10
import com .scalar .db .api .Operation ;
11
11
import com .scalar .db .api .Put ;
12
+ import com .scalar .db .api .PutBuilder ;
12
13
import com .scalar .db .api .Result ;
13
14
import com .scalar .db .api .Scan ;
14
15
import com .scalar .db .api .ScanAll ;
29
30
import java .util .Comparator ;
30
31
import java .util .HashMap ;
31
32
import java .util .HashSet ;
33
+ import java .util .LinkedHashMap ;
32
34
import java .util .List ;
33
35
import java .util .Map ;
34
36
import java .util .Map .Entry ;
@@ -112,56 +114,105 @@ Isolation getIsolation() {
112
114
113
115
// Although this class is not thread-safe, this method is actually thread-safe because the readSet
114
116
// is a concurrent map
115
- public void put (Key key , Optional <TransactionResult > result ) {
117
+ public void putIntoReadSet (Key key , Optional <TransactionResult > result ) {
116
118
readSet .put (key , result );
117
119
}
118
120
119
121
// Although this class is not thread-safe, this method is actually thread-safe because the getSet
120
122
// is a concurrent map
121
- public void put (Get get , Optional <TransactionResult > result ) {
123
+ public void putIntoGetSet (Get get , Optional <TransactionResult > result ) {
122
124
getSet .put (get , result );
123
125
}
124
126
125
- public void put (Scan scan , Map <Key , TransactionResult > results ) {
127
+ public void putIntoScanSet (Scan scan , Map <Key , TransactionResult > results ) {
126
128
scanSet .put (scan , results );
127
129
}
128
130
129
- public void put (Key key , Put put ) {
131
+ public void putIntoWriteSet (Key key , Put put ) {
130
132
if (deleteSet .containsKey (key )) {
131
133
throw new IllegalArgumentException (
132
134
CoreError .CONSENSUS_COMMIT_WRITING_ALREADY_DELETED_DATA_NOT_ALLOWED .buildMessage ());
133
135
}
134
136
if (writeSet .containsKey (key )) {
137
+ if (put .isInsertModeEnabled ()) {
138
+ throw new IllegalArgumentException (
139
+ CoreError .CONSENSUS_COMMIT_INSERTING_ALREADY_WRITTEN_DATA_NOT_ALLOWED .buildMessage ());
140
+ }
141
+
135
142
// merge the previous put in the write set and the new put
136
143
Put originalPut = writeSet .get (key );
137
- put .getColumns ().values ().forEach (originalPut ::withValue );
144
+ PutBuilder .BuildableFromExisting putBuilder = Put .newBuilder (originalPut );
145
+ put .getColumns ().values ().forEach (putBuilder ::value );
146
+
147
+ // If the implicit pre-read is enabled for the new put, it should also be enabled for the
148
+ // merged put. However, if the previous put is in insert mode, this doesn’t apply. This is
149
+ // because, in insert mode, the read set is not used during the preparation phase. Therefore,
150
+ // we only need to enable the implicit pre-read if the previous put is not in insert mode
151
+ if (put .isImplicitPreReadEnabled () && !originalPut .isInsertModeEnabled ()) {
152
+ putBuilder .enableImplicitPreRead ();
153
+ }
154
+
155
+ writeSet .put (key , putBuilder .build ());
138
156
} else {
139
157
writeSet .put (key , put );
140
158
}
141
159
}
142
160
143
- public void put (Key key , Delete delete ) {
144
- writeSet .remove (key );
161
+ public void putIntoDeleteSet (Key key , Delete delete ) {
162
+ Put put = writeSet .get (key );
163
+ if (put != null ) {
164
+ if (put .isInsertModeEnabled ()) {
165
+ throw new IllegalArgumentException (
166
+ CoreError .CONSENSUS_COMMIT_DELETING_ALREADY_INSERTED_DATA_NOT_ALLOWED .buildMessage ());
167
+ }
168
+
169
+ writeSet .remove (key );
170
+ }
171
+
145
172
deleteSet .put (key , delete );
146
173
}
147
174
175
+ public List <Put > getPutsInWriteSet () {
176
+ return new ArrayList <>(writeSet .values ());
177
+ }
178
+
179
+ public List <Delete > getDeletesInDeleteSet () {
180
+ return new ArrayList <>(deleteSet .values ());
181
+ }
182
+
148
183
public boolean containsKeyInReadSet (Key key ) {
149
184
return readSet .containsKey (key );
150
185
}
151
186
152
- public Optional < TransactionResult > getFromReadSet ( Key key ) {
153
- return readSet . getOrDefault ( key , Optional . empty () );
187
+ public boolean containsKeyInGetSet ( Get get ) {
188
+ return getSet . containsKey ( get );
154
189
}
155
190
156
- public List <Put > getPutsInWriteSet () {
157
- return new ArrayList <>(writeSet .values ());
191
+ public Optional <TransactionResult > getResult (Key key ) throws CrudException {
192
+ Optional <TransactionResult > result = readSet .getOrDefault (key , Optional .empty ());
193
+ return mergeResult (key , result );
158
194
}
159
195
160
- public List <Delete > getDeletesInDeleteSet () {
161
- return new ArrayList <>(deleteSet .values ());
196
+ public Optional <TransactionResult > getResult (Key key , Get get ) throws CrudException {
197
+ Optional <TransactionResult > result = getSet .getOrDefault (get , Optional .empty ());
198
+ return mergeResult (key , result , get .getConjunctions ());
199
+ }
200
+
201
+ public Optional <Map <Snapshot .Key , TransactionResult >> getResults (Scan scan ) throws CrudException {
202
+ if (!scanSet .containsKey (scan )) {
203
+ return Optional .empty ();
204
+ }
205
+
206
+ Map <Key , TransactionResult > results = new LinkedHashMap <>();
207
+ for (Entry <Snapshot .Key , TransactionResult > entry : scanSet .get (scan ).entrySet ()) {
208
+ mergeResult (entry .getKey (), Optional .of (entry .getValue ()))
209
+ .ifPresent (result -> results .put (entry .getKey (), result ));
210
+ }
211
+
212
+ return Optional .of (results );
162
213
}
163
214
164
- public Optional <TransactionResult > mergeResult (Key key , Optional <TransactionResult > result )
215
+ private Optional <TransactionResult > mergeResult (Key key , Optional <TransactionResult > result )
165
216
throws CrudException {
166
217
if (deleteSet .containsKey (key )) {
167
218
return Optional .empty ();
@@ -175,7 +226,7 @@ public Optional<TransactionResult> mergeResult(Key key, Optional<TransactionResu
175
226
}
176
227
}
177
228
178
- public Optional <TransactionResult > mergeResult (
229
+ private Optional <TransactionResult > mergeResult (
179
230
Key key , Optional <TransactionResult > result , Set <Conjunction > conjunctions )
180
231
throws CrudException {
181
232
return mergeResult (key , result )
@@ -204,32 +255,6 @@ private TableMetadata getTableMetadata(Key key) throws CrudException {
204
255
}
205
256
}
206
257
207
- private TableMetadata getTableMetadata (Scan scan ) throws ExecutionException {
208
- TransactionTableMetadata metadata = tableMetadataManager .getTransactionTableMetadata (scan );
209
- if (metadata == null ) {
210
- throw new IllegalArgumentException (
211
- CoreError .TABLE_NOT_FOUND .buildMessage (scan .forFullTableName ().get ()));
212
- }
213
- return metadata .getTableMetadata ();
214
- }
215
-
216
- public boolean containsKeyInGetSet (Get get ) {
217
- return getSet .containsKey (get );
218
- }
219
-
220
- public Optional <TransactionResult > get (Get get ) {
221
- // We expect this method is called after putting the result of the get operation in the get set.
222
- assert getSet .containsKey (get );
223
- return getSet .get (get );
224
- }
225
-
226
- public Optional <Map <Key , TransactionResult >> get (Scan scan ) {
227
- if (scanSet .containsKey (scan )) {
228
- return Optional .ofNullable (scanSet .get (scan ));
229
- }
230
- return Optional .empty ();
231
- }
232
-
233
258
public void verify (Scan scan ) {
234
259
if (isWriteSetOverlappedWith (scan )) {
235
260
throw new IllegalArgumentException (
@@ -531,6 +556,15 @@ void toSerializableWithExtraRead(DistributedStorage storage)
531
556
parallelExecutor .validate (tasks , getId ());
532
557
}
533
558
559
+ private TableMetadata getTableMetadata (Scan scan ) throws ExecutionException {
560
+ TransactionTableMetadata metadata = tableMetadataManager .getTransactionTableMetadata (scan );
561
+ if (metadata == null ) {
562
+ throw new IllegalArgumentException (
563
+ CoreError .TABLE_NOT_FOUND .buildMessage (scan .forFullTableName ().get ()));
564
+ }
565
+ return metadata .getTableMetadata ();
566
+ }
567
+
534
568
private boolean isChanged (
535
569
Optional <TransactionResult > latestResult , Optional <TransactionResult > result ) {
536
570
if (latestResult .isPresent () != result .isPresent ()) {
0 commit comments