Search in sources :

Example 6 with Text

use of com.cinchapi.concourse.server.model.Text in project concourse by cinchapi.

the class Database method getLookupRecord.

/**
 * Return a {@link Record} that is guaranteed to have the present state for
 * whether {@code value} is contained for {@code key} in {@code record}. The
 * truth of this query can be obtained using the
 * {@link Record#contains(com.cinchapi.concourse.server.io.Byteable, com.cinchapi.concourse.server.io.Byteable)}
 * method on the returned {@link Record}.
 * <p>
 * The query answered by this {@link Record} can also be answered by that
 * returned from {@link #getTableRecord(Identifier)}
 * and {@link #getTableRecord(Identifier, Text)}, but this method will
 * attempt to short circuit by not loading {@link Revisions} that don't
 * involve {@code record}, {@code key} and {@code value}. As a result, the
 * returned {@link Record} is not cached and cannot be reliably used for
 * other queries.
 * </p>
 *
 * @param record
 * @param key
 * @param value
 * @return the {@link Record}
 */
private Record<Identifier, Text, Value> getLookupRecord(Identifier record, Text key, Value value) {
    masterLock.readLock().lock();
    try {
        // First, see if there is a cached full or partial Record that can
        // allow a lookup to be performed.
        Composite c1 = Composite.create(record);
        Composite c2 = null;
        Composite c3 = null;
        Record<Identifier, Text, Value> lookup = tableCache.getIfPresent(c1);
        if (lookup == null) {
            c2 = Composite.create(record, key);
            lookup = tablePartialCache.getIfPresent(c2);
        }
        if (lookup == null) {
            // Create a LookupRecord to handle this, but DO NOT cache it
            // since it has no other utility.
            c3 = Composite.create(record, key, value);
            lookup = new LookupRecord(record, key, value);
            for (Segment segment : segments) {
                if (segment.table().mightContain(c3)) {
                    // Whenever it is possible that the LKV exists, we must
                    // gather Revisions for LK within a Record so the
                    // current state of LKV can be determined.
                    segment.table().seek(c2, lookup);
                }
            }
        }
        return lookup;
    } finally {
        masterLock.readLock().unlock();
    }
}
Also used : Identifier(com.cinchapi.concourse.server.model.Identifier) Composite(com.cinchapi.concourse.server.io.Composite) Value(com.cinchapi.concourse.server.model.Value) Text(com.cinchapi.concourse.server.model.Text) Segment(com.cinchapi.concourse.server.storage.db.kernel.Segment)

Example 7 with Text

use of com.cinchapi.concourse.server.model.Text in project concourse by cinchapi.

the class Segment method acquire.

/**
 * Append the {@code write} to this {@link Segment} using the
 * {@code executor} to asynchronously write to all the contained
 * {@link Block blocks}.
 *
 * @param write
 * @param executor
 * @return a {@link Receipt} that contains the {@link Revision Revisions}
 *         that were created as a consequence of the transfer
 * @throws InterruptedException
 */
public Receipt acquire(Write write, AwaitableExecutorService executor) throws InterruptedException {
    Preconditions.checkState(isMutable(), "Cannot transfer Writes to an immutable Segment");
    writeLock.lock();
    try {
        // @formatter:off
        Identifier record = write.getRecord();
        Text key = write.getKey();
        Value value = write.getValue();
        long version = write.getVersion();
        Action type = write.getType();
        Receipt.Builder receipt = Receipt.builder();
        Runnable[] tasks = Array.containing(() -> {
            TableArtifact artifact = table.insert(record, key, value, version, type);
            receipt.itemize(artifact);
        }, () -> {
            IndexArtifact artifact = index.insert(key, value, record, version, type);
            receipt.itemize(artifact);
        }, () -> {
            Collection<CorpusArtifact> artifacts = corpus.insert(key, value, record, version, type);
            receipt.itemize(artifacts);
        });
        // @formatter:on
        executor.await((task, error) -> Logger.error("Unexpected error when trying to transfer the following Write to the Database: {}", write, error), tasks);
        // CON-587: Set the min/max version of this Segment because it
        // cannot be assumed that revisions are inserted in monotonically
        // increasing order of version.
        maxTs = Math.max(write.getVersion(), maxTs);
        minTs = Math.min(write.getVersion(), minTs);
        return receipt.build();
    } finally {
        writeLock.unlock();
    }
}
Also used : Action(com.cinchapi.concourse.server.storage.Action) Text(com.cinchapi.concourse.server.model.Text) Identifier(com.cinchapi.concourse.server.model.Identifier) Value(com.cinchapi.concourse.server.model.Value)

Example 8 with Text

use of com.cinchapi.concourse.server.model.Text in project concourse by cinchapi.

the class Database method select.

@Override
public Map<String, Set<TObject>> select(long record, long timestamp) {
    Identifier L = Identifier.of(record);
    TableRecord table = getTableRecord(L);
    Map<Text, Set<Value>> data = table.getAll(timestamp);
    return Transformers.transformTreeMapSet(data, Text::toString, Value::getTObject, Comparators.CASE_INSENSITIVE_STRING_COMPARATOR);
}
Also used : Identifier(com.cinchapi.concourse.server.model.Identifier) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) Value(com.cinchapi.concourse.server.model.Value) Text(com.cinchapi.concourse.server.model.Text)

Example 9 with Text

use of com.cinchapi.concourse.server.model.Text in project concourse by cinchapi.

the class Database method chronologize.

