Search in sources :

Example 6 with Transaction

use of org.rocksdb.Transaction in project FarPlaneTwo by PorkStudios.

the class RocksTileHandle method markDirty.

@Override
@SneakyThrows(RocksDBException.class)
public boolean markDirty(long dirtyTimestamp) {
    try (Transaction txn = this.storage.db.beginTransaction(WRITE_OPTIONS)) {
        byte[] keyBytes = this.pos.toBytes();
        // obtain an exclusive lock on both timestamp keys to ensure coherency
        byte[][] get = txn.multiGetForUpdate(READ_OPTIONS, ImmutableList.of(this.storage.cfTileTimestamp, this.storage.cfTileDirtyTimestamp), new byte[][] { keyBytes, keyBytes });
        byte[] timestampBytes = get[0];
        long timestamp = timestampBytes != null ? // timestamp for this tile exists, extract it from the byte array
        Unpooled.wrappedBuffer(timestampBytes).readLongLE() : TIMESTAMP_BLANK;
        byte[] dirtyTimestampBytes = get[1];
        long existingDirtyTimestamp = dirtyTimestampBytes != null ? // dirty timestamp for this tile exists, extract it from the byte array
        Unpooled.wrappedBuffer(dirtyTimestampBytes).readLongLE() : TIMESTAMP_BLANK;
        if (// the tile doesn't exist, so we can't mark it as dirty
        timestamp == TIMESTAMP_BLANK || dirtyTimestamp <= timestamp || dirtyTimestamp <= existingDirtyTimestamp) {
            // exit without committing the transaction
            return false;
        }
        // store new dirty timestamp in db
        txn.put(this.storage.cfTileDirtyTimestamp, keyBytes, UnpooledByteBufAllocator.DEFAULT.heapBuffer(Long.BYTES, Long.BYTES).writeLongLE(dirtyTimestamp).array());
        // commit transaction and report that a change was made
        txn.commit();
        this.storage.listeners.forEach(listener -> listener.tilesDirty(Stream.of(this.pos)));
        return true;
    }
}
Also used : Transaction(org.rocksdb.Transaction) SneakyThrows(lombok.SneakyThrows)

Example 7 with Transaction

use of org.rocksdb.Transaction in project FarPlaneTwo by PorkStudios.

the class RocksTileHandle method set.

@Override
@SneakyThrows(RocksDBException.class)
public boolean set(@NonNull ITileMetadata metadata, @NonNull T tile) {
    try (Transaction txn = this.storage.db.beginTransaction(WRITE_OPTIONS)) {
        byte[] keyBytes = this.pos.toBytes();
        // obtain an exclusive lock on both timestamp keys to ensure coherency
        byte[][] get = txn.multiGetForUpdate(READ_OPTIONS, ImmutableList.of(this.storage.cfTileTimestamp, this.storage.cfTileDirtyTimestamp), new byte[][] { keyBytes, keyBytes });
        byte[] timestampBytes = get[0];
        long timestamp = timestampBytes != null ? // timestamp for this tile exists, extract it from the byte array
        readLongLE(timestampBytes) : TIMESTAMP_BLANK;
        byte[] dirtyTimestampBytes = get[1];
        long dirtyTimestamp = dirtyTimestampBytes != null ? // dirty timestamp for this tile exists, extract it from the byte array
        readLongLE(dirtyTimestampBytes) : TIMESTAMP_BLANK;
        if (metadata.timestamp() <= timestamp) {
            // exit without committing the transaction
            return false;
        }
        // store new timestamp in db
        txn.put(this.storage.cfTileTimestamp, keyBytes, writeLongLE(metadata.timestamp()));
        // clear dirty timestamp if needed
        if (metadata.timestamp() >= dirtyTimestamp) {
            txn.delete(this.storage.cfTileDirtyTimestamp, keyBytes);
        }
        // encode tile and store it in db
        ByteBuf buf = ByteBufAllocator.DEFAULT.heapBuffer();
        try {
            if (tile.write(buf)) {
                // the tile was empty, remove it from the db!
                txn.delete(this.storage.cfTileData, keyBytes);
            } else {
                // the tile was non-empty, store it in the db
                txn.put(this.storage.cfTileData, keyBytes, Arrays.copyOfRange(buf.array(), buf.arrayOffset(), buf.arrayOffset() + buf.writerIndex()));
            }
        } finally {
            buf.release();
        }
        // commit transaction and report that a change was made
        txn.commit();
        this.storage.listeners.forEach(listener -> listener.tilesChanged(Stream.of(this.pos)));
        return true;
    }
}
Also used : Transaction(org.rocksdb.Transaction) ByteBuf(io.netty.buffer.ByteBuf) SneakyThrows(lombok.SneakyThrows)

