public static String toString(Entry<Key, Value> entry) { Key key = entry.getKey(); if (NotificationUtil.isNtfy(key)) { StringBuilder sb = new StringBuilder(); encNonAscii(sb, key.getRowData()); encNonAscii(sb, key.getColumnFamilyData()); sb.append(":"); Column col = NotificationUtil.decodeCol(key); encNonAscii(sb, col.getFamily()); sb.append(":"); encNonAscii(sb, key.getColumnVisibilityData()); sb.append("] "); sb.append(NotificationUtil.decodeTs(key)); sb.append('-'); sb.append(NotificationUtil.isDelete(key) ? "DELETE" : "INSERT"); sb.append("\t"); encNonAscii(sb, entry.getValue().get());
@Override protected void consume() throws IOException { PushbackIterator source = (PushbackIterator) getSource(); if (lastKeySet == true) { skipRowCol(source, lastKey); } consumeDeletes(source); if (source.hasTop() && isNtfy(source.getTopKey()) && !isDelete(source.getTopKey())) { lastKey.set(source.getTopKey()); lastKeySet = true; } else { lastKeySet = false; } }
@VisibleForTesting static boolean shouldProcess(Notification notification, int divisor, int remainder) { byte[] cfcq = NotificationUtil.encodeCol(notification.getColumn()); return NotificationHashFilter.accept(ByteUtil.toByteSequence(notification.getRow()), new ArrayByteSequence(cfcq), divisor, remainder); }
public static boolean isDelete(Key k) { return isDelete(k.getTimestamp()); }
public static long decodeTs(Key k) { return decodeTs(k.getTimestamp()); }
public static Column decodeCol(Key k) { return decodeCol(k.getColumnQualifierData().toArray()); }
private void consumeDeletes(PushbackIterator source) throws IOException { while (source.hasTop() && isNtfy(source.getTopKey()) && isDelete(source.getTopKey())) { Key keyCopy = new Key(source.getTopKey()); if (scanOrFullMajc) { // consume everything w/ the same row col source.next(); skipRowCol(source, keyCopy); } else { // need to make a decision about propagating delete... IF the pattern of notifications and // deletes seems orderly AND it does not end with a delete THEN // do not propagate delete Value valCopy = new Value(source.getTopValue()); boolean lastKeyWasDelete = true; boolean isOrderly = true; // used to check that deletes and notifications alternate source.next(); while (source.hasTop() && source.getTopKey().equals(keyCopy, PartialKey.ROW_COLFAM_COLQUAL_COLVIS)) { isOrderly &= isDelete(source.getTopKey()) ^ lastKeyWasDelete; lastKeyWasDelete = isDelete(source.getTopKey()); source.next(); } if (!isOrderly || lastKeyWasDelete) { // dropping this delete on a partial compaction does not look promising, so propagate the // delete marker source.pushback(keyCopy, valCopy); break; } } } }
@VisibleForTesting static boolean shouldProcess(Notification notification, int divisor, int remainder) { byte[] cfcq = NotificationUtil.encodeCol(notification.getColumn()); return NotificationHashFilter.accept(ByteUtil.toByteSequence(notification.getRow()), new ArrayByteSequence(cfcq), divisor, remainder); }
public static long getNotificationTS(Environment env, String row, Column col) { Scanner scanner; try { scanner = env.getAccumuloClient().createScanner(env.getTable(), env.getAuthorizations()); } catch (TableNotFoundException e) { throw new RuntimeException(e); } IteratorSetting iterCfg = new IteratorSetting(11, NotificationIterator.class); scanner.addScanIterator(iterCfg); Text cv = ByteUtil.toText(col.getVisibility()); scanner.setRange(SpanUtil.toRange(Span.prefix(row))); scanner.fetchColumn(ByteUtil.toText(ColumnConstants.NOTIFY_CF), new Text(NotificationUtil.encodeCol(col))); for (Entry<Key, org.apache.accumulo.core.data.Value> entry : scanner) { if (entry.getKey().getColumnVisibility().equals(cv)) { return Notification.from(entry.getKey()).getTimestamp(); } } throw new RuntimeException("No notification found"); }
public Flutation newDelete(Environment env, long ts) { Flutation m = new Flutation(env, rowCol.getRow()); ColumnVisibility cv = env.getSharedResources().getVisCache().getCV(rowCol.getColumn()); m.put(NOTIFY_CF_ARRAY, encodeCol(rowCol.getColumn()), cv, encodeTs(ts, true), TransactionImpl.EMPTY); return m; }
public Flutation newDelete(Environment env, long ts) { Flutation m = new Flutation(env, rowCol.getRow()); ColumnVisibility cv = env.getSharedResources().getVisCache().getCV(rowCol.getColumn()); m.put(NOTIFY_CF_ARRAY, encodeCol(rowCol.getColumn()), cv, encodeTs(ts, true), TransactionImpl.EMPTY); return m; }