org.apache.accumulo.core.data.ConditionalMutation Java Examples

The following examples show how to use org.apache.accumulo.core.data.ConditionalMutation. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: PcjTables.java    From rya with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a {@link ConditionalMutation} that only updates the cardinality
 * of the PCJ table if the old value has not changed by the time this mutation
 * is committed to Accumulo.
 *
 * @param current - The current cardinality value.
 * @param delta - How much the cardinality will change.
 * @return The mutation that will perform the conditional update.
 */
private static ConditionalMutation makeUpdateCardinalityMutation(final long current, final long delta) {
    // Try to update the cardinality by the delta.
    final ConditionalMutation mutation = new ConditionalMutation(PCJ_METADATA_ROW_ID);
    final Condition lastCardinalityStillCurrent = new Condition(
            PCJ_METADATA_FAMILY,
            PCJ_METADATA_CARDINALITY);

    // Require the old cardinality to be the value we just read.
    final byte[] currentCardinalityBytes = longLexicoder.encode( current );
    lastCardinalityStillCurrent.setValue( currentCardinalityBytes );
    mutation.addCondition(lastCardinalityStillCurrent);

    // If that is the case, then update to the new value.
    final Value newCardinality = new Value( longLexicoder.encode(current + delta) );
    mutation.put(PCJ_METADATA_FAMILY, PCJ_METADATA_CARDINALITY, newCardinality);
    return mutation;
}
 
Example #2
Source File: TransactionImpl.java    From fluo with Apache License 2.0 6 votes vote down vote up
@Override
CompletableFuture<Void> getFailureOp(CommitData cd) {
  // TODO can this be simplified by pushing some code to the superclass?
  return CompletableFuture.supplyAsync(() -> {
    final ConditionalMutation pcm = Iterables.getOnlyElement(createMutations(cd));

    cd.addPrimaryToRejected();
    getStats().setRejected(cd.getRejected());
    // TODO do async
    try {
      checkForOrphanedLocks(cd);
    } catch (Exception e) {
      throw new CompletionException(e);
    }
    if (checkForAckCollision(pcm)) {
      cd.commitObserver.alreadyAcknowledged();
    } else {
      cd.commitObserver.commitFailed(cd.getShortCollisionMessage());
    }

    return null;
  }, env.getSharedResources().getSyncCommitExecutor());
}
 
Example #3
Source File: TransactionImpl.java    From fluo with Apache License 2.0 6 votes vote down vote up
@Override
public Collection<ConditionalMutation> createMutations(CommitData cd) {

  ArrayList<ConditionalMutation> mutations = new ArrayList<>();

  for (Entry<Bytes, Map<Column, Bytes>> rowUpdates : updates.entrySet()) {
    ConditionalFlutation cm = null;

    for (Entry<Column, Bytes> colUpdates : rowUpdates.getValue().entrySet()) {
      if (cm == null) {
        cm = prewrite(rowUpdates.getKey(), colUpdates.getKey(), colUpdates.getValue(), cd.prow,
            cd.pcol, false);
      } else {
        prewrite(cm, colUpdates.getKey(), colUpdates.getValue(), cd.prow, cd.pcol, false);
      }
    }

    mutations.add(cm);
  }

  cd.acceptedRows = new HashSet<>();

  return mutations;
}
 
Example #4
Source File: TransactionImpl.java    From fluo with Apache License 2.0 6 votes vote down vote up
@Override
public Collection<ConditionalMutation> createMutations(CommitData cd) {
  long commitTs = getStats().getCommitTs();
  IteratorSetting iterConf = new IteratorSetting(10, PrewriteIterator.class);
  PrewriteIterator.setSnaptime(iterConf, startTs);
  boolean isTrigger = isTriggerRow(cd.prow) && cd.pcol.equals(notification.getColumn());

  Condition lockCheck =
      new FluoCondition(env, cd.pcol).setIterators(iterConf).setValue(LockValue.encode(cd.prow,
          cd.pcol, isWrite(cd.pval), isDelete(cd.pval), isTrigger, getTransactorID()));
  final ConditionalMutation delLockMutation = new ConditionalFlutation(env, cd.prow, lockCheck);

  ColumnUtil.commitColumn(env, isTrigger, true, cd.pcol, isWrite(cd.pval), isDelete(cd.pval),
      isReadLock(cd.pval), startTs, commitTs, observedColumns, delLockMutation);

  return Collections.singletonList(delLockMutation);
}
 