Example 8 with Transaction

use of org.rocksdb.Transaction in project incubator-pulsar by apache.

the class RocksdbMetadataStore method storeDelete.

@Override
protected CompletableFuture<Void> storeDelete(String path, Optional<Long> expectedVersion) {
    if (log.isDebugEnabled()) {
        log.debug("storeDelete.path={},instanceId={}", path, instanceId);
    }
    try {
        dbStateLock.readLock().lock();
        if (state == State.CLOSED) {
            throw new MetadataStoreException.AlreadyClosedException("");
        }
        try (Transaction transaction = db.beginTransaction(optionSync)) {
            byte[] pathBytes = toBytes(path);
            byte[] oldValueData = transaction.getForUpdate(optionDontCache, pathBytes, false);
            MetaValue metaValue = MetaValue.parse(oldValueData);
            if (metaValue == null) {
                throw new MetadataStoreException.NotFoundException(String.format("path %s not found.", path));
            }
            if (expectedVersion.isPresent() && !expectedVersion.get().equals(metaValue.getVersion())) {
                throw new MetadataStoreException.BadVersionException(String.format("Version mismatch, actual=%s, expect=%s", metaValue.getVersion(), expectedVersion.get()));
            }
            transaction.delete(pathBytes);
            transaction.commit();
            receivedNotification(new Notification(NotificationType.Deleted, path));
            notifyParentChildrenChanged(path);
            return CompletableFuture.completedFuture(null);
        }
    } catch (Throwable e) {
        return FutureUtil.failedFuture(MetadataStoreException.wrap(e));
    } finally {
        dbStateLock.readLock().unlock();
    }
}
Also used : Transaction(org.rocksdb.Transaction) Notification(org.apache.pulsar.metadata.api.Notification)

Example 9 with Transaction

use of org.rocksdb.Transaction in project pulsar by yahoo.

the class RocksdbMetadataStore method storePut.

@Override
protected CompletableFuture<Stat> storePut(String path, byte[] data, Optional<Long> expectedVersion, EnumSet<CreateOption> options) {
    if (log.isDebugEnabled()) {
        log.debug("storePut.path={},instanceId={}", path, instanceId);
    }
    try {
        dbStateLock.readLock().lock();
        if (state == State.CLOSED) {
            throw new MetadataStoreException.AlreadyClosedException("");
        }
        try (Transaction transaction = db.beginTransaction(optionSync)) {
            byte[] pathBytes = toBytes(path);
            byte[] oldValueData = transaction.getForUpdate(optionDontCache, pathBytes, false);
            MetaValue metaValue = MetaValue.parse(oldValueData);
            if (expectedVersion.isPresent()) {
                if (metaValue == null && expectedVersion.get() != -1 || metaValue != null && !expectedVersion.get().equals(metaValue.getVersion())) {
                    throw new MetadataStoreException.BadVersionException(String.format("Version mismatch, actual=%s, expect=%s", metaValue == null ? null : metaValue.getVersion(), expectedVersion.get()));
                }
            }
            boolean created = false;
            long timestamp = System.currentTimeMillis();
            if (metaValue == null) {
                // create new node
                metaValue = new MetaValue();
                metaValue.version = 0;
                metaValue.createdTimestamp = timestamp;
                metaValue.ephemeral = options.contains(CreateOption.Ephemeral);
                if (options.contains(CreateOption.Sequential)) {
                    path += sequentialIdGenerator.getAndIncrement();
                    pathBytes = toBytes(path);
                    transaction.put(SEQUENTIAL_ID_KEY, toBytes(sequentialIdGenerator.get()));
                }
                created = true;
            } else {
                // update old node
                metaValue.version++;
            }
            metaValue.modifiedTimestamp = timestamp;
            metaValue.owner = instanceId;
            metaValue.data = data;
            // handle Sequential
            transaction.put(pathBytes, metaValue.serialize());
            transaction.commit();
            receivedNotification(new Notification(created ? NotificationType.Created : NotificationType.Modified, path));
            if (created) {
                notifyParentChildrenChanged(path);
            }
            return CompletableFuture.completedFuture(new Stat(path, metaValue.version, metaValue.createdTimestamp, metaValue.modifiedTimestamp, metaValue.ephemeral, true));
        }
    } catch (Throwable e) {
        return FutureUtil.failedFuture(MetadataStoreException.wrap(e));
    } finally {
        dbStateLock.readLock().unlock();
    }
}
Also used : Stat(org.apache.pulsar.metadata.api.Stat) Transaction(org.rocksdb.Transaction) Notification(org.apache.pulsar.metadata.api.Notification)