@Override
public Map<Long, Set<TObject>> chronologize(String key, long record, long start, long end) {
    Identifier L = Identifier.of(record);
    Text K = Text.wrapCached(key);
    TableRecord table = getTableRecord(L);
    Map<Long, Set<Value>> data = table.chronologize(K, start, end);
    return Transformers.transformMapSet(data, Functions.identity(), Value::getTObject);
}
Also used : Identifier(com.cinchapi.concourse.server.model.Identifier) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) Value(com.cinchapi.concourse.server.model.Value) Text(com.cinchapi.concourse.server.model.Text)

Example 10 with Text

use of com.cinchapi.concourse.server.model.Text in project concourse by cinchapi.

the class AtomicOperation method grabLocks.

/**
 * Check each one of the {@link #intentions} against the
 * {@link #durable} and grab the appropriate locks along the way. This
 * method will return {@code true} if all expectations are met and all
 * necessary locks are grabbed. Otherwise it will return {@code false}, in
 * which case this operation should be aborted immediately.
 *
 * @return {@code true} if all expectations are met and all necessary locks
 *         are grabbed.
 */
private boolean grabLocks() {
    if (isReadOnly()) {
        return true;
    } else {
        // NOTE: If we can't grab a lock immediately because it is held by
        // someone else, then we must fail immediately because the
        // AtomicOperation can't properly commit.
        locks = Maps.newHashMap();
        try {
            // intentions
            for (Token token : writes2Lock) {
                if (notifiedAboutVersionChange) {
                    return false;
                }
                LockType type;
                if (token instanceof RangeToken) {
                    RangeToken rangeToken = (RangeToken) token;
                    if (!rangeReads2Lock.isEmpty(rangeToken.getKey())) {
                        Range<Value> containing = rangeReads2Lock.get(rangeToken.getKey(), rangeToken.getValues()[0]);
                        if (containing != null) {
                            rangeReads2Lock.remove(rangeToken.getKey(), containing);
                            Iterable<Range<Value>> xor = Ranges.xor(Range.singleton(rangeToken.getValues()[0]), containing);
                            for (Range<Value> range : xor) {
                                rangeReads2Lock.put(rangeToken.getKey(), range);
                            }
                        }
                    }
                    type = LockType.RANGE_WRITE;
                } else {
                    reads2Lock.remove(token);
                    type = LockType.WRITE;
                }
                LockDescription lock = LockDescription.forToken(token, lockService, rangeLockService, type);
                if (lock.getLock().tryLock()) {
                    locks.put(lock.getToken(), lock);
                } else {
                    return false;
                }
            }
            // grabbed previously.
            for (Token token : reads2Lock) {
                if (notifiedAboutVersionChange) {
                    return false;
                }
                LockDescription lock = LockDescription.forToken(token, lockService, rangeLockService, LockType.READ);
                if (lock.getLock().tryLock()) {
                    locks.put(lock.getToken(), lock);
                } else {
                    return false;
                }
            }
            // grabbed previously.
            for (Entry<Text, RangeSet<Value>> entry : rangeReads2Lock.ranges.entrySet()) {
                /* (Authorized) */
                if (notifiedAboutVersionChange) {
                    return false;
                }
                Text key = entry.getKey();
                for (Range<Value> range : entry.getValue().asRanges()) {
                    RangeToken rangeToken = Ranges.convertToRangeToken(key, range);
                    LockDescription lock = LockDescription.forToken(rangeToken, lockService, rangeLockService, LockType.RANGE_READ);
                    if (lock.getLock().tryLock()) {
                        locks.put(lock.getToken(), lock);
                    } else {
                        return false;
                    }
                }
            }
        } catch (NullPointerException e) {
            // abort immediately which means that #locks will become null.
            return false;
        }
        return true;
    }
}
Also used : RangeToken(com.cinchapi.concourse.server.concurrent.RangeToken) Value(com.cinchapi.concourse.server.model.Value) RangeSet(com.google.common.collect.RangeSet) TreeRangeSet(com.google.common.collect.TreeRangeSet) RangeToken(com.cinchapi.concourse.server.concurrent.RangeToken) Token(com.cinchapi.concourse.server.concurrent.Token) Text(com.cinchapi.concourse.server.model.Text) Range(com.google.common.collect.Range) LockType(com.cinchapi.concourse.server.concurrent.LockType)

Aggregations

Text (com.cinchapi.concourse.server.model.Text)70 Value (com.cinchapi.concourse.server.model.Value)60 Test (org.junit.Test)46 ConcourseBaseTest (com.cinchapi.concourse.test.ConcourseBaseTest)34 Identifier (com.cinchapi.concourse.server.model.Identifier)28 CountDownLatch (java.util.concurrent.CountDownLatch)22 Set (java.util.Set)10 Operator (com.cinchapi.concourse.thrift.Operator)8 LinkedHashSet (java.util.LinkedHashSet)8 Position (com.cinchapi.concourse.server.model.Position)6 TObject (com.cinchapi.concourse.thrift.TObject)6 Action (com.cinchapi.concourse.server.storage.Action)4 Write (com.cinchapi.concourse.server.storage.temp.Write)4 RangeToken (com.cinchapi.concourse.server.concurrent.RangeToken)3 Composite (com.cinchapi.concourse.server.io.Composite)3 Revision (com.cinchapi.concourse.server.storage.db.Revision)3 Range (com.google.common.collect.Range)3 Path (java.nio.file.Path)3 AwaitableExecutorService (com.cinchapi.concourse.server.concurrent.AwaitableExecutorService)2 CorpusRecord (com.cinchapi.concourse.server.storage.db.CorpusRecord)2