Example #5
Source File: AsyncConditionalWriter.java    From fluo with Apache License 2.0 6 votes vote down vote up
public CompletableFuture<Iterator<Result>> apply(Collection<ConditionalMutation> input) {
  if (input.isEmpty()) {
    return CompletableFuture.completedFuture(Collections.<Result>emptyList().iterator());
  }

  semaphore.acquire(input.size());
  Iterator<Result> iter = cw.write(input.iterator());
  return CompletableFuture.supplyAsync(() -> {
    try {
      Builder<Result> imlb = ImmutableList.builder();
      while (iter.hasNext()) {
        Result result = iter.next();
        imlb.add(result);
      }
      return imlb.build().iterator();
    } finally {
      semaphore.release(input.size());
    }
  }, es);
}
 
Example #6
Source File: FaultyConfig.java    From fluo with Apache License 2.0 5 votes vote down vote up
@Override
public Iterator<Result> write(Iterator<ConditionalMutation> mutations) {
  ArrayList<Result> resultList = new ArrayList<>();
  ArrayList<ConditionalMutation> writes = new ArrayList<>();

  while (mutations.hasNext()) {
    ConditionalMutation cm = mutations.next();
    if (rand.nextDouble() <= up && rand.nextDouble() > wp) {
      resultList.add(new Result(Status.UNKNOWN, cm, null));
    } else {
      writes.add(cm);
    }
  }

  if (!writes.isEmpty()) {
    Iterator<Result> results = cw.write(writes.iterator());

    while (results.hasNext()) {
      Result result = results.next();

      if (rand.nextDouble() <= up && rand.nextDouble() <= wp) {
        result = new Result(Status.UNKNOWN, result.getMutation(), result.getTabletServer());
      }
      resultList.add(result);
    }
  }
  return resultList.iterator();
}
 
Example #7
Source File: TransactionImpl.java    From fluo with Apache License 2.0 5 votes vote down vote up
@Override
public Iterator<Result> handleUnknown(CommitData cd, Iterator<Result> results)
    throws Exception {
  // the code for handing this is synchronous and needs to be handled in another thread pool
  // TODO - how do we do the above without return a CF?
  long commitTs = getStats().getCommitTs();
  Result result = Iterators.getOnlyElement(results);
  Status ms = result.getStatus();

  while (ms == Status.UNKNOWN) {

    // TODO async
    TxInfo txInfo = TxInfo.getTransactionInfo(env, cd.prow, cd.pcol, startTs);

    switch (txInfo.status) {
      case COMMITTED:
        if (txInfo.commitTs != commitTs) {
          throw new IllegalStateException(
              cd.prow + " " + cd.pcol + " " + txInfo.commitTs + "!=" + commitTs);
        }
        ms = Status.ACCEPTED;
        break;
      case LOCKED:
        // TODO async
        ConditionalMutation delLockMutation = result.getMutation();
        ms = cd.cw.write(delLockMutation).getStatus();
        break;
      default:
        ms = Status.REJECTED;
    }
  }
  Result newResult = new Result(ms, result.getMutation(), result.getTabletServer());
  return Collections.singletonList(newResult).iterator();
}
 
