Java Code Examples for org.apache.accumulo.core.data.Mutation#putDelete()

The following examples show how to use org.apache.accumulo.core.data.Mutation#putDelete() . 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: AbstractFunctionalQuery.java    From datawave with Apache License 2.0 6 votes vote down vote up
protected Multimap<String,Key> removeMetadataEntries(Set<String> fields, Text cf) throws AccumuloSecurityException, AccumuloException,
                TableNotFoundException {
    Multimap<String,Key> metadataEntries = HashMultimap.create();
    MultiTableBatchWriter multiTableWriter = connector.createMultiTableBatchWriter(new BatchWriterConfig());
    BatchWriter writer = multiTableWriter.getBatchWriter(QueryTestTableHelper.METADATA_TABLE_NAME);
    for (String field : fields) {
        Mutation mutation = new Mutation(new Text(field));
        Scanner scanner = connector.createScanner(QueryTestTableHelper.METADATA_TABLE_NAME, new Authorizations());
        scanner.fetchColumnFamily(cf);
        scanner.setRange(new Range(new Text(field)));
        boolean foundEntries = false;
        for (Map.Entry<Key,Value> entry : scanner) {
            foundEntries = true;
            metadataEntries.put(field, entry.getKey());
            mutation.putDelete(entry.getKey().getColumnFamily(), entry.getKey().getColumnQualifier(), entry.getKey().getColumnVisibilityParsed());
        }
        scanner.close();
        if (foundEntries) {
            writer.addMutation(mutation);
        }
    }
    writer.close();
    connector.tableOperations().compact(QueryTestTableHelper.METADATA_TABLE_NAME, new Text("\0"), new Text("~"), true, true);
    return metadataEntries;
}
 
Example 2
Source File: ElementMutationBuilder.java    From vertexium with Apache License 2.0 6 votes vote down vote up
public boolean alterElementVisibility(Mutation m, AccumuloElement element, Visibility newVisibility, Object data) {
    ColumnVisibility currentColumnVisibility = visibilityToAccumuloVisibility(element.getVisibility());
    ColumnVisibility newColumnVisibility = visibilityToAccumuloVisibility(newVisibility);
    if (currentColumnVisibility.equals(newColumnVisibility)) {
        return false;
    }

    if (element instanceof AccumuloEdge) {
        AccumuloEdge edge = (AccumuloEdge) element;
        m.put(AccumuloEdge.CF_SIGNAL, new Text(edge.getLabel()), currentColumnVisibility, currentTimeMillis(), toSignalDeletedValue(data));
        m.put(AccumuloEdge.CF_SIGNAL, new Text(edge.getLabel()), newColumnVisibility, currentTimeMillis(), toSignalValue(data));

        m.putDelete(AccumuloEdge.CF_OUT_VERTEX, new Text(edge.getVertexId(Direction.OUT)), currentColumnVisibility, currentTimeMillis());
        m.put(AccumuloEdge.CF_OUT_VERTEX, new Text(edge.getVertexId(Direction.OUT)), newColumnVisibility, currentTimeMillis(), ElementMutationBuilder.EMPTY_VALUE);

        m.putDelete(AccumuloEdge.CF_IN_VERTEX, new Text(edge.getVertexId(Direction.IN)), currentColumnVisibility, currentTimeMillis());
        m.put(AccumuloEdge.CF_IN_VERTEX, new Text(edge.getVertexId(Direction.IN)), newColumnVisibility, currentTimeMillis(), ElementMutationBuilder.EMPTY_VALUE);
    } else if (element instanceof AccumuloVertex) {
        m.put(AccumuloVertex.CF_SIGNAL, EMPTY_TEXT, currentColumnVisibility, currentTimeMillis(), toSignalDeletedValue(data));
        m.put(AccumuloVertex.CF_SIGNAL, EMPTY_TEXT, newColumnVisibility, currentTimeMillis(), toSignalValue(data));
    } else {
        throw new IllegalArgumentException("Invalid element type: " + element);
    }
    return true;
}
 
