void addMutation(String table, Mutation mutation) { List<Mutation> tabMutList = mutations.get(table); if (tabMutList == null) { tabMutList = new ArrayList<Mutation>(); mutations.put(table, tabMutList); } tabMutList.add(mutation); memoryUsed += mutation.estimatedMemoryUsed(); }
public synchronized void addMutation(String table, Mutation m) throws MutationsRejectedException { if (closed) throw new IllegalStateException("Closed"); if (m.size() == 0) throw new IllegalArgumentException("Can not add empty mutations"); checkForFailures(); while ((totalMemUsed >= maxMem || flushing) && !somethingFailed) { waitRTE(); } // do checks again since things could have changed while waiting and not holding lock if (closed) throw new IllegalStateException("Closed"); checkForFailures(); if (startTime == 0) { startTime = System.currentTimeMillis(); List<GarbageCollectorMXBean> gcmBeans = ManagementFactory.getGarbageCollectorMXBeans(); for (GarbageCollectorMXBean garbageCollectorMXBean : gcmBeans) { initialGCTimes += garbageCollectorMXBean.getCollectionTime(); } CompilationMXBean compMxBean = ManagementFactory.getCompilationMXBean(); if (compMxBean.isCompilationTimeMonitoringSupported()) { initialCompileTimes = compMxBean.getTotalCompilationTime(); } initialSystemLoad = ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage(); } // create a copy of mutation so that after this method returns the user // is free to reuse the mutation object, like calling readFields... this // is important for the case where a mutation is passed from map to reduce // to batch writer... the map reduce code will keep passing the same mutation // object into the reduce method m = new Mutation(m); totalMemUsed += m.estimatedMemoryUsed(); mutations.addMutation(table, m); totalAdded++; if (mutations.getMemoryUsed() >= maxMem / 2) { startProcessing(); checkForFailures(); } }
public void send(TabletServerMutations<Mutation> tsm) throws AccumuloServerException, AccumuloSecurityException { MutationSet failures = null; String oldName = Thread.currentThread().getName(); Map<KeyExtent, List<Mutation>> mutationBatch = tsm.getMutations(); try { long count = 0; for (List<Mutation> list : mutationBatch.values()) { count += list.size(); } String msg = "sending " + String.format("%,d", count) + " mutations to " + String.format("%,d", mutationBatch.size()) + " tablets at " + location; Thread.currentThread().setName(msg); Span span = Trace.start("sendMutations"); try { TimeoutTracker timeoutTracker = timeoutTrackers.get(location); if (timeoutTracker == null) { timeoutTracker = new TimeoutTracker(location, timeout); timeoutTrackers.put(location, timeoutTracker); } long st1 = System.currentTimeMillis(); failures = sendMutationsToTabletServer(location, mutationBatch, timeoutTracker); long st2 = System.currentTimeMillis(); if (log.isTraceEnabled()) log.trace( "sent " + String.format("%,d", count) + " mutations to " + location + " in " + String.format( "%.2f secs (%,.2f mutations/sec) with %,d failures", (st2 - st1) / 1000.0, count / ((st2 - st1) / 1000.0), failures.size())); long successBytes = 0; for (Entry<KeyExtent, List<Mutation>> entry : mutationBatch.entrySet()) { for (Mutation mutation : entry.getValue()) { successBytes += mutation.estimatedMemoryUsed(); } } if (failures.size() > 0) { failedMutations.add(failures); successBytes -= failures.getMemoryUsed(); } updateSendStats(count, st2 - st1); decrementMemUsed(successBytes); } finally { span.stop(); } } catch (IOException e) { if (log.isTraceEnabled()) log.trace("failed to send mutations to " + location + " : " + e.getMessage()); HashSet<String> tables = new HashSet<String>(); for (KeyExtent ke : mutationBatch.keySet()) tables.add(ke.getTableId().toString()); for (String table : tables) TabletLocator.getLocator(instance, new Text(table)).invalidateCache(location); failedMutations.add(location, tsm); } finally { Thread.currentThread().setName(oldName); } }
@Override public List<Short> check(Environment env, Mutation mutation) { if (mutation.estimatedMemoryUsed() < MAX_SIZE) return empty; return violations; }