<commit_before>package nl.tudelft.watchdog.logic.interval;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import nl.tudelft.watchdog.logic.interval.intervaltypes.IntervalBase;
import nl.tudelft.watchdog.logic.network.JsonTransferer;
import nl.tudelft.watchdog.logic.network.NetworkUtils.Connection;
import nl.tudelft.watchdog.ui.UIUtils;
import nl.tudelft.watchdog.ui.preferences.Preferences;
import nl.tudelft.watchdog.util.WatchDogGlobals;
import nl.tudelft.watchdog.util.WatchDogLogger;

/**
 * This manager takes care of the repeated transferal of all closed intervals to
 * the server. When the transfer to the server was successful, the intervals are
 * immediately deleted from the local database. Furthermore, it allows the
 * immediate execution of this regularly scheduled task, e.g. when it is needed
 * on exiting.
 */
public class IntervalTransferManager {

	private static final int UPDATE_RATE = 3 * 60 * 1000;

	private Timer timer;

	private IntervalsTransferTimerTask task;

	/**
	 * Constructor. Tries to immediately transfer all remaining intervals, and
	 * sets up a scheduled timer to run every {@value #UPDATE_RATE}
	 * milliseconds.
	 */
	public IntervalTransferManager(final IntervalPersister intervalPersister) {
		task = new IntervalsTransferTimerTask(intervalPersister);
		task.run();
		timer = new Timer(true);
		timer.scheduleAtFixedRate(task, 0, UPDATE_RATE);
	}

	/** Immediately synchronizes the intervals with the server. */
	public void sendIntervalsImmediately() {
		task.run();
	}

	private static class IntervalsTransferTimerTask extends TimerTask {
		private final IntervalPersister intervalPersister;
		private Preferences preferences;

		private IntervalsTransferTimerTask(IntervalPersister intervalPersister) {
			this.intervalPersister = intervalPersister;
			this.preferences = Preferences.getInstance();
		}

		/**
		 * Transfers all intervals from the persistence storage that are not yet
		 * on the server, to the server.
		 */
		@Override
		public void run() {
			List<IntervalBase> intervalsToTransfer = new ArrayList<IntervalBase>(
					intervalPersister.readIntervals());

			if (intervalsToTransfer.isEmpty()) {
				return;
			}

			transferIntervals(intervalsToTransfer);
			resetDatabase();

			UIUtils.refreshCommand(UIUtils.COMMAND_SHOW_INFO);
		}