Example 3
Source File: ElementMutationBuilder.java    From vertexium with Apache License 2.0 5 votes vote down vote up
public void addPropertyDeleteToMutation(Mutation m, Property property) {
    Preconditions.checkNotNull(m, "mutation cannot be null");
    Preconditions.checkNotNull(property, "property cannot be null");
    Text columnQualifier = KeyHelper.getColumnQualifierFromPropertyColumnQualifier(property, getNameSubstitutionStrategy());
    ColumnVisibility columnVisibility = visibilityToAccumuloVisibility(property.getVisibility());
    m.putDelete(AccumuloElement.CF_PROPERTY, columnQualifier, columnVisibility, currentTimeMillis());
    for (Metadata.Entry metadataEntry : property.getMetadata().entrySet()) {
        Text metadataEntryColumnQualifier = getPropertyMetadataColumnQualifierText(property, metadataEntry.getKey());
        ColumnVisibility metadataEntryVisibility = visibilityToAccumuloVisibility(metadataEntry.getVisibility());
        addPropertyMetadataItemDeleteToMutation(m, metadataEntryColumnQualifier, metadataEntryVisibility);
    }
}
 
Example 4
Source File: IndexMetadataMutator.java    From AccumuloGraph with Apache License 2.0 5 votes vote down vote up
@Override
public Iterable<Mutation> create() {
  Mutation m = new Mutation(key);
  m.putDelete(entryType.name().getBytes(),
      elementClass.getName().getBytes());
  return Lists.newArrayList(m);
}
 
Example 5
Source File: EntityCentricIndex.java    From rya with Apache License 2.0 5 votes vote down vote up
protected Mutation deleteMutation(final TripleRow tripleRow) {
    final Mutation m = new Mutation(new Text(tripleRow.getRow()));

    final byte[] columnFamily = tripleRow.getColumnFamily();
    final Text cfText = columnFamily == null ? EMPTY_TEXT : new Text(columnFamily);

    final byte[] columnQualifier = tripleRow.getColumnQualifier();
    final Text cqText = columnQualifier == null ? EMPTY_TEXT : new Text(columnQualifier);

    final byte[] columnVisibility = tripleRow.getColumnVisibility();
    final ColumnVisibility cv = columnVisibility == null ? EMPTY_CV : new ColumnVisibility(columnVisibility);

    m.putDelete(cfText, cqText, cv, tripleRow.getTimestamp());
    return m;
}
 
Example 6
Source File: MergeToolMapper.java    From rya with Apache License 2.0 5 votes vote down vote up
/**
 * Writes a mutation to the specified table.  If the mutation is meant to delete then the mutation will
 * be transformed to a delete mutation.
 * @param table the table to write to.
 * @param mutation the {@link mutation}.
 * @param context the {@link Context}.
 * @param isDelete {@code true} if the mutation should be a delete mutation.  {@code false} otherwise.
 * @throws IOException
 * @throws InterruptedException
 */
private static void writeMutation(final Text table, final Mutation mutation, final Context context, final boolean isDelete) throws IOException, InterruptedException {
    if (isDelete) {
        final List<ColumnUpdate> updates = mutation.getUpdates();
        final ColumnUpdate columnUpdate = updates.get(0);
        final ColumnVisibility cv = columnUpdate.getColumnVisibility() != null ? new ColumnVisibility(columnUpdate.getColumnVisibility()) : null;
        final Mutation deleteMutation = new Mutation(new Text(mutation.getRow()));
        deleteMutation.putDelete(columnUpdate.getColumnFamily(), columnUpdate.getColumnQualifier(), cv, columnUpdate.getTimestamp());
        context.write(table, deleteMutation);
    } else {
        context.write(table, mutation);
    }
}
 
Example 7
Source File: AccumuloRyaDAO.java    From rya with Apache License 2.0 5 votes vote down vote up
@Override
public void removeNamespace(final String pfx) throws RyaDAOException {
    try {
        final Mutation del = new Mutation(new Text(pfx));
        del.putDelete(INFO_NAMESPACE_TXT, EMPTY_TEXT);
        bw_ns.addMutation(del);
        if (flushEachUpdate.get()) {
            mt_bw.flush();
        }
    } catch (final Exception e) {
        throw new RyaDAOException(e);
    }
}
 
