Skip to content

Commit 9f51810

Browse files
committed
Make Etch persistence throw checked IOExceptions
1 parent ea1b1a1 commit 9f51810

File tree

29 files changed

+194
-115
lines changed

29 files changed

+194
-115
lines changed

convex-benchmarks/src/main/java/convex/benchmarks/BigBlockBenchmark.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package convex.benchmarks;
22

3+
import java.io.IOException;
34
import java.util.ArrayList;
45
import java.util.Random;
56

@@ -53,7 +54,7 @@ public class BigBlockBenchmark {
5354
}
5455

5556
@Benchmark
56-
public void benchmark() throws BadSignatureException {
57+
public void benchmark() throws BadSignatureException, IOException {
5758
BlockResult br=state.applyBlock(block);
5859
Cells.persist(br.getState());
5960
}

convex-benchmarks/src/main/java/convex/benchmarks/EtchBenchmark.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,22 @@ public class EtchBenchmark {
4141
static {
4242
try {
4343
store =EtchStore.createTemp();
44+
for (int i=0; i<NUMVALS; i++) {
45+
AVector<CVMLong> v=Vectors.of(0L,(long)i);
46+
Ref<ACell> r=v.getRef();
47+
refs[i]=r;
48+
r.getHash();
49+
store.storeTopRef(r, Ref.STORED, null);
50+
}
4451
} catch (IOException e) {
4552
throw new Error(e);
4653
}
47-
for (int i=0; i<NUMVALS; i++) {
48-
AVector<CVMLong> v=Vectors.of(0L,(long)i);
49-
Ref<ACell> r=v.getRef();
50-
refs[i]=r;
51-
r.getHash();
52-
store.storeTopRef(r, Ref.STORED, null);
53-
}
54+
5455
System.out.println("Refs stored for testing");
5556
}
5657

5758
@Benchmark
58-
public void writeData() {
59+
public void writeData() throws IOException {
5960
AVector<CVMLong> v=Vectors.of(1L,nonce++);
6061
store.storeTopRef(v.getRef(), Ref.STORED, null);
6162
}

convex-benchmarks/src/main/java/convex/benchmarks/SignatureBenchmark.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package convex.benchmarks;
22

3+
import java.io.IOException;
4+
35
import org.openjdk.jmh.annotations.Benchmark;
46
import org.openjdk.jmh.runner.Runner;
57
import org.openjdk.jmh.runner.options.Options;
@@ -25,7 +27,11 @@ public class SignatureBenchmark {
2527

2628
private static SignedData<ABlob> makeSigned() {
2729
SignedData<ABlob> signed= KEYPAIR.signData(Blobs.fromHex("cafebabe"));
28-
Cells.persist(signed);
30+
try {
31+
Cells.persist(signed);
32+
} catch (IOException e) {
33+
throw new Error(e);
34+
}
2935
return signed;
3036
}
3137

convex-cli/src/main/java/convex/cli/etch/EtchWrite.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package convex.cli.etch;
22

3+
import java.io.IOException;
4+
5+
import convex.cli.CLIError;
36
import convex.core.data.ACell;
47
import convex.core.data.Hash;
58
import convex.core.data.Ref;
@@ -34,6 +37,8 @@ public void run() {
3437
Hash h=Ref.get(cell).getHash();
3538
println(h.toString());
3639
informSuccess("Data saved with hash: "+h);
40+
} catch (IOException e) {
41+
throw new CLIError("Unable to write to store",e);
3742
} finally {
3843
store.close();
3944
}

convex-core/src/main/java/convex/core/data/Cells.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package convex.core.data;
22

3+
import java.io.IOException;
34
import java.lang.reflect.Array;
45
import java.util.function.Consumer;
56

@@ -126,8 +127,9 @@ public static boolean isValue(ACell a) {
126127
* Persist a cell in the current store
127128
* @param a Cell to persist
128129
* @return Cell after persisting (may be the same Cell if no change in cell hierarchy)
130+
* @throws IOException
129131
*/
130-
public static <T extends ACell> T persist(T a) {
132+
public static <T extends ACell> T persist(T a) throws IOException {
131133
return persist(a,Stores.current());
132134
}
133135

@@ -136,8 +138,9 @@ public static <T extends ACell> T persist(T a) {
136138
* @param a Cell to persist
137139
* @param store Store instance to persist in
138140
* @return Cell after persisting (may be the same Cell if no change in cell hierarchy)
141+
* @throws IOException
139142
*/
140-
public static <T extends ACell> T persist(T a, AStore store) {
143+
public static <T extends ACell> T persist(T a, AStore store) throws IOException {
141144
Ref<T> ref=Ref.get(a);
142145
Ref<T> sref=store.storeTopRef(ref, Ref.PERSISTED, null);
143146
return sref.getValue();
@@ -148,8 +151,9 @@ public static <T extends ACell> T persist(T a, AStore store) {
148151
* @param a Cell to persist
149152
* @param store Store instance to persist in
150153
* @return Cell after persisting (may be the same Cell if no change in cell hierarchy)
154+
* @throws IOException
151155
*/
152-
public static <T extends ACell> T store(T a, AStore store) {
156+
public static <T extends ACell> T store(T a, AStore store) throws IOException {
153157
Ref<T> ref=Ref.get(a);
154158
Ref<T> sref=store.storeTopRef(ref, Ref.STORED, null);
155159
return sref.getValue();
@@ -160,8 +164,9 @@ public static <T extends ACell> T store(T a, AStore store) {
160164
* @param a Cell to announce
161165
* @param noveltyHandler Handler for novelty values
162166
* @return Cell after announcing (may be the same Cell if no change in cell hierarchy)
167+
* @throws IOException
163168
*/
164-
public static <T extends ACell> T announce(T a, Consumer<Ref<ACell>> noveltyHandler) {
169+
public static <T extends ACell> T announce(T a, Consumer<Ref<ACell>> noveltyHandler) throws IOException {
165170
if (a==null) {
166171
return null; // null is never "novelty"
167172
};

convex-core/src/main/java/convex/core/data/Ref.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package convex.core.data;
22

3+
import java.io.IOException;
34
import java.util.ArrayList;
45
import java.util.HashSet;
56
import java.util.function.Consumer;
@@ -404,11 +405,12 @@ public boolean isMarked() {
404405
*
405406
* @param noveltyHandler Novelty handler to call (may be null)
406407
* @return the persisted Ref
408+
* @throws IOException
407409
* @throws MissingDataException If the Ref's value does not exist or has been
408410
* garbage collected before being persisted
409411
*/
410412
@SuppressWarnings("unchecked")
411-
public <R extends ACell> Ref<R> persist(Consumer<Ref<ACell>> noveltyHandler) {
413+
public <R extends ACell> Ref<R> persist(Consumer<Ref<ACell>> noveltyHandler) throws IOException {
412414
int status = getStatus();
413415
if (status >= PERSISTED) return (Ref<R>) this; // already persisted in some form
414416
AStore store=Stores.current();
@@ -423,8 +425,9 @@ public <R extends ACell> Ref<R> persist(Consumer<Ref<ACell>> noveltyHandler) {
423425
*
424426
* @throws MissingDataException if the Ref cannot be fully persisted.
425427
* @return the persisted Ref
428+
* @throws IOException
426429
*/
427-
public <R extends ACell> Ref<R> persist() {
430+
public <R extends ACell> Ref<R> persist() throws IOException {
428431
return persist(null);
429432
}
430433

@@ -531,8 +534,9 @@ public final boolean isEmbedded() {
531534
* Status will be updated to STORED or higher.
532535
*
533536
* @return Ref with status of STORED or above
537+
* @throws IOException
534538
*/
535-
public <R extends ACell> Ref<R> persistShallow() {
539+
public <R extends ACell> Ref<R> persistShallow() throws IOException {
536540
return persistShallow(null);
537541
}
538542

@@ -544,9 +548,10 @@ public <R extends ACell> Ref<R> persistShallow() {
544548
*
545549
* @param noveltyHandler Novelty handler to call (may be null)
546550
* @return Ref with status of STORED or above
551+
* @throws IOException
547552
*/
548553
@SuppressWarnings("unchecked")
549-
public <R extends ACell> Ref<R> persistShallow(Consumer<Ref<ACell>> noveltyHandler) {
554+
public <R extends ACell> Ref<R> persistShallow(Consumer<Ref<ACell>> noveltyHandler) throws IOException {
550555
AStore store=Stores.current();
551556
return (Ref<R>) store.storeTopRef((Ref<ACell>)this, Ref.STORED, noveltyHandler);
552557
}

convex-core/src/main/java/convex/core/store/AStore.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ public abstract class AStore implements Closeable {
3737
* @param status Status to store at
3838
* @param noveltyHandler Novelty Handler function for Novelty detected. May be null.
3939
* @return The persisted Ref, of status STORED at minimum
40+
* @throws IOException
4041
*/
41-
public abstract <T extends ACell> Ref<T> storeRef(Ref<T> ref, int status,Consumer<Ref<ACell>> noveltyHandler);
42+
public abstract <T extends ACell> Ref<T> storeRef(Ref<T> ref, int status,Consumer<Ref<ACell>> noveltyHandler) throws IOException;
4243

4344
/**
4445
* Stores a top level @Ref in long term storage as defined by this store implementation.
@@ -55,8 +56,9 @@ public abstract class AStore implements Closeable {
5556
* @param status Status to store at
5657
* @param noveltyHandler Novelty Handler function for Novelty detected. May be null.
5758
* @return The persisted Ref, of status STORED at minimum
59+
* @throws IOException
5860
*/
59-
public abstract <T extends ACell> Ref<T> storeTopRef(Ref<T> ref, int status,Consumer<Ref<ACell>> noveltyHandler);
61+
public abstract <T extends ACell> Ref<T> storeTopRef(Ref<T> ref, int status,Consumer<Ref<ACell>> noveltyHandler) throws IOException;
6062

6163

6264
/**

convex-core/src/main/java/convex/core/store/MemoryStore.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public <T extends ACell> Ref<T> persistRef(Ref<T> ref, Consumer<Ref<ACell>> nove
9999

100100
// need to do recursive persistence
101101
cell = cell.updateRefs(r -> {
102-
return r.persist(noveltyHandler);
102+
return persistRef(r,noveltyHandler,requiredStatus,false);
103103
});
104104

105105
ref=ref.withValue((T)cell);

convex-core/src/main/java/convex/etch/EtchStore.java

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -133,18 +133,18 @@ public <T extends ACell> Ref<T> readStoreRef(Hash hash) throws IOException {
133133
}
134134

135135
@Override
136-
public <T extends ACell> Ref<T> storeRef(Ref<T> ref, int status, Consumer<Ref<ACell>> noveltyHandler) {
136+
public <T extends ACell> Ref<T> storeRef(Ref<T> ref, int status, Consumer<Ref<ACell>> noveltyHandler) throws IOException {
137137
return storeRef(ref, status, noveltyHandler, false);
138138
}
139139

140140
@Override
141-
public <T extends ACell> Ref<T> storeTopRef(Ref<T> ref, int status, Consumer<Ref<ACell>> noveltyHandler) {
141+
public <T extends ACell> Ref<T> storeTopRef(Ref<T> ref, int status, Consumer<Ref<ACell>> noveltyHandler) throws IOException {
142142
return storeRef(ref, status, noveltyHandler, true);
143143
}
144144

145145
@SuppressWarnings("unchecked")
146146
public <T extends ACell> Ref<T> storeRef(Ref<T> ref, int requiredStatus, Consumer<Ref<ACell>> noveltyHandler,
147-
boolean topLevel) {
147+
boolean topLevel) throws IOException {
148148

149149
// Get the value. If we are persisting, should be there!
150150
ACell cell = ref.getValue();
@@ -179,7 +179,11 @@ public <T extends ACell> Ref<T> storeRef(Ref<T> ref, int requiredStatus, Consume
179179
if ((requiredStatus > Ref.STORED) && (cell.getRefCount() > 0)) {
180180
// TODO: probably slow to rebuild these all the time!
181181
IRefFunction func = r -> {
182-
return storeRef((Ref<ACell>) r, requiredStatus, noveltyHandler, false);
182+
try {
183+
return storeRef((Ref<ACell>) r, requiredStatus, noveltyHandler, false);
184+
} catch (IOException e) {
185+
throw Utils.sneakyThrow(e);
186+
}
183187
};
184188

185189
// need to do recursive persistence
@@ -206,23 +210,20 @@ public <T extends ACell> Ref<T> storeRef(Ref<T> ref, int requiredStatus, Consume
206210
}
207211

208212
Ref<ACell> result;
209-
try {
210-
// ensure status is set when we write to store
211-
ref = ref.withMinimumStatus(requiredStatus);
212-
cell.attachRef(ref); // make sure we are using current ref within cell
213-
result = etch.write(fHash, (Ref<ACell>) ref);
214-
215-
if (!embedded) {
216-
// Ensure we have soft Refpointing to this store
217-
result = result.toSoft(this);
218-
}
219213

220-
cell.attachRef(result);
221-
addToCache(result); // cache for subsequent writes
222-
} catch (IOException e) {
223-
throw Utils.sneakyThrow(e);
214+
// ensure status is set when we write to store
215+
ref = ref.withMinimumStatus(requiredStatus);
216+
cell.attachRef(ref); // make sure we are using current ref within cell
217+
result = etch.write(fHash, (Ref<ACell>) ref);
218+
219+
if (!embedded) {
220+
// Ensure we have soft Refpointing to this store
221+
result = result.toSoft(this);
224222
}
225223

224+
cell.attachRef(result);
225+
addToCache(result); // cache for subsequent writes
226+
226227
// call novelty handler if newly persisted non-embedded
227228
if (noveltyHandler != null) {
228229
if (!embedded)

convex-core/src/test/java/convex/comms/GenTestFormat.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import static org.junit.Assert.assertEquals;
44

5+
import java.io.IOException;
6+
57
import org.junit.runner.RunWith;
68

79
import com.pholser.junit.quickcheck.From;
@@ -35,7 +37,7 @@ public void messageRoundTrip(String str) throws BadFormatException {
3537
}
3638

3739
@Property
38-
public void primitiveRoundTrip(@From(PrimitiveGen.class) ACell prim) throws BadFormatException {
40+
public void primitiveRoundTrip(@From(PrimitiveGen.class) ACell prim) throws BadFormatException, IOException {
3941
Blob b = Format.encodedBlob(prim);
4042
if (!Format.isEmbedded(prim)) {
4143
// persist in case large
@@ -49,7 +51,7 @@ public void primitiveRoundTrip(@From(PrimitiveGen.class) ACell prim) throws BadF
4951
}
5052

5153
@Property
52-
public void dataRoundTrip(@From(ValueGen.class) ACell value) throws BadFormatException {
54+
public void dataRoundTrip(@From(ValueGen.class) ACell value) throws BadFormatException, IOException {
5355
Ref<ACell> pref = Ref.get(Cells.persist(value)); // ensure persisted
5456
Blob b = Format.encodedBlob(value);
5557
ACell o = Format.read(b);

0 commit comments

Comments
 (0)