Example 10 with Transaction

use of org.rocksdb.Transaction in project pulsar by apache.

the class RocksdbMetadataStore method storePut.

@Override
protected CompletableFuture<Stat> storePut(String path, byte[] data, Optional<Long> expectedVersion, EnumSet<CreateOption> options) {
    if (log.isDebugEnabled()) {
        log.debug("storePut.path={},instanceId={}", path, instanceId);
    }
    try {
        dbStateLock.readLock().lock();
        if (state == State.CLOSED) {
            throw new MetadataStoreException.AlreadyClosedException("");
        }
        try (Transaction transaction = db.beginTransaction(optionSync)) {
            byte[] pathBytes = toBytes(path);
            byte[] oldValueData = transaction.getForUpdate(optionDontCache, pathBytes, false);
            MetaValue metaValue = MetaValue.parse(oldValueData);
            if (expectedVersion.isPresent()) {
                if (metaValue == null && expectedVersion.get() != -1 || metaValue != null && !expectedVersion.get().equals(metaValue.getVersion())) {
                    throw new MetadataStoreException.BadVersionException(String.format("Version mismatch, actual=%s, expect=%s", metaValue == null ? null : metaValue.getVersion(), expectedVersion.get()));
                }
            }
            boolean created = false;
            long timestamp = System.currentTimeMillis();
            if (metaValue == null) {
                // create new node
                metaValue = new MetaValue();
                metaValue.version = 0;
                metaValue.createdTimestamp = timestamp;
                metaValue.ephemeral = options.contains(CreateOption.Ephemeral);
                if (options.contains(CreateOption.Sequential)) {
                    path += sequentialIdGenerator.getAndIncrement();
                    pathBytes = toBytes(path);
                    transaction.put(SEQUENTIAL_ID_KEY, toBytes(sequentialIdGenerator.get()));
                }
                created = true;
            } else {
                // update old node
                metaValue.version++;
            }
            metaValue.modifiedTimestamp = timestamp;
            metaValue.owner = instanceId;
            metaValue.data = data;
            // handle Sequential
            transaction.put(pathBytes, metaValue.serialize());
            transaction.commit();
            receivedNotification(new Notification(created ? NotificationType.Created : NotificationType.Modified, path));
            if (created) {
                notifyParentChildrenChanged(path);
            }
            return CompletableFuture.completedFuture(new Stat(path, metaValue.version, metaValue.createdTimestamp, metaValue.modifiedTimestamp, metaValue.ephemeral, true));
        }
    } catch (Throwable e) {
        return FutureUtil.failedFuture(MetadataStoreException.wrap(e));
    } finally {
        dbStateLock.readLock().unlock();
    }
}
Also used : Stat(org.apache.pulsar.metadata.api.Stat) Transaction(org.rocksdb.Transaction) Notification(org.apache.pulsar.metadata.api.Notification)

Aggregations

Transaction (org.rocksdb.Transaction)13 Notification (org.apache.pulsar.metadata.api.Notification)6 SneakyThrows (lombok.SneakyThrows)4 Stat (org.apache.pulsar.metadata.api.Stat)3 ByteBuf (io.netty.buffer.ByteBuf)1 ArrayList (java.util.ArrayList)1