Example #8
Source File: ARS.java    From accumulo-examples with Apache License 2.0 4 votes vote down vote up
public void cancel(String what, String when, String who) throws Exception {

    String row = what + ":" + when;

    // Even though this method is only deleting a column, its important to use a conditional writer.
    // By updating the seq # when deleting a reservation, it
    // will cause any concurrent reservations to retry. If this delete were done using a batch
    // writer, then a concurrent reservation could report WAIT_LISTED
    // when it actually got the reservation.

    // its important to use an isolated scanner so that only whole mutations are seen
    try (
        ConditionalWriter cwriter = client.createConditionalWriter(rTable,
            new ConditionalWriterConfig());
        Scanner scanner = new IsolatedScanner(client.createScanner(rTable, Authorizations.EMPTY))) {
      while (true) {
        scanner.setRange(new Range(row));

        int seq = -1;
        String reservation = null;

        for (Entry<Key,Value> entry : scanner) {
          String cf = entry.getKey().getColumnFamilyData().toString();
          String cq = entry.getKey().getColumnQualifierData().toString();
          String val = entry.getValue().toString();

          // EXCERCISE avoid linear scan

          if (cf.equals("tx") && cq.equals("seq")) {
            seq = Integer.parseInt(val);
          } else if (cf.equals("res") && val.equals(who)) {
            reservation = cq;
          }
        }

        if (reservation != null) {
          ConditionalMutation update = new ConditionalMutation(row,
              new Condition("tx", "seq").setValue(seq + ""));
          update.putDelete("res", reservation);
          update.put("tx", "seq", (seq + 1) + "");

          Status status = cwriter.write(update).getStatus();
          switch (status) {
            case ACCEPTED:
              // successfully canceled reservation
              return;
            case REJECTED:
            case UNKNOWN:
              // retry
              // EXCERCISE exponential back-off could be used here
              break;
            default:
              throw new RuntimeException("Unexpected status " + status);
          }

        } else {
          // not reserved, nothing to do
          break;
        }

      }
    }
  }
 
Example #9
Source File: AccumuloRyaInstanceDetailsRepository.java    From rya with Apache License 2.0 4 votes vote down vote up
@Override
public void update(final RyaDetails oldDetails, final RyaDetails newDetails)
        throws NotInitializedException, ConcurrentUpdateException, RyaDetailsRepositoryException {
    // Preconditions.
    requireNonNull(oldDetails);
    requireNonNull(newDetails);

    if(!newDetails.getRyaInstanceName().equals( instanceName )) {
        throw new RyaDetailsRepositoryException("The instance name that was in the provided 'newDetails' does not match " +
                "the instance name that this repository is connected to. Make sure you're connected to the" +
                "correct Rya instance.");
    }

    if(!isInitialized()) {
        throw new NotInitializedException("Could not update the details for the Rya instanced named '" +
                instanceName + "' because it has not been initialized yet.");
    }

    // Use a conditional writer so that we can detect when the old details
    // are no longer the currently stored ones.
    ConditionalWriter writer = null;
    try {
        // Setup the condition that ensures the details have not changed since the edits were made.
        final byte[] oldDetailsBytes = serializer.serialize(oldDetails);
        final Condition condition = new Condition(COL_FAMILY, COL_QUALIFIER);
        condition.setValue( oldDetailsBytes );

        // Create the mutation that only performs the update if the details haven't changed.
        final ConditionalMutation mutation = new ConditionalMutation(ROW_ID);
        mutation.addCondition( condition );
        final byte[] newDetailsBytes = serializer.serialize(newDetails);
        mutation.put(COL_FAMILY, COL_QUALIFIER, new Value(newDetailsBytes));

        // Do the write.
        writer = connector.createConditionalWriter(detailsTableName, new ConditionalWriterConfig());
        final Result result = writer.write(mutation);
        switch(result.getStatus()) {
            case REJECTED:
            case VIOLATED:
                throw new ConcurrentUpdateException("Could not update the details for the Rya instance named '" +
                        instanceName + "' because the old value is out of date.");
            case UNKNOWN:
            case INVISIBLE_VISIBILITY:
                throw new RyaDetailsRepositoryException("Could not update the details for the Rya instance named '" + instanceName + "'.");
        }
    } catch (final TableNotFoundException | AccumuloException | AccumuloSecurityException e) {
        throw new RyaDetailsRepositoryException("Could not update the details for the Rya instance named '" + instanceName + "'.");
    } finally {
        if(writer != null) {
            writer.close();
        }
    }
}
 
Example #10
Source File: PcjTables.java    From rya with Apache License 2.0 4 votes vote down vote up
/**
 * Update the cardinality of a PCJ by a {@code delta}.
 *
 * @param accumuloConn - A connection to the Accumulo that hosts the PCJ table. (not null)
 * @param pcjTableName - The name of the PCJ table that will have its cardinality updated. (not null)
 * @param delta - How much the cardinality will change.
 * @throws PCJStorageException The cardinality could not be updated.
 */
