private TabletServerMutations<QCMutation> dequeue(String location) { BlockingQueue<TabletServerMutations<QCMutation>> queue = getServerQueue(location).queue; ArrayList<TabletServerMutations<QCMutation>> mutations = new ArrayList<>(); queue.drainTo(mutations); if (mutations.size() == 0) return null; if (mutations.size() == 1) { return mutations.get(0); } else { // merge multiple request to a single tablet server TabletServerMutations<QCMutation> tsm = mutations.get(0); for (int i = 1; i < mutations.size(); i++) { for (Entry<KeyExtent,List<QCMutation>> entry : mutations.get(i).getMutations().entrySet()) { List<QCMutation> list = tsm.getMutations().get(entry.getKey()); if (list == null) { list = new ArrayList<>(); tsm.getMutations().put(entry.getKey(), list); } list.addAll(entry.getValue()); } } return tsm; } }
private void reschedule(SendTask task) { ServerQueue serverQueue = getServerQueue(task.location); // just finished processing work for this server, could reschedule if it has more work or // immediately process the work // this code reschedules the the server for processing later... there may be other queues with // more data that need to be processed... also it will give the current server time to build // up more data... the thinking is that rescheduling instead or processing immediately will // result // in bigger batches and less RPC overhead synchronized (serverQueue) { if (serverQueue.queue.size() > 0) threadPool.execute(new LoggingRunnable(log, Trace.wrap(task))); else serverQueue.taskQueued = false; } }
private void queue(String location, TabletServerMutations<QCMutation> mutations) { ServerQueue serverQueue = getServerQueue(location); synchronized (serverQueue) { serverQueue.queue.add(mutations); // never execute more than one task per server if (!serverQueue.taskQueued) { threadPool.execute(new LoggingRunnable(log, Trace.wrap(new SendTask(location)))); serverQueue.taskQueued = true; } } }