Example 8
Source File: IndexValueMutator.java    From AccumuloGraph with Apache License 2.0 5 votes vote down vote up
@Override
public Iterable<Mutation> create() {
  byte[] bytes = AccumuloByteSerializer.serialize(value);
  Mutation m = new Mutation(bytes);
  m.putDelete(key, element.getId().toString());
  return Lists.newArrayList(m);
}
 
Example 9
Source File: LiveContextWriter.java    From datawave with Apache License 2.0 5 votes vote down vote up
/**
 * Turn a key, value into a mutation
 * 
 * @param key
 * @param value
 * @return the mutation
 */
protected Mutation getMutation(Key key, Value value) {
    Mutation m = new Mutation(key.getRow());
    if (key.isDeleted()) {
        m.putDelete(key.getColumnFamily(), key.getColumnQualifier(), new ColumnVisibility(key.getColumnVisibility()), key.getTimestamp());
    } else {
        m.put(key.getColumnFamily(), key.getColumnQualifier(), new ColumnVisibility(key.getColumnVisibility()), key.getTimestamp(), value);
    }
    return m;
}
 
Example 10
Source File: EdgeEndpointsMutator.java    From AccumuloGraph with Apache License 2.0 5 votes vote down vote up
@Override
public Iterable<Mutation> create() {
  Mutation in = new Mutation(inVertexId);
  in.putDelete(Constants.IN_EDGE.getBytes(),
      (outVertexId + Constants.ID_DELIM + id).getBytes());

  Mutation out = new Mutation(outVertexId);
  out.putDelete(Constants.OUT_EDGE.getBytes(),
      (inVertexId + Constants.ID_DELIM + id).getBytes());

  return Lists.newArrayList(in, out);
}
 
Example 11
Source File: ElementMutationBuilder.java    From vertexium with Apache License 2.0 5 votes vote down vote up
public boolean alterEdgeVertexOutVertex(Mutation vertexOutMutation, Edge edge, Visibility newVisibility) {
    ColumnVisibility currentColumnVisibility = visibilityToAccumuloVisibility(edge.getVisibility());
    ColumnVisibility newColumnVisibility = visibilityToAccumuloVisibility(newVisibility);
    if (currentColumnVisibility.equals(newColumnVisibility)) {
        return false;
    }
    AccumuloEdgeInfo edgeInfo = new AccumuloEdgeInfo(getNameSubstitutionStrategy().deflate(edge.getLabel()), edge.getVertexId(Direction.IN));
    vertexOutMutation.putDelete(AccumuloVertex.CF_OUT_EDGE, new Text(edge.getId()), currentColumnVisibility);
    vertexOutMutation.put(AccumuloVertex.CF_OUT_EDGE, new Text(edge.getId()), newColumnVisibility, edgeInfo.toValue());
    return true;
}
 