private void updateCardinality(final Connector accumuloConn, final String pcjTableName, final long delta) throws PCJStorageException {
    checkNotNull(accumuloConn);
    checkNotNull(pcjTableName);

    ConditionalWriter conditionalWriter = null;
    try {
        conditionalWriter = accumuloConn.createConditionalWriter(pcjTableName, new ConditionalWriterConfig());

        boolean updated = false;
        while (!updated) {
            // Write the conditional update request to Accumulo.
            final long cardinality = getPcjMetadata(accumuloConn,pcjTableName).getCardinality();
            final ConditionalMutation mutation = makeUpdateCardinalityMutation(cardinality, delta);
            final ConditionalWriter.Result result = conditionalWriter.write(mutation);

            // Interpret the result.
            switch (result.getStatus()) {
            case ACCEPTED:
                updated = true;
                break;
            case REJECTED:
                break;
            case UNKNOWN:
                // We do not know if the mutation succeeded. At best, we
                // can hope the metadata hasn't been updated
                // since we originally fetched it and try again.
                // Otherwise, continue forwards as if it worked. It's
                // okay if this number is slightly off.
                final long newCardinality = getPcjMetadata(accumuloConn,pcjTableName).getCardinality();
                if (newCardinality != cardinality) {
                    updated = true;
                }
                break;
            case VIOLATED:
                throw new PCJStorageException("The cardinality could not be updated because the commit violated a table constraint.");
            case INVISIBLE_VISIBILITY:
                throw new PCJStorageException("The condition contains a visibility the updater can not satisfy.");
            }
        }
    } catch (AccumuloException | AccumuloSecurityException | TableNotFoundException e) {
        throw new PCJStorageException("Could not update the cardinality value of the PCJ Table named: " + pcjTableName, e);
    } finally {
        if (conditionalWriter != null) {
            conditionalWriter.close();
        }
    }
}
 
Example #11
Source File: FaultyConfig.java    From fluo with Apache License 2.0 4 votes vote down vote up
@Override
public Result write(ConditionalMutation mutation) {
  return write(Collections.singleton(mutation).iterator()).next();
}
 
Example #12
Source File: TransactionImpl.java    From fluo with Apache License 2.0 4 votes vote down vote up
private boolean checkForAckCollision(ConditionalMutation cm) {
  Bytes row = Bytes.of(cm.getRow());

  if (isTriggerRow(row)) {
    List<ColumnUpdate> updates = cm.getUpdates();

    for (ColumnUpdate cu : updates) {
      // TODO avoid create col vis object
      Column col = new Column(Bytes.of(cu.getColumnFamily()), Bytes.of(cu.getColumnQualifier()),
          Bytes.of(cu.getColumnVisibility()));

      if (notification.getColumn().equals(col)) {
        // check to see if ACK exist after notification
        Key startKey = SpanUtil.toKey(notification.getRowColumn());
        startKey.setTimestamp(ColumnType.ACK.first());

        Key endKey = SpanUtil.toKey(notification.getRowColumn());
        endKey.setTimestamp(ColumnType.ACK.encode(notification.getTimestamp() + 1));

        Range range = new Range(startKey, endKey);

        try (Scanner scanner =
            env.getAccumuloClient().createScanner(env.getTable(), env.getAuthorizations())) {
          scanner.setRange(range);

          // TODO could use iterator that stops after 1st ACK. thought of using versioning iter
          // but
          // it scans to ACK
          if (scanner.iterator().hasNext()) {
            env.getSharedResources().getBatchWriter()
                .writeMutationAsync(notification.newDelete(env));
            return true;
          }
        } catch (TableNotFoundException e) {
          // TODO proper exception handling
          throw new RuntimeException(e);
        }
      }
    }
  }

  return false;
}
 
Example #13
Source File: TransactionImpl.java    From fluo with Apache License 2.0 4 votes vote down vote up
@Override
public Collection<ConditionalMutation> createMutations(CommitData cd) {
  return Collections
      .singleton(prewrite(cd.prow, cd.pcol, cd.pval, cd.prow, cd.pcol, isTriggerRow(cd.prow)));
}
 
Example #14
Source File: TransactionImpl.java    From fluo with Apache License 2.0 votes vote down vote up
public abstract Collection<ConditionalMutation> createMutations(CommitData cd);