public boolean preCommit(CommitData cd) throws TableNotFoundException, AccumuloException, AccumuloSecurityException, AlreadyAcknowledgedException { if (notification != null) { // always want to throw already ack exception if collision, so process trigger first return preCommit(cd, notification.getRow(), notification.getColumn()); } else { Bytes prow = updates.keySet().iterator().next(); Map<Column, Bytes> colSet = updates.get(prow); Column pcol = colSet.keySet().iterator().next(); return preCommit(cd, prow, pcol); } }
public TracingTransaction(TransactionImpl tx, Notification notification, Class<?> clazz) { this.tx = tx; this.txid = tx.getStartTs(); this.notification = notification; this.clazz = clazz; if (log.isTraceEnabled()) { log.trace("txid: {} begin() thread: {}", txid, Thread.currentThread().getId()); if (notification != null) { log.trace("txid: {} trigger: {} {} {}", txid, enc(notification.getRow()), enc(notification.getColumn()), notification.getTimestamp()); } if (clazz != null) { log.trace("txid: {} class: {}", txid, clazz.getName()); } } }
public Flutation newDelete(Environment env) { return newDelete(env, getTimestamp()); }
private int scan(ModulusParams lmp, Range range) throws TableNotFoundException { Scanner scanner = env.getConnector().createScanner(env.getTable(), env.getAuthorizations()); scanner.setRange(range); Notification.configureScanner(scanner); IteratorSetting iterCfg = new IteratorSetting(30, "nhf", NotificationHashFilter.class); NotificationHashFilter.setModulusParams(iterCfg, lmp.divisor, lmp.remainder); scanner.addScanIterator(iterCfg); int count = 0; for (Entry<Key, Value> entry : scanner) { if (lmp.update != hwf.getModulusParams().update) { throw new HashNotificationFinder.ModParamsChangedException(); } if (stopped.get()) { return count; } if (hwf.getWorkerQueue().addNotification(hwf, Notification.from(entry.getKey()))) { count++; } } return count; }
@Override public void waitForObservers() { try { Scanner scanner = env.getConnector().createScanner(env.getTable(), env.getAuthorizations()); Notification.configureScanner(scanner); while (isProcessing(scanner)) { Thread.sleep(100); } } catch (Exception e) { throw new RuntimeException(e); } } }
Bytes.of(cu.getColumnVisibility())); if (notification.getColumn().equals(col)) { endKey.setTimestamp(ColumnConstants.ACK_PREFIX | (notification.getTimestamp() + 1)); .writeMutationAsync(notification.newDelete(env)); return true;
public boolean finishCommit(CommitData cd, Stamp commitStamp) throws TableNotFoundException, MutationsRejectedException { long commitTs = commitStamp.getTxTimestamp(); // delete locks and add writes for other columns ArrayList<Mutation> mutations = new ArrayList<>(updates.size() + 1); for (Entry<Bytes, Map<Column, Bytes>> rowUpdates : updates.entrySet()) { Flutation m = new Flutation(env, rowUpdates.getKey()); boolean isTriggerRow = isTriggerRow(rowUpdates.getKey()); for (Entry<Column, Bytes> colUpdates : rowUpdates.getValue().entrySet()) { ColumnUtil.commitColumn(env, isTriggerRow && colUpdates.getKey().equals(notification.getColumn()), false, colUpdates.getKey(), colUpdates.getValue() != null, colUpdates.getValue() == DELETE, startTs, commitTs, observedColumns, m); } mutations.add(m); } ArrayList<Mutation> afterFlushMutations = new ArrayList<>(2); Flutation m = new Flutation(env, cd.prow); // mark transaction as complete for garbage collection purposes m.put(cd.pcol, ColumnConstants.TX_DONE_PREFIX | commitTs, EMPTY); afterFlushMutations.add(m); if (weakNotification != null) { afterFlushMutations.add(weakNotification.newDelete(env, startTs)); } if (notification != null) { afterFlushMutations.add(notification.newDelete(env, startTs)); } env.getSharedResources().getBatchWriter().writeMutationsAsync(mutations, afterFlushMutations); return true; }
private ConditionalFlutation prewrite(ConditionalFlutation cm, Bytes row, Column col, Bytes val, Bytes primaryRow, Column primaryColumn, boolean isTriggerRow) { IteratorSetting iterConf = new IteratorSetting(10, PrewriteIterator.class); PrewriteIterator.setSnaptime(iterConf, startTs); boolean isTrigger = isTriggerRow && col.equals(notification.getColumn()); if (isTrigger) { PrewriteIterator.enableAckCheck(iterConf, notification.getTimestamp()); } Condition cond = new FluoCondition(env, col).setIterators(iterConf); if (cm == null) { cm = new ConditionalFlutation(env, row, cond); } else { cm.addCondition(cond); } if (val != null && val != DELETE) { cm.put(col, ColumnConstants.DATA_PREFIX | startTs, val.toArray()); } cm.put(col, ColumnConstants.LOCK_PREFIX | startTs, LockValue.encode(primaryRow, primaryColumn, val != null, val == DELETE, isTriggerRow, getTransactorID())); return cm; }
private void writeWeakNotifications(long commitTs) { if (weakNotifications.size() > 0) { SharedBatchWriter sbw = env.getSharedResources().getBatchWriter(); ArrayList<Mutation> mutations = new ArrayList<>(); for (Entry<Bytes, Set<Column>> entry : weakNotifications.entrySet()) { Flutation m = new Flutation(env, entry.getKey()); for (Column col : entry.getValue()) { Notification.put(env, m, col, commitTs); } mutations.add(m); } sbw.writeMutations(mutations); } }
public static String encNonAscii(Notification n) { StringBuilder sb = new StringBuilder(); encNonAscii(sb, n, " "); sb.append(" "); sb.append(n.getTimestamp()); return sb.toString(); }
private boolean isTriggerRow(Bytes row) { return notification != null && notification.getRow().equals(row); }
void deleteWeakRow() { if (weakNotification != null) { env.getSharedResources().getBatchWriter() .writeMutation(weakNotification.newDelete(env, startTs)); } }
public static Notification from(Key k) { Preconditions.checkArgument(!isDelete(k), "Method not expected to be used with delete notifications"); Bytes row = ByteUtil.toBytes(k.getRowData()); return new Notification(row, decodeCol(k), decodeTs(k)); }
boolean isTrigger = isTriggerRow(cd.prow) && cd.pcol.equals(notification.getColumn());
@VisibleForTesting public long countNotifications(Environment env) { Scanner scanner = null; try { scanner = env.getConnector().createScanner(env.getTable(), env.getAuthorizations()); } catch (TableNotFoundException e) { log.error("An exception was thrown -", e); throw new FluoException(e); } Notification.configureScanner(scanner); long count = 0; for (Iterator<Map.Entry<Key, Value>> iterator = scanner.iterator(); iterator.hasNext(); iterator .next()) { count++; } return count; }
public static void commitColumn(Environment env, boolean isTrigger, boolean isPrimary, Column col, boolean isWrite, boolean isDelete, long startTs, long commitTs, Set<Column> observedColumns, Mutation m) { if (isWrite) { Flutation.put(env, m, col, ColumnConstants.WRITE_PREFIX | commitTs, WriteValue.encode(startTs, isPrimary, isDelete)); } else { Flutation.put(env, m, col, ColumnConstants.DEL_LOCK_PREFIX | commitTs, DelLockValue.encode(startTs, isPrimary, false)); } if (isTrigger) { Flutation.put(env, m, col, ColumnConstants.ACK_PREFIX | startTs, TransactionImpl.EMPTY); } if (observedColumns.contains(col) && isWrite && !isDelete) { Notification.put(env, m, col, commitTs); } }
public TransactionImpl(Environment env, Notification trigger, long startTs) { Preconditions.checkNotNull(env, "environment cannot be null"); Preconditions.checkArgument(startTs >= 0, "startTs cannot be negative"); this.env = env; this.stats = new TxStats(env); this.startTs = startTs; this.observedColumns = env.getObservers().keySet(); if (trigger != null && env.getWeakObservers().containsKey(trigger.getColumn())) { this.weakNotification = trigger; } else { this.notification = trigger; } if (notification != null) { Map<Column, Bytes> colUpdates = new HashMap<>(); colUpdates.put(notification.getColumn(), null); updates.put(notification.getRow(), colUpdates); } }
@Override public void commit() throws CommitException { try { tx.commit(); committed = true; log.trace("txid: {} commit() -> SUCCESSFUL commitTs: {}", txid, tx.getStats().getCommitTs()); } catch (CommitException ce) { log.trace("txid: {} commit() -> UNSUCCESSFUL commitTs: {}", txid, tx.getStats().getCommitTs()); if (!log.isTraceEnabled() && notification != null) { collisionLog.trace("txid: {} trigger: {} {} {}", txid, notification.getRow(), notification.getColumn(), notification.getTimestamp()); } if (!log.isTraceEnabled() && clazz != null) { collisionLog.trace("txid: {} class: {}", txid, clazz.getName()); } collisionLog.trace("txid: {} collisions: {}", txid, tx.getStats().getRejected()); throw ce; } }
@VisibleForTesting static boolean shouldProcess(Notification notification, int divisor, int remainder) { byte[] cfcq = NotificationUtil.encodeCol(notification.getColumn()); return NotificationHashFilter.accept( ByteUtil.toByteSequence((MutableBytes) notification.getRow()), new ArrayByteSequence(cfcq), divisor, remainder); }
public Flutation newDelete(Environment env, long ts) { Flutation m = new Flutation(env, getRow()); ColumnVisibility cv = env.getSharedResources().getVisCache().getCV(getColumn()); m.put(ColumnConstants.NOTIFY_CF.toArray(), encodeCol(getColumn()), cv, encodeTs(ts, true), TransactionImpl.EMPTY); return m; }