Example 12
Source File: AccumuloRangeStore.java    From accumulo-recipes with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
@Override
public void delete(Iterable<ValueRange<T>> ranges) {
    checkNotNull(ranges);

    try {
        for (ValueRange<T> range : ranges) {

            checkState(helper.isValid(range), "Invalid Range:" + range.toString());

            String low = helper.encode(range.getStart());
            String high = helper.encode(range.getStop());

            Mutation forwardRange = new Mutation(LOWER_BOUND_INDEX + NULL_BYTE + low + NULL_BYTE + high);
            forwardRange.putDelete(new Text(""), new Text(""));

            Mutation reverseRange = new Mutation(UPPER_BOUND_INDEX + NULL_BYTE + high + NULL_BYTE + low);
            reverseRange.putDelete(new Text(""), new Text(""));

            String distanceComplement = helper.encodeComplement(helper.distance(range));
            Mutation distanceMut = new Mutation(DISTANCE_INDEX + NULL_BYTE + distanceComplement);
            distanceMut.putDelete(new Text(low), new Text(high));

            writer.addMutation(forwardRange);
            writer.addMutation(reverseRange);
            writer.addMutation(distanceMut);
        }

        writer.flush();

    } catch (RuntimeException re) {
        throw re;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
 
Example 13
Source File: RowOperations.java    From accumulo-examples with Apache License 2.0 5 votes vote down vote up
private static void deleteRow(String row, AccumuloClient client, BatchWriter bw)
    throws MutationsRejectedException, TableNotFoundException {
  Mutation mut = new Mutation(row);
  try (Scanner scanner = client.createScanner(table, Authorizations.EMPTY)) {
    scanner.setRange(Range.exact(row));
    for (Entry<Key,Value> entry : scanner) {
      mut.putDelete(entry.getKey().getColumnFamily(), entry.getKey().getColumnQualifier());
    }
  }
  bw.addMutation(mut);
  bw.flush();
}
 
Example 14
Source File: ElementMutationBuilder.java    From vertexium with Apache License 2.0 4 votes vote down vote up
private void addPropertyMetadataItemDeleteToMutation(Mutation m, Text columnQualifier, ColumnVisibility metadataVisibility) {
    m.putDelete(AccumuloElement.CF_PROPERTY_METADATA, columnQualifier, metadataVisibility, currentTimeMillis());
}
 
Example 15
Source File: ClearPropertyMutator.java    From AccumuloGraph with Apache License 2.0 4 votes vote down vote up
@Override
public Iterable<Mutation> create() {
  Mutation m = new Mutation(id);
  m.putDelete(key.getBytes(), Constants.EMPTY);
  return Lists.newArrayList(m);
}
 
Example 16
Source File: QfdHelper.java    From accumulo-recipes with Apache License 2.0 4 votes vote down vote up
private void createMutations(Iterable<T> items, boolean mutateIndices, boolean deleteItems) {
    checkNotNull(items);

    Value fiVal = new Value();
    Text forwardCQ = new Text();
    Text fieldIndexCF = new Text();
    Text fieldIndexCQ = new Text();

    try {

        for (T item : items) {

            //If there are no getAttributes then don't write anything to the data store.
            if (item.size() > 0) {
                String id = buildId(item);

                String shardId = shardBuilder.buildShard(item);

                long minExpiration = Long.MAX_VALUE;

                int time = 0;
                Mutation shardMutation = new Mutation(shardId);
                for (Attribute attribute : item.getAttributes()) {
                    String visibility = getVisibility(attribute.getMetadata(), "");
                    String aliasValue = typeRegistry.getAlias(attribute.getValue()) + ONE_BYTE +
                            typeRegistry.encode(attribute.getValue());

                    ColumnVisibility columnVisibility = new ColumnVisibility(visibility);

                    Map<String,String> meta = new HashMap<String, String>(attribute.getMetadata());
                    meta.remove(VISIBILITY);

                    Long expiration = getExpiration(meta, -1);

                    byte[] metaBytes = metadataSerDe.serialize(meta);

                    fiVal.set(expiration.toString().getBytes());

                    if(expiration > -1)
                        minExpiration = min(minExpiration, expiration);

                    forwardCQ.set(attribute.getKey() + NULL_BYTE + aliasValue);
                    fieldIndexCF.set(PREFIX_FI + NULL_BYTE + buildAttributeKey(item, attribute.getKey()));
                    fieldIndexCQ.set(aliasValue + NULL_BYTE + id);

                    long timestamp  = buildAttributeTimestampForEntity(item);

                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    DataOutputStream dout = new DataOutputStream(baos);
                    dout.writeLong(expiration);
                    dout.writeLong(timestamp);
                    dout.writeInt(metaBytes.length);
                    dout.write(metaBytes);
                    dout.flush();

                    if (deleteItems) {
                        shardMutation.putDelete(new Text(id),
                                forwardCQ,
                                columnVisibility);
                    } else {
                        shardMutation.put(new Text(id),
                                forwardCQ,
                                columnVisibility,
                                time,
                                new Value(baos.toByteArray()));
                    }

                    if(mutateIndices) {
                        if (deleteItems) {
                            shardMutation.putDelete(fieldIndexCF,
                                    fieldIndexCQ,
                                    columnVisibility,
                                    timestamp);
                        } else {
                            shardMutation.put(fieldIndexCF,
                                    fieldIndexCQ,
                                    columnVisibility,
                                    timestamp,
                                    fiVal);
                        }
                    }

                    time++;
                }

                shardWriter.addMutation(shardMutation);
            }
        }

        if (deleteItems) {
            keyValueIndex.deleteIndexKeyValues(items, mutateIndices);
        } else {
            keyValueIndex.indexKeyValues(items, mutateIndices);
        }

    } catch (RuntimeException re) {
        throw re;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
 
Example 17
Source File: Upgrade322Tool.java    From rya with Apache License 2.0 4 votes vote down vote up
@Override
protected void map(
  Key key, Value value, Context context)
  throws IOException, InterruptedException {

    //read the key, expect OSP
    final String row = key.getRow().toString();
    final int firstDelim = row.indexOf(DELIM);
    final int secondDelim = row.indexOf(DELIM, firstDelim + 1);
    final int typeDelim = row.lastIndexOf(TYPE_DELIM);
    final String oldSerialization = row.substring(0, firstDelim);
    char typeMarker = row.charAt(row.length() - 1);

    final String subject = row.substring(firstDelim + 1, secondDelim);
    final String predicate = row.substring(secondDelim + 1, typeDelim);
    final String typeSuffix = TYPE_DELIM + typeMarker;

    String newSerialization = upgradeObjectSerialization.upgrade(oldSerialization, typeMarker);
    if(newSerialization == null) {
        return;
    }

    //write out delete Mutations
    Mutation deleteOldSerialization_osp = new Mutation(key.getRow());
    deleteOldSerialization_osp.putDelete(key.getColumnFamily(), key.getColumnQualifier(),
                       key.getColumnVisibilityParsed());
    Mutation deleteOldSerialization_po = new Mutation(predicate + DELIM + oldSerialization + DELIM + subject + typeSuffix);
    deleteOldSerialization_po.putDelete(key.getColumnFamily(),
                                        key.getColumnQualifier(),
                                        key.getColumnVisibilityParsed());
    Mutation deleteOldSerialization_spo = new Mutation(subject + DELIM + predicate + DELIM + oldSerialization + typeSuffix);
    deleteOldSerialization_spo.putDelete(key.getColumnFamily(), key.getColumnQualifier(),
                                        key.getColumnVisibilityParsed());

    //write out new serialization
    Mutation putNewSerialization_osp = new Mutation(newSerialization + DELIM + subject + DELIM + predicate + typeSuffix);
    putNewSerialization_osp.put(key.getColumnFamily(),
                                key.getColumnQualifier(),
                                key.getColumnVisibilityParsed(),
                                key.getTimestamp(), value);
    Mutation putNewSerialization_po = new Mutation(predicate + DELIM + newSerialization + DELIM + subject + typeSuffix);
    putNewSerialization_po.put(key.getColumnFamily(),
                               key.getColumnQualifier(),
                               key.getColumnVisibilityParsed(),
                               key.getTimestamp(), value);
    Mutation putNewSerialization_spo = new Mutation(subject + DELIM + predicate + DELIM + newSerialization + typeSuffix);
    putNewSerialization_spo.put(key.getColumnFamily(),
                                key.getColumnQualifier(),
                                key.getColumnVisibilityParsed(),
                                key.getTimestamp(), value);

    //write out deletes to all tables
    context.write(ospTable, deleteOldSerialization_osp);
    context.write(poTable, deleteOldSerialization_po);
    context.write(spoTable, deleteOldSerialization_spo);

    //write out inserts to all tables
    context.write(ospTable, putNewSerialization_osp);
    context.write(poTable, putNewSerialization_po);
    context.write(spoTable, putNewSerialization_spo);
}
 
Example 18
Source File: ModelKeyParserTest.java    From datawave with Apache License 2.0 4 votes vote down vote up
@Before
public void setup() throws Exception {
    FORWARD_FIELD_MAPPING = new FieldMapping();
    FORWARD_FIELD_MAPPING.setColumnVisibility(COLVIZ);
    FORWARD_FIELD_MAPPING.setDatatype(DATATYPE);
    FORWARD_FIELD_MAPPING.setDirection(FORWARD);
    FORWARD_FIELD_MAPPING.setFieldName(FIELD_NAME);
    FORWARD_FIELD_MAPPING.setModelFieldName(MODEL_FIELD_NAME);
    REVERSE_FIELD_MAPPING = new FieldMapping();
    REVERSE_FIELD_MAPPING.setColumnVisibility(COLVIZ);
    REVERSE_FIELD_MAPPING.setDatatype(DATATYPE);
    REVERSE_FIELD_MAPPING.setDirection(REVERSE);
    REVERSE_FIELD_MAPPING.setFieldName(FIELD_NAME);
    REVERSE_FIELD_MAPPING.setModelFieldName(MODEL_FIELD_NAME);
    NULL_CV_MAPPING = new FieldMapping();
    NULL_CV_MAPPING.setColumnVisibility("");
    NULL_CV_MAPPING.setDatatype(DATATYPE);
    NULL_CV_MAPPING.setDirection(REVERSE);
    NULL_CV_MAPPING.setFieldName(FIELD_NAME);
    NULL_CV_MAPPING.setModelFieldName(MODEL_FIELD_NAME);
    FORWARD_KEY = new Key(MODEL_FIELD_NAME, MODEL_NAME + ModelKeyParser.NULL_BYTE + DATATYPE, FIELD_NAME + ModelKeyParser.NULL_BYTE + FORWARD.getValue(),
                    COLVIZ, TIMESTAMP);
    REVERSE_KEY = new Key(FIELD_NAME, MODEL_NAME + ModelKeyParser.NULL_BYTE + DATATYPE, MODEL_FIELD_NAME + ModelKeyParser.NULL_BYTE + REVERSE.getValue(),
                    COLVIZ, TIMESTAMP);
    NULL_CV_KEY = new Key(FIELD_NAME, MODEL_NAME + ModelKeyParser.NULL_BYTE + DATATYPE, MODEL_FIELD_NAME + ModelKeyParser.NULL_BYTE + REVERSE.getValue(),
                    "", TIMESTAMP);
    FORWARD_MUTATION = new Mutation(MODEL_FIELD_NAME);
    FORWARD_MUTATION.put(MODEL_NAME + ModelKeyParser.NULL_BYTE + DATATYPE, FIELD_NAME + ModelKeyParser.NULL_BYTE + FORWARD.getValue(),
                    new ColumnVisibility(COLVIZ), TIMESTAMP, ModelKeyParser.NULL_VALUE);
    FORWARD_DELETE_MUTATION = new Mutation(MODEL_FIELD_NAME);
    FORWARD_DELETE_MUTATION.putDelete(MODEL_NAME + ModelKeyParser.NULL_BYTE + DATATYPE, FIELD_NAME + ModelKeyParser.NULL_BYTE + FORWARD.getValue(),
                    new ColumnVisibility(COLVIZ), TIMESTAMP);
    FORWARD_DELETE_MUTATION.putDelete(MODEL_NAME + ModelKeyParser.NULL_BYTE + DATATYPE, FIELD_NAME + ModelKeyParser.NULL_BYTE + "index_only"
                    + ModelKeyParser.NULL_BYTE + FORWARD.getValue(), new ColumnVisibility(COLVIZ), TIMESTAMP);
    
    REVERSE_MUTATION = new Mutation(FIELD_NAME);
    REVERSE_MUTATION.put(MODEL_NAME + ModelKeyParser.NULL_BYTE + DATATYPE, MODEL_FIELD_NAME + ModelKeyParser.NULL_BYTE + REVERSE.getValue(),
                    new ColumnVisibility(COLVIZ), TIMESTAMP, ModelKeyParser.NULL_VALUE);
    REVERSE_DELETE_MUTATION = new Mutation(FIELD_NAME);
    REVERSE_DELETE_MUTATION.putDelete(MODEL_NAME + ModelKeyParser.NULL_BYTE + DATATYPE, MODEL_FIELD_NAME + ModelKeyParser.NULL_BYTE + REVERSE.getValue(),
                    new ColumnVisibility(COLVIZ), TIMESTAMP);
    
    PowerMock.mockStatic(System.class, System.class.getMethod("currentTimeMillis"));
}
 
Example 19
Source File: AccumuloFreeTextIndexer.java    From rya with Apache License 2.0 4 votes vote down vote up
private static Mutation createEmptyPutDeleteMutation(final Text row) {
    final Mutation m = new Mutation(row);
    m.putDelete(EMPTY_TEXT, EMPTY_TEXT);
    return m;
}
 
Example 20
Source File: AccumuloFreeTextIndexer.java    From rya with Apache License 2.0 4 votes vote down vote up
private void deleteStatement(final Statement statement) throws IOException {
    Objects.requireNonNull(mtbw, "Freetext indexer attempting to delete, but setMultiTableBatchWriter() was not set.");

    // if the predicate list is empty, accept all predicates.
    // Otherwise, make sure the predicate is on the "valid" list
    final boolean isValidPredicate = validPredicates.isEmpty() || validPredicates.contains(statement.getPredicate());

    if (isValidPredicate && (statement.getObject() instanceof Literal)) {

        // Get the tokens
        final String text = statement.getObject().stringValue().toLowerCase();
        final SortedSet<String> tokens = tokenizer.tokenize(text);

        if (!tokens.isEmpty()) {
            // Get Document Data
            final String docContent = StatementSerializer.writeStatement(statement);

            final String docId = Md5Hash.md5Base64(docContent);

            // Setup partition
            final Text partition = genPartition(docContent.hashCode(), docTableNumPartitions);

            final Mutation docTableMut = new Mutation(partition);
            final List<Mutation> termTableMutations = new ArrayList<Mutation>();

            final Text docIdText = new Text(docId);

            // Delete the Document Data
            docTableMut.putDelete(ColumnPrefixes.DOCS_CF_PREFIX, docIdText);

            // Delete the statement parts in index
            docTableMut.putDelete(ColumnPrefixes.getSubjColFam(statement), docIdText);
            docTableMut.putDelete(ColumnPrefixes.getPredColFam(statement), docIdText);
            docTableMut.putDelete(ColumnPrefixes.getObjColFam(statement), docIdText);
            docTableMut.putDelete(ColumnPrefixes.getContextColFam(statement), docIdText);


            // Delete the statement terms in index
            for (final String token : tokens) {
                if (IS_TERM_TABLE_TOKEN_DELETION_ENABLED) {
                    final int rowId = Integer.parseInt(partition.toString());
                    final boolean doesTermExistInOtherDocs = doesTermExistInOtherDocs(token, rowId, docIdText);
                    // Only delete the term from the term table if it doesn't appear in other docs
                    if (!doesTermExistInOtherDocs) {
                        // Delete the term in the term table
                        termTableMutations.add(createEmptyPutDeleteMutation(ColumnPrefixes.getTermListColFam(token)));
                        termTableMutations.add(createEmptyPutDeleteMutation(ColumnPrefixes.getRevTermListColFam(token)));
                    }
                }

                // Un-tie the token to the document
                docTableMut.putDelete(ColumnPrefixes.getTermColFam(token), docIdText);
            }

            // write the mutations
            try {
                docTableBw.addMutation(docTableMut);
                termTableBw.addMutations(termTableMutations);
            } catch (final MutationsRejectedException e) {
                logger.error("error adding mutation", e);
                throw new IOException(e);
            }

        }
    }
}