[ 
https://issues.apache.org/jira/browse/TINKERPOP-3282?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18120405#comment-18120405
 ] 

ASF GitHub Bot commented on TINKERPOP-3282:
-------------------------------------------

kenhuuu commented on code in PR #3639:
URL: https://github.com/apache/tinkerpop/pull/3639#discussion_r4127089698


##########
tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerTransaction.java:
##########
@@ -174,9 +177,36 @@ protected void doCommit() throws TransactionException {
             final TinkerTransactionalIndex edgeIndex = 
(TinkerTransactionalIndex) graph.edgeIndex;
             if (edgeIndex != null) edgeIndex.commit(changedEdges);
 
-            // commit all changes
-            changedVertices.forEach(v -> v.commit(txVersion));
-            changedEdges.forEach(e -> e.commit(txVersion));
+            // write-ahead: durably persist the changeset before applying the 
in-memory commit, so a failure here
+            // aborts the commit (via the catch below) and leaves memory and 
disk consistent. Skipped while the graph

Review Comment:
   Is this actually true? `persist` and `flush` throw `UncheckedIOException` 
which isn't covered by `TransactionException`.



##########
tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/storage/AbstractLogStorage.java:
##########
@@ -0,0 +1,485 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.tinkerpop.gremlin.tinkergraph.structure.storage;
+
+import org.apache.commons.configuration2.Configuration;
+import org.apache.tinkerpop.gremlin.structure.util.Attachable;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.AbstractTinkerGraph;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerEdge;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UncheckedIOException;
+import java.nio.channels.FileChannel;
+import java.nio.file.AtomicMoveNotSupportedException;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.zip.CRC32;
+
+/**
+ * Log-structured durable storage machinery shared by {@link TinkerStorage} 
engines, independent of how an element is
+ * encoded. It persists a {@code TinkerStorageGraph} as an append-only commit 
log ({@code log.gbin}) plus an optional
+ * folded {@code snapshot.gbin}; on open the snapshot is read followed by the 
log, last-write-wins per element id.
+ * <p/>
+ * This base owns everything that is not the element codec: the on-disk file 
layout, the single-source-of-truth
+ * {@code VERSION} marker, length+CRC frame framing (which tells an 
interrupted trailing append apart from genuine
+ * corruption), the replay fold loop, durability via {@link SyncMode}, and 
crash-safe atomic compaction with a
+ * size threshold. Concrete engines supply only the codec through {@link 
#encodeCommit}, {@link #decodeFrame},
+ * {@link #writeSnapshot}, and (optionally) {@link #beginReplay} for 
per-replay decode state.
+ * <p/>
+ * The in-memory graph remains authoritative (write-through); this machinery 
does not support graphs larger than memory.
+ */
+public abstract class AbstractLogStorage implements TinkerStorage {
+
+    /**
+     * Magic bytes ("TGSB" — TinkerGraph Storage Binary) at the start of every 
storage file, so a file can be
+     * identified as one written by this engine (and a foreign or corrupt file 
rejected) before any record is read.
+     */
+    static final byte[] MAGIC = { 'T', 'G', 'S', 'B' };
+
+    /**
+     * On-disk format version of the store. Recorded once per store in the 
{@link #VERSION_FILE} marker rather than in
+     * every file, so a store has a single unambiguous version even when it 
momentarily holds a snapshot and a log
+     * written at different times. A future format bump is detected against 
this marker so an older store is rejected
+     * (never silently misread); the supported migration path is to export via 
{@code g.io()} before upgrading.
+     */
+    static final byte FORMAT_VERSION = 1;
+
+    /**
+     * Store-level version marker file, holding {@link #MAGIC} followed by the 
one-byte {@link #FORMAT_VERSION}.
+     */
+    static final String VERSION_FILE = "VERSION";
+
+    /**
+     * Bytes of the per-file header: just {@link #MAGIC}. The format version 
lives in the store-level
+     * {@link #VERSION_FILE}, not in each file.
+     */
+    static final int HEADER_SIZE = MAGIC.length;
+
+    static final String SNAPSHOT_FILE = "snapshot.gbin";
+    static final String LOG_FILE = "log.gbin";
+
+    /**
+     * Default automatic-compaction threshold: 64 MB of appended log since the 
last compaction.
+     */
+    static final long DEFAULT_COMPACT_THRESHOLD_BYTES = 64L * 1024 * 1024;
+
+    private File directory;
+    private File snapshotFile;
+    private File logFile;
+    private File versionFile;
+
+    private DataOutputStream logOut;
+    private FileOutputStream logFos;
+    private SyncMode syncMode = SyncMode.COMMIT;
+    private long compactThresholdBytes = DEFAULT_COMPACT_THRESHOLD_BYTES;
+    private long logBytesSinceCompaction = 0;
+    private boolean closed = false;
+
+    // 
---------------------------------------------------------------------------------------

> TinkerGraph file persistence
> ----------------------------
>
>                 Key: TINKERPOP-3282
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP-3282
>             Project: TinkerPop
>          Issue Type: Improvement
>          Components: tinkergraph
>    Affects Versions: 3.7.6
>            Reporter: Stephen Mallette
>            Assignee: Stephen Mallette
>            Priority: Major
>
> Give TinkerGraph a basic file persistence option tied to its transactional 
> usage so that it can support some more complex use cases.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to