		private void transferIntervals(List<IntervalBase> intervalsToTransfer) {
			JsonTransferer intervalTransferer = new JsonTransferer();

			Connection connection = intervalTransferer
					.sendIntervals(intervalsToTransfer);
			switch (connection) {
			case SUCCESSFUL:
				intervalPersister.removeIntervals(intervalsToTransfer);
				preferences.setLastTransferedInterval();
				preferences.addTransferedIntervals(intervalsToTransfer.size());
				WatchDogGlobals.lastTransactionFailed = false;
				break;

			case UNSUCCESSFUL:
				WatchDogLogger.getInstance().logSevere(
						"Could not transfer interval and removed permanently!");
				intervalPersister.removeIntervals(intervalsToTransfer);
				WatchDogGlobals.lastTransactionFailed = true;
				break;

			case NETWORK_ERROR:
				WatchDogGlobals.lastTransactionFailed = true;
				int intervals = intervalsToTransfer.size();

				if (intervals == 1) {
					return;
				}

				// divide and conquer
				int halfOfIntervals = (int) Math.floor(intervals / 2);
				List<IntervalBase> firstHalfIntervals = intervalsToTransfer
						.subList(0, halfOfIntervals);
				List<IntervalBase> secondHalfIntervals = intervalsToTransfer
						.subList(halfOfIntervals, intervals);<commit_msg>Splits unsuccessful interval transfers until they are isolated.<commit_after>package nl.tudelft.watchdog.logic.interval;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import nl.tudelft.watchdog.logic.interval.intervaltypes.IntervalBase;
import nl.tudelft.watchdog.logic.network.JsonTransferer;
import nl.tudelft.watchdog.logic.network.NetworkUtils.Connection;
import nl.tudelft.watchdog.ui.UIUtils;
import nl.tudelft.watchdog.ui.preferences.Preferences;
import nl.tudelft.watchdog.util.WatchDogGlobals;
import nl.tudelft.watchdog.util.WatchDogLogger;

/**
 * This manager takes care of the repeated transferal of all closed intervals to
 * the server. When the transfer to the server was successful, the intervals are
 * immediately deleted from the local database. Furthermore, it allows the
 * immediate execution of this regularly scheduled task, e.g. when it is needed
 * on exiting.
 */
public class IntervalTransferManager {

	private static final int UPDATE_RATE = 3 * 60 * 1000;

	private Timer timer;

	private IntervalsTransferTimerTask task;

	/**
	 * Constructor. Tries to immediately transfer all remaining intervals, and
	 * sets up a scheduled timer to run every {@value #UPDATE_RATE}
	 * milliseconds.
	 */
	public IntervalTransferManager(final IntervalPersister intervalPersister) {
		task = new IntervalsTransferTimerTask(intervalPersister);
		task.run();
		timer = new Timer(true);
		timer.scheduleAtFixedRate(task, 0, UPDATE_RATE);
	}

	/** Immediately synchronizes the intervals with the server. */
	public void sendIntervalsImmediately() {
		task.run();
	}

	private static class IntervalsTransferTimerTask extends TimerTask {
		private final IntervalPersister intervalPersister;
		private Preferences preferences;

		private IntervalsTransferTimerTask(IntervalPersister intervalPersister) {
			this.intervalPersister = intervalPersister;
			this.preferences = Preferences.getInstance();
		}

		/**
		 * Transfers all intervals from the persistence storage that are not yet
		 * on the server, to the server.
		 */
		@Override
		public void run() {
			List<IntervalBase> intervalsToTransfer = new ArrayList<IntervalBase>(
					intervalPersister.readIntervals());

			if (intervalsToTransfer.isEmpty()) {
				return;
			}

			transferIntervals(intervalsToTransfer);
			resetDatabase();

			UIUtils.refreshCommand(UIUtils.COMMAND_SHOW_INFO);
		}

		private void transferIntervals(List<IntervalBase> intervalsToTransfer) {
			JsonTransferer intervalTransferer = new JsonTransferer();

			Connection connection = intervalTransferer
					.sendIntervals(intervalsToTransfer);
			switch (connection) {
			case SUCCESSFUL:
				intervalPersister.removeIntervals(intervalsToTransfer);
				preferences.setLastTransferedInterval();
				preferences.addTransferedIntervals(intervalsToTransfer.size());
				WatchDogGlobals.lastTransactionFailed = false;
				break;

			case UNSUCCESSFUL:
			case NETWORK_ERROR:
				WatchDogGlobals.lastTransactionFailed = true;
				int intervals = intervalsToTransfer.size();

				if (intervals == 1) {
					if (connection == Connection.UNSUCCESSFUL) {
						WatchDogLogger
								.getInstance()
								.logSevere(
										"Could not transfer interval and removed permanently!");
						intervalPersister.removeIntervals(intervalsToTransfer);
					}
					return;
				}

				// divide and conquer
				int halfOfIntervals = (int) Math.floor(intervals / 2);
				List<IntervalBase> firstHalfIntervals = intervalsToTransfer
						.subList(0, halfOfIntervals);
				List<IntervalBase> secondHalfIntervals = intervalsToTransfer
						.subList(halfOfIntervals, intervals);
{'fraction_non_alphanumeric': 0.0818294530927125, 'fraction_numerical': 0.0030307204849152774, 'mean_word_length': 4.636645962732919, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2499741', 'n_tokens_mistral': 2366, 'n_tokens_neox': 1998, 'n_words': 514}