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

org.rocksdb.TtlDB Maven / Gradle / Ivy

// Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).

package org.rocksdb;

import java.util.Arrays;
import java.util.List;

/**
 * Database with TTL support.
 *
 * 

Use case

*

This API should be used to open the db when key-values inserted are * meant to be removed from the db in a non-strict 'ttl' amount of time * Therefore, this guarantees that key-values inserted will remain in the * db for >= ttl amount of time and the db will make efforts to remove the * key-values as soon as possible after ttl seconds of their insertion. *

* *

Behaviour

*

TTL is accepted in seconds * (int32_t)Timestamp(creation) is suffixed to values in Put internally * Expired TTL values deleted in compaction only:(Timestamp+ttl<time_now) * Get/Iterator may return expired entries(compaction not run on them yet) * Different TTL may be used during different Opens *

* *

Example

*
    *
  • Open1 at t=0 with ttl=4 and insert k1,k2, close at t=2
  • *
  • Open2 at t=3 with ttl=5. Now k1,k2 should be deleted at t>=5
  • *
* *

* read_only=true opens in the usual read-only mode. Compactions will not be * triggered(neither manual nor automatic), so no expired entries removed *

* *

Constraints

*

Not specifying/passing or non-positive TTL behaves * like TTL = infinity

* *

!!!WARNING!!!

*

Calling DB::Open directly to re-open a db created by this API will get * corrupt values(timestamp suffixed) and no ttl effect will be there * during the second Open, so use this API consistently to open the db * Be careful when passing ttl with a small positive value because the * whole database may be deleted in a small amount of time.

*/ public class TtlDB extends RocksDB { /** *

Opens a TtlDB.

* *

Database is opened in read-write mode without default TTL.

* * @param options {@link org.rocksdb.Options} instance. * @param db_path path to database. * * @return TtlDB instance. * * @throws RocksDBException thrown if an error occurs within the native * part of the library. */ public static TtlDB open(final Options options, final String db_path) throws RocksDBException { return open(options, db_path, 0, false); } /** *

Opens a TtlDB.

* * @param options {@link org.rocksdb.Options} instance. * @param db_path path to database. * @param ttl time to live for new entries. * @param readOnly boolean value indicating if database if db is * opened read-only. * * @return TtlDB instance. * * @throws RocksDBException thrown if an error occurs within the native * part of the library. */ public static TtlDB open(final Options options, final String db_path, final int ttl, final boolean readOnly) throws RocksDBException { final TtlDB db = new TtlDB(open(options.nativeHandle_, db_path, ttl, readOnly)); db.storeOptionsInstance(options); db.storeDefaultColumnFamilyHandle(db.makeDefaultColumnFamilyHandle()); return db; } /** *

Opens a TtlDB.

* * @param options {@link org.rocksdb.Options} instance. * @param db_path path to database. * @param columnFamilyDescriptors list of column family descriptors * @param columnFamilyHandles will be filled with ColumnFamilyHandle instances * on open. * @param ttlValues time to live values per column family handle * @param readOnly boolean value indicating if database if db is * opened read-only. * * @return TtlDB instance. * * @throws RocksDBException thrown if an error occurs within the native * part of the library. * @throws java.lang.IllegalArgumentException when there is not a ttl value * per given column family handle. */ public static TtlDB open(final DBOptions options, final String db_path, final List columnFamilyDescriptors, final List columnFamilyHandles, final List ttlValues, final boolean readOnly) throws RocksDBException { if (columnFamilyDescriptors.size() != ttlValues.size()) { throw new IllegalArgumentException("There must be a ttl value per column" + " family handle."); } int defaultColumnFamilyIndex = -1; final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][]; final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()]; for (int i = 0; i < columnFamilyDescriptors.size(); i++) { final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors.get(i); cfNames[i] = cfDescriptor.getName(); cfOptionHandles[i] = cfDescriptor.getOptions().nativeHandle_; if (Arrays.equals(cfDescriptor.getName(), RocksDB.DEFAULT_COLUMN_FAMILY)) { defaultColumnFamilyIndex = i; } } if (defaultColumnFamilyIndex < 0) { throw new IllegalArgumentException( "You must provide the default column family in your columnFamilyDescriptors"); } final int[] ttlVals = new int[ttlValues.size()]; for(int i = 0; i < ttlValues.size(); i++) { ttlVals[i] = ttlValues.get(i); } final long[] handles = openCF(options.nativeHandle_, db_path, cfNames, cfOptionHandles, ttlVals, readOnly); final TtlDB ttlDB = new TtlDB(handles[0]); for (int i = 1; i < handles.length; i++) { columnFamilyHandles.add(new ColumnFamilyHandle(ttlDB, handles[i])); } ttlDB.storeOptionsInstance(options); ttlDB.ownedColumnFamilyHandles.addAll(columnFamilyHandles); ttlDB.storeDefaultColumnFamilyHandle(columnFamilyHandles.get(defaultColumnFamilyIndex)); return ttlDB; } /** *

Close the TtlDB instance and release resource.

* * This is similar to {@link #close()} except that it * throws an exception if any error occurs. *

* This will not fsync the WAL files. * If syncing is required, the caller must first call {@link #syncWal()} * or {@link #write(WriteOptions, WriteBatch)} using an empty write batch * with {@link WriteOptions#setSync(boolean)} set to true. *

* See also {@link #close()}. * * @throws RocksDBException if an error occurs whilst closing. */ @Override public void closeE() throws RocksDBException { if (owningHandle_.compareAndSet(true, false)) { try { closeDatabase(nativeHandle_); } finally { disposeInternal(); } } } /** *

Close the TtlDB instance and release resource.

* * * This will not fsync the WAL files. * If syncing is required, the caller must first call {@link #syncWal()} * or {@link #write(WriteOptions, WriteBatch)} using an empty write batch * with {@link WriteOptions#setSync(boolean)} set to true. *

* See also {@link #close()}. */ @SuppressWarnings("PMD.EmptyCatchBlock") @Override public void close() { for (final ColumnFamilyHandle columnFamilyHandle : // NOPMD - CloseResource ownedColumnFamilyHandles) { columnFamilyHandle.close(); } ownedColumnFamilyHandles.clear(); if (owningHandle_.compareAndSet(true, false)) { try { closeDatabase(nativeHandle_); } catch (final RocksDBException e) { // silently ignore the error report } finally { disposeInternal(); } } } /** *

Creates a new ttl based column family with a name defined * in given ColumnFamilyDescriptor and allocates a * ColumnFamilyHandle within an internal structure.

* *

The ColumnFamilyHandle is automatically disposed with DB * disposal.

* * @param columnFamilyDescriptor column family to be created. * @param ttl TTL to set for this column family. * * @return {@link org.rocksdb.ColumnFamilyHandle} instance. * * @throws RocksDBException thrown if error happens in underlying * native library. */ public ColumnFamilyHandle createColumnFamilyWithTtl( final ColumnFamilyDescriptor columnFamilyDescriptor, final int ttl) throws RocksDBException { return new ColumnFamilyHandle(this, createColumnFamilyWithTtl(nativeHandle_, columnFamilyDescriptor.getName(), columnFamilyDescriptor.getOptions().nativeHandle_, ttl)); } /** *

A protected constructor that will be used in the static * factory method * {@link #open(Options, String, int, boolean)} * and * {@link #open(DBOptions, String, java.util.List, java.util.List, * java.util.List, boolean)}. *

* * @param nativeHandle The native handle of the C++ TtlDB object */ protected TtlDB(final long nativeHandle) { super(nativeHandle); } @Override protected void disposeInternal(final long handle) { disposeInternalJni(handle); } private static native void disposeInternalJni(final long handle); private static native long open(final long optionsHandle, final String db_path, final int ttl, final boolean readOnly) throws RocksDBException; private static native long[] openCF(final long optionsHandle, final String db_path, final byte[][] columnFamilyNames, final long[] columnFamilyOptions, final int[] ttlValues, final boolean readOnly) throws RocksDBException; private static native long createColumnFamilyWithTtl( final long handle, final byte[] columnFamilyName, final long columnFamilyOptions, int ttl) throws RocksDBException; private static native void closeDatabase(final long handle) throws RocksDBException; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy