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

jetbrains.exodus.io.DataWriter Maven / Gradle / Ivy

There is a newer version: 9.8.0.76914
Show newest version
/**
 * Copyright 2010 - 2022 JetBrains s.r.o.
 *
 * 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
 *
 * https://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 jetbrains.exodus.io;

import jetbrains.exodus.ExodusException;
import jetbrains.exodus.env.EnvironmentConfig;
import org.jetbrains.annotations.NotNull;

import java.io.Closeable;

/**
 * {@code DataWriter} defines the way how data is written to {@code Log}, how {@linkplain Block blocks} appear in
 * the log and how they are removed from the log.
 *
 * {@code Log} blocks can be mutable and immutable. All blocks having length equal to {@linkplain EnvironmentConfig#getLogFileSize()
 * maximum log block size} are immutable. In any moment, only one block can be mutable. This has maximum {@linkplain
 * Block#getAddress() address}. {@code DataWriter} always writes to a single mutable block, that makes {@code log}
 * appendable.
 *
 * @see Block
 * @see DataReader
 * @see DataReaderWriterProvider
 * @since 1.3.0
 */
public interface DataWriter extends Closeable {

    /**
     * Returns {@code true} is the DataWriter is open. i.e. there is an incomplete mutable {@linkplain Block block}
     * having length less than {@linkplain EnvironmentConfig#getLogFileSize() maximum log block size}.
     *
     * @return {@code true} is the DataWriter is open
     */
    boolean isOpen();

    /**
     * Writes (appends) binary data to {@code Log}. Returns new {@linkplain Block} instance representing mutable block.
     *
     * @param b   binary data array
     * @param off starting offset in the array
     * @param len number of byte to write
     * @return mutable {@linkplain Block} instance
     * @see Block
     */
    Block write(byte[] b, int off, int len);

    /**
     * If applicable, forces flush of written data to underlying storage device. Transaction durability depends
     * on the implementation of this method.
     */
    void sync();

    /**
     * If applicable, forces flush of changes in directory structure to underlying storage device.
     */
    void syncDirectory();

    /**
     * Closes the data writer. {@code Log} closes the data writer each time when mutable {@linkplain Block block}
     * becomes immutable, i.e. reaches its {@linkplain EnvironmentConfig#getLogFileSize() maximum log block size}.
     */
    void close();

    /**
     * Clears {@code Log} by location specified as a parameter to {@linkplain DataReaderWriterProvider#newReaderWriter(String)}.
     * The database becomes empty.
     */
    void clear();

    /**
     * Open existing {@linkplain Block block} for writing or creates the new one by specified address with specified length.
     * This method is used in the log recovery procedure, so {@code DataWriter} should truncate existing block
     * if its physical length is greater than specified one. This method is always applied to a mutable {@linkplain Block block}.
     *
     * @param address address of {@linkplain Block block} to open or create
     * @param length  valid {@linkplain Block block} length
     * @return mutable {@linkplain Block} instance
     */
    Block openOrCreateBlock(long address, long length);

    /**
     * Removes existing immutable {@linkplain Block block}. If applicable, this method can rename
     * {@linkplain Block block} (file on a file system) instead of removing it if specified
     * {@code RemoveBlockType rbt} is equal to {@linkplain RemoveBlockType#Rename}.
     *
     * @param blockAddress address of {@linkplain Block block} to remove
     * @param rbt          {@linkplain RemoveBlockType#Rename} to rename {@linkplain Block block} instead of removing it.
     * @see RemoveBlockType
     */
    void removeBlock(long blockAddress, @NotNull RemoveBlockType rbt);

    /**
     * Truncates existing {@linkplain Block block} to specified length. Does nothing is specified length is greater
     * than or equal to physical {@linkplain Block block} length.
     *
     * @param blockAddress address of {@linkplain Block block} to truncate
     * @param length       {@linkplain Block block} length
     */
    void truncateBlock(long blockAddress, long length);

    /**
     * If applicable, tries to acquire writer's lock in specified time. If the lock is acquired, returns {@code true}.
     * Successfully acquired lock guarantees that {@code Log} cannot be opened in parallel (within same
     * JVM or not) unless it is released by the writer.
     *
     * @param timeout - time to wait for lock acquisition
     * @return {@code true} if the lock is acquired
     * @see #release()
     * @see #lockInfo()
     */
    boolean lock(long timeout);

    /**
     * Releases writer's lock.
     *
     * @return {@code true} if released successfully
     * @see #lock(long)
     */
    boolean release();

    /**
     * For debugging purposes, returns detailed information about current lock owner. If {@linkplain #lock(long)}
     * return {@code false}, {@code Log} throws an {@linkplain ExodusException} with the lock info in its message.
     *
     * @return Human-readable information about lock owner
     * @see #lock(long)
     */
    String lockInfo();
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy