Package com.thinkaurelius.titan.diskstorage.idmanagement

Source Code of com.thinkaurelius.titan.diskstorage.idmanagement.TransactionalIDManager

package com.thinkaurelius.titan.diskstorage.idmanagement;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.thinkaurelius.titan.diskstorage.StaticBuffer;
import com.thinkaurelius.titan.diskstorage.StorageException;
import com.thinkaurelius.titan.diskstorage.keycolumnvalue.*;
import com.thinkaurelius.titan.diskstorage.locking.TemporaryLockingException;
import com.thinkaurelius.titan.diskstorage.util.ByteBufferUtil;
import com.thinkaurelius.titan.diskstorage.util.TimeUtility;
import com.thinkaurelius.titan.graphdb.database.idassigner.IDPoolExhaustedException;
import org.apache.commons.configuration.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
* {@link com.thinkaurelius.titan.diskstorage.IDAuthority} implementation assuming that the backing store
* supports consistent transactions.
* <p/>
* With transactional isolation guarantees, unique id block assignments are just a matter of reading the current
* counter, incrementing it and committing the transaction. If the transaction fails, another process applied for the same
* id and the process is retried.
*
* @author Matthias Broecheler (me@matthiasb.com)
*/
public class TransactionalIDManager extends AbstractIDManager {

    private static final Logger log = LoggerFactory.getLogger(TransactionalIDManager.class);

    private static final StaticBuffer DEFAULT_COLUMN = ByteBufferUtil.zeroBuffer(1);

    private final StoreManager manager;
    private final KeyColumnValueStore idStore;

    public TransactionalIDManager(KeyColumnValueStore idStore, StoreManager manager, Configuration config) throws StorageException {
        super(config);
        this.manager = manager;
        this.idStore = idStore;
    }

    @Override
    public long[] getIDBlock(int partition) throws StorageException {
        long blockSize = getBlockSize(partition);
        StaticBuffer partitionKey = getPartitionKey(partition);

        for (int retry = 0; retry < idApplicationRetryCount; retry++) {
            StoreTransaction txh = null;
            try {
                txh = manager.beginTransaction(new StoreTxConfig(metricsPrefix));
                long current = getCurrentID(partitionKey, txh);
                if (Long.MAX_VALUE - blockSize <= current) {
                    throw new IDPoolExhaustedException("Exhausted id block for partition ["+partition+"]");
                }

                assert Long.MAX_VALUE - blockSize > current;
                long next = current + blockSize;
                idStore.mutate(partitionKey, ImmutableList.of(StaticBufferEntry.of(DEFAULT_COLUMN, ByteBufferUtil.getLongBuffer(next))), KeyColumnValueStore.NO_DELETIONS, txh);
                txh.commit();
                return new long[]{current, next};
            } catch (StorageException e) {
                log.warn("Storage exception while allocating id block - retrying in {} ms: {}", idApplicationWaitMS, e);
                if (txh != null) txh.rollback();
                if (idApplicationWaitMS > 0)
                    TimeUtility.INSTANCE.sleepUntil(System.currentTimeMillis() + idApplicationWaitMS, log);
            }
        }
        throw new TemporaryLockingException("Exceeded timeout count [" + idApplicationRetryCount + "] when attempting to allocate next id block");
    }

    @Override
    public StaticBuffer[] getLocalIDPartition() throws StorageException {
        return idStore.getLocalKeyPartition();
    }

    @Override
    public void close() throws StorageException {
        idStore.close();
    }

    private long getCurrentID(StaticBuffer partitionKey, StoreTransaction txh) throws StorageException {
        if (!KCVSUtil.containsKeyColumn(idStore, partitionKey, DEFAULT_COLUMN, txh)) {
            return BASE_ID;
        } else {
            long current = KCVSUtil.get(idStore, partitionKey, DEFAULT_COLUMN, txh).getLong(0);
            return current;
        }
    }
}
TOP

Related Classes of com.thinkaurelius.titan.diskstorage.idmanagement.TransactionalIDManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.