All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.trino.plugin.deltalake.transactionlog.writer.TransactionLogWriter Maven / Gradle / Ivy

/*
 * 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 io.trino.plugin.deltalake.transactionlog.writer;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.airlift.json.ObjectMapperProvider;
import io.trino.filesystem.Location;
import io.trino.plugin.deltalake.transactionlog.AddFileEntry;
import io.trino.plugin.deltalake.transactionlog.CdcEntry;
import io.trino.plugin.deltalake.transactionlog.CommitInfoEntry;
import io.trino.plugin.deltalake.transactionlog.DeltaLakeTransactionLogEntry;
import io.trino.plugin.deltalake.transactionlog.MetadataEntry;
import io.trino.plugin.deltalake.transactionlog.ProtocolEntry;
import io.trino.plugin.deltalake.transactionlog.RemoveFileEntry;
import io.trino.spi.connector.ConnectorSession;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static io.trino.plugin.deltalake.transactionlog.TransactionLogUtil.getTransactionLogDir;
import static io.trino.plugin.deltalake.transactionlog.TransactionLogUtil.getTransactionLogJsonEntryPath;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
import static org.apache.parquet.Preconditions.checkState;

public class TransactionLogWriter
{
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapperProvider().get();

    private Optional commitInfoEntry = Optional.empty();
    private final List entries = new ArrayList<>();
    private final TransactionLogSynchronizer logSynchronizer;
    private final ConnectorSession session;
    private final String tableLocation;

    public TransactionLogWriter(TransactionLogSynchronizer logSynchronizer, ConnectorSession session, String tableLocation)
    {
        this.logSynchronizer = requireNonNull(logSynchronizer, "logSynchronizer is null");
        this.session = requireNonNull(session, "session is null");
        this.tableLocation = requireNonNull(tableLocation, "tableLocation is null");
    }

    public void appendCommitInfoEntry(CommitInfoEntry commitInfoEntry)
    {
        checkState(this.commitInfoEntry.isEmpty(), "commitInfo already set");
        this.commitInfoEntry = Optional.of(DeltaLakeTransactionLogEntry.commitInfoEntry(commitInfoEntry));
    }

    public void appendMetadataEntry(MetadataEntry metadataEntry)
    {
        entries.add(DeltaLakeTransactionLogEntry.metadataEntry(metadataEntry));
    }

    public void appendProtocolEntry(ProtocolEntry protocolEntry)
    {
        entries.add(DeltaLakeTransactionLogEntry.protocolEntry(protocolEntry));
    }

    public void appendAddFileEntry(AddFileEntry addFileEntry)
    {
        entries.add(DeltaLakeTransactionLogEntry.addFileEntry(addFileEntry));
    }

    public void appendRemoveFileEntry(RemoveFileEntry removeFileEntry)
    {
        entries.add(DeltaLakeTransactionLogEntry.removeFileEntry(removeFileEntry));
    }

    public void appendCdcEntry(CdcEntry cdcEntry)
    {
        entries.add(DeltaLakeTransactionLogEntry.cdcEntry(cdcEntry));
    }

    public boolean isUnsafe()
    {
        return logSynchronizer.isUnsafe();
    }

    public void flush()
            throws IOException
    {
        checkState(commitInfoEntry.isPresent(), "commitInfo not set");

        String transactionLogLocation = getTransactionLogDir(tableLocation);
        CommitInfoEntry commitInfo = requireNonNull(commitInfoEntry.get().getCommitInfo(), "commitInfoEntry.get().getCommitInfo() is null");
        Location logEntry = getTransactionLogJsonEntryPath(transactionLogLocation, commitInfo.getVersion());

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        writeEntry(bos, commitInfoEntry.get());
        for (DeltaLakeTransactionLogEntry entry : entries) {
            writeEntry(bos, entry);
        }

        String clusterId = commitInfoEntry.get().getCommitInfo().getClusterId();
        logSynchronizer.write(session, clusterId, logEntry, bos.toByteArray());
    }

    private void writeEntry(OutputStream outputStream, DeltaLakeTransactionLogEntry deltaLakeTransactionLogEntry)
            throws IOException
    {
        outputStream.write(OBJECT_MAPPER.writeValueAsString(deltaLakeTransactionLogEntry).getBytes(UTF_8));
        outputStream.write("\n".getBytes(UTF_8));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy