Search in sources :

Example 16 with StaticBuffer

use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project titan by thinkaurelius.

the class KCVSConfiguration method get.

/**
     * Reads the configuration property for this StoreManager
     *
     * @param key Key identifying the configuration property
     * @return Value stored for the key or null if the configuration property has not (yet) been defined.
     * @throws com.thinkaurelius.titan.diskstorage.BackendException
     */
@Override
public <O> O get(final String key, final Class<O> datatype) {
    StaticBuffer column = string2StaticBuffer(key);
    final KeySliceQuery query = new KeySliceQuery(rowKey, column, BufferUtil.nextBiggerBuffer(column));
    StaticBuffer result = BackendOperation.execute(new BackendOperation.Transactional<StaticBuffer>() {

        @Override
        public StaticBuffer call(StoreTransaction txh) throws BackendException {
            List<Entry> entries = store.getSlice(query, txh);
            if (entries.isEmpty())
                return null;
            return entries.get(0).getValueAs(StaticBuffer.STATIC_FACTORY);
        }

        @Override
        public String toString() {
            return "getConfiguration";
        }
    }, txProvider, times, maxOperationWaitTime);
    if (result == null)
        return null;
    return staticBuffer2Object(result, datatype);
}
Also used : StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) ArrayList(java.util.ArrayList) List(java.util.List) BackendOperation(com.thinkaurelius.titan.diskstorage.util.BackendOperation) BackendException(com.thinkaurelius.titan.diskstorage.BackendException)

Example 17 with StaticBuffer

use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project titan by thinkaurelius.

the class ColumnValueStore method mutate.

synchronized void mutate(List<Entry> additions, List<StaticBuffer> deletions, StoreTransaction txh) {
    //Prepare data
    Entry[] add;
    if (!additions.isEmpty()) {
        add = new Entry[additions.size()];
        int pos = 0;
        for (Entry e : additions) {
            add[pos] = e;
            pos++;
        }
        Arrays.sort(add);
    } else
        add = new Entry[0];
    //Filter out deletions that are also added
    Entry[] del;
    if (!deletions.isEmpty()) {
        del = new Entry[deletions.size()];
        int pos = 0;
        for (StaticBuffer deletion : deletions) {
            Entry delEntry = StaticArrayEntry.of(deletion);
            if (Arrays.binarySearch(add, delEntry) >= 0)
                continue;
            del[pos++] = delEntry;
        }
        if (pos < deletions.size())
            del = Arrays.copyOf(del, pos);
        Arrays.sort(del);
    } else
        del = new Entry[0];
    Lock lock = getLock(txh);
    lock.lock();
    try {
        Entry[] olddata = data.array;
        int oldsize = data.size;
        Entry[] newdata = new Entry[oldsize + add.length];
        //Merge sort
        int i = 0, iold = 0, iadd = 0, idel = 0;
        while (iold < oldsize) {
            Entry e = olddata[iold];
            iold++;
            //Compare with additions
            if (iadd < add.length) {
                int compare = e.compareTo(add[iadd]);
                if (compare >= 0) {
                    e = add[iadd];
                    iadd++;
                    //Skip duplicates
                    while (iadd < add.length && e.equals(add[iadd])) iadd++;
                }
                if (compare > 0)
                    iold--;
            }
            //Compare with deletions
            if (idel < del.length) {
                int compare = e.compareTo(del[idel]);
                if (compare == 0)
                    e = null;
                if (compare >= 0)
                    idel++;
            }
            if (e != null) {
                newdata[i] = e;
                i++;
            }
        }
        while (iadd < add.length) {
            newdata[i] = add[iadd];
            i++;
            iadd++;
        }
        if (i * 1.0 / newdata.length < SIZE_THRESHOLD) {
            //shrink array to free space
            Entry[] tmpdata = newdata;
            newdata = new Entry[i];
            System.arraycopy(tmpdata, 0, newdata, 0, i);
        }
        data = new Data(newdata, i);
    } finally {
        lock.unlock();
    }
}
Also used : Entry(com.thinkaurelius.titan.diskstorage.Entry) StaticArrayEntry(com.thinkaurelius.titan.diskstorage.util.StaticArrayEntry) StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Lock(java.util.concurrent.locks.Lock) NoLock(com.thinkaurelius.titan.diskstorage.util.NoLock)

Example 18 with StaticBuffer

use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project titan by thinkaurelius.

the class ConsistentKeyLockerSerializer method fromLockColumn.

public TimestampRid fromLockColumn(StaticBuffer lockKey, TimestampProvider provider) {
    ReadBuffer r = lockKey.asReadBuffer();
    int len = r.length();
    long tsNS = r.getLong();
    len -= 8;
    byte[] curRid = new byte[len];
    for (int i = 0; r.hasRemaining(); i++) {
        curRid[i] = r.getByte();
    }
    StaticBuffer rid = new StaticArrayBuffer(curRid);
    Instant time = provider.getTime(tsNS);
    return new TimestampRid(time, rid);
}
Also used : ReadBuffer(com.thinkaurelius.titan.diskstorage.ReadBuffer) Instant(java.time.Instant) StaticArrayBuffer(com.thinkaurelius.titan.diskstorage.util.StaticArrayBuffer) StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer)

Example 19 with StaticBuffer

use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project incubator-atlas by apache.

the class HBaseStoreManager method normalizeKeyBounds.

/**
     * Given a map produced by {@link HTable#getRegionLocations()}, transform
     * each key from an {@link HRegionInfo} to a {@link KeyRange} expressing the
     * region's start and end key bounds using Titan-partitioning-friendly
     * conventions (start inclusive, end exclusive, zero bytes appended where
     * necessary to make all keys at least 4 bytes long).
     * <p/>
     * This method iterates over the entries in its map parameter and performs
     * the following conditional conversions on its keys. "Require" below means
     * either a {@link Preconditions} invocation or an assertion. HRegionInfo
     * sometimes returns start and end keys of zero length; this method replaces
     * zero length keys with null before doing any of the checks described
     * below. The parameter map and the values it contains are only read and
     * never modified.
     *
     * <ul>
     * <li>If an entry's HRegionInfo has null start and end keys, then first
     * require that the parameter map is a singleton, and then return a
     * single-entry map whose {@code KeyRange} has start and end buffers that
     * are both four bytes of zeros.</li>
     * <li>If the entry has a null end key (but non-null start key), put an
     * equivalent entry in the result map with a start key identical to the
     * input, except that zeros are appended to values less than 4 bytes long,
     * and an end key that is four bytes of zeros.
     * <li>If the entry has a null start key (but non-null end key), put an
     * equivalent entry in the result map where the start key is four bytes of
     * zeros, and the end key has zeros appended, if necessary, to make it at
     * least 4 bytes long, after which one is added to the padded value in
     * unsigned 32-bit arithmetic with overflow allowed.</li>
     * <li>Any entry which matches none of the above criteria results in an
     * equivalent entry in the returned map, except that zeros are appended to
     * both keys to make each at least 4 bytes long, and the end key is then
     * incremented as described in the last bullet point.</li>
     * </ul>
     *
     * After iterating over the parameter map, this method checks that it either
     * saw no entries with null keys, one entry with a null start key and a
     * different entry with a null end key, or one entry with both start and end
     * keys null. If any null keys are observed besides these three cases, the
     * method will die with a precondition failure.
     *
     * @param raw
     *            A map of HRegionInfo and ServerName from HBase
     * @return Titan-friendly expression of each region's rowkey boundaries
     */
private Map<KeyRange, ServerName> normalizeKeyBounds(NavigableMap<HRegionInfo, ServerName> raw) {
    Map.Entry<HRegionInfo, ServerName> nullStart = null;
    Map.Entry<HRegionInfo, ServerName> nullEnd = null;
    ImmutableMap.Builder<KeyRange, ServerName> b = ImmutableMap.builder();
    for (Map.Entry<HRegionInfo, ServerName> e : raw.entrySet()) {
        HRegionInfo regionInfo = e.getKey();
        byte[] startKey = regionInfo.getStartKey();
        byte[] endKey = regionInfo.getEndKey();
        if (0 == startKey.length) {
            startKey = null;
            logger.trace("Converted zero-length HBase startKey byte array to null");
        }
        if (0 == endKey.length) {
            endKey = null;
            logger.trace("Converted zero-length HBase endKey byte array to null");
        }
        if (null == startKey && null == endKey) {
            Preconditions.checkState(1 == raw.size());
            logger.debug("HBase table {} has a single region {}", tableName, regionInfo);
            // Choose arbitrary shared value = startKey = endKey
            return b.put(new KeyRange(FOUR_ZERO_BYTES, FOUR_ZERO_BYTES), e.getValue()).build();
        } else if (null == startKey) {
            logger.debug("Found HRegionInfo with null startKey on server {}: {}", e.getValue(), regionInfo);
            Preconditions.checkState(null == nullStart);
            nullStart = e;
            // I thought endBuf would be inclusive from the HBase javadoc, but in practice it is exclusive
            StaticBuffer endBuf = StaticArrayBuffer.of(zeroExtend(endKey));
            // Replace null start key with zeroes
            b.put(new KeyRange(FOUR_ZERO_BYTES, endBuf), e.getValue());
        } else if (null == endKey) {
            logger.debug("Found HRegionInfo with null endKey on server {}: {}", e.getValue(), regionInfo);
            Preconditions.checkState(null == nullEnd);
            nullEnd = e;
            // Replace null end key with zeroes
            b.put(new KeyRange(StaticArrayBuffer.of(zeroExtend(startKey)), FOUR_ZERO_BYTES), e.getValue());
        } else {
            Preconditions.checkState(null != startKey);
            Preconditions.checkState(null != endKey);
            // Convert HBase's inclusive end keys into exclusive Titan end keys
            StaticBuffer startBuf = StaticArrayBuffer.of(zeroExtend(startKey));
            StaticBuffer endBuf = StaticArrayBuffer.of(zeroExtend(endKey));
            KeyRange kr = new KeyRange(startBuf, endBuf);
            b.put(kr, e.getValue());
            logger.debug("Found HRegionInfo with non-null end and start keys on server {}: {}", e.getValue(), regionInfo);
        }
    }
    // Require either no null key bounds or a pair of them
    Preconditions.checkState((null == nullStart) == (null == nullEnd));
    // Check that every key in the result is at least 4 bytes long
    Map<KeyRange, ServerName> result = b.build();
    for (KeyRange kr : result.keySet()) {
        Preconditions.checkState(4 <= kr.getStart().length());
        Preconditions.checkState(4 <= kr.getEnd().length());
    }
    return result;
}
Also used : HRegionInfo(org.apache.hadoop.hbase.HRegionInfo) ServerName(org.apache.hadoop.hbase.ServerName) KeyRange(com.thinkaurelius.titan.diskstorage.keycolumnvalue.KeyRange) StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) Map(java.util.Map) BiMap(com.google.common.collect.BiMap) ImmutableMap(com.google.common.collect.ImmutableMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) NavigableMap(java.util.NavigableMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) ImmutableBiMap(com.google.common.collect.ImmutableBiMap) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 20 with StaticBuffer

use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project incubator-atlas by apache.

the class HBaseStoreManager method mutateMany.

@Override
public void mutateMany(Map<String, Map<StaticBuffer, KCVMutation>> mutations, StoreTransaction txh) throws BackendException {
    logger.debug("Enter mutateMany");
    final MaskedTimestamp commitTime = new MaskedTimestamp(txh);
    // In case of an addition and deletion with identical timestamps, the
    // deletion tombstone wins.
    // http://hbase.apache.org/book/versions.html#d244e4250
    Map<StaticBuffer, Pair<Put, Delete>> commandsPerKey = convertToCommands(mutations, commitTime.getAdditionTime(times.getUnit()), commitTime.getDeletionTime(times.getUnit()));
    // actual batch operation
    List<Row> batch = new ArrayList<>(commandsPerKey.size());
    // convert sorted commands into representation required for 'batch' operation
    for (Pair<Put, Delete> commands : commandsPerKey.values()) {
        if (commands.getFirst() != null)
            batch.add(commands.getFirst());
        if (commands.getSecond() != null)
            batch.add(commands.getSecond());
    }
    try {
        TableMask table = null;
        try {
            table = cnx.getTable(tableName);
            logger.debug("mutateMany : batch mutate started size {} ", batch.size());
            table.batch(batch, new Object[batch.size()]);
            logger.debug("mutateMany : batch mutate finished {} ", batch.size());
        } finally {
            IOUtils.closeQuietly(table);
        }
    } catch (IOException | InterruptedException e) {
        throw new TemporaryBackendException(e);
    }
    sleepAfterWrite(txh, commitTime);
}
Also used : Delete(org.apache.hadoop.hbase.client.Delete) ArrayList(java.util.ArrayList) IOException(java.io.IOException) Put(org.apache.hadoop.hbase.client.Put) TemporaryBackendException(com.thinkaurelius.titan.diskstorage.TemporaryBackendException) StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) Row(org.apache.hadoop.hbase.client.Row) Pair(org.apache.hadoop.hbase.util.Pair)

Aggregations

StaticBuffer (com.thinkaurelius.titan.diskstorage.StaticBuffer)44 Entry (com.thinkaurelius.titan.diskstorage.Entry)13 Test (org.junit.Test)12 ArrayList (java.util.ArrayList)9 DataOutput (com.thinkaurelius.titan.graphdb.database.serialize.DataOutput)8 ReadBuffer (com.thinkaurelius.titan.diskstorage.ReadBuffer)7 Map (java.util.Map)7 ImmutableMap (com.google.common.collect.ImmutableMap)6 Instant (java.time.Instant)6 HashMap (java.util.HashMap)6 KeyRange (com.thinkaurelius.titan.diskstorage.keycolumnvalue.KeyRange)5 BiMap (com.google.common.collect.BiMap)4 ImmutableBiMap (com.google.common.collect.ImmutableBiMap)4 EntryList (com.thinkaurelius.titan.diskstorage.EntryList)4 KeySliceQuery (com.thinkaurelius.titan.diskstorage.keycolumnvalue.KeySliceQuery)4 SliceQuery (com.thinkaurelius.titan.diskstorage.keycolumnvalue.SliceQuery)4 Delete (org.apache.hadoop.hbase.client.Delete)4 Put (org.apache.hadoop.hbase.client.Put)4 Pair (org.apache.hadoop.hbase.util.Pair)4 ImmutableList (com.google.common.collect.ImmutableList)3