<commit_before>package server;

import static spark.Spark.get;
import static spark.Spark.redirect;
import static spark.Spark.staticFileLocation;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.google.gson.Gson;

import configuration.Configuration;
import database.DatabaseService;
import spark.ModelAndView;
import spark.Request;
import spark.template.thymeleaf.ThymeleafTemplateEngine;

public class Server {
	private static final int LIMIT = 2;
	private static final ExecutorService executor = Executors
			.newFixedThreadPool(20);

	private static Map<String, Object> getAssociation(final Request request,
			final DatabaseService db, final String table,
			final boolean isContextQuery) throws Exception {
		final String corpus = request.queryParams("corpus");
		final String word1 = request.queryParams("word1");
		final String word2 = request.queryParams("word2");
		return getAssociationJson(db, corpus, table, isContextQuery, word1,
				word2);
	}

	static final Map<String, Object> getAssociationJson(
			final DatabaseService db, final String corpus, final String table,
			final boolean isContextQuery, final String initialWord,
			final String... moreWords) throws Exception {
		final JSON data = new JSON();
		for (final String word : moreWords)
			data.addValues(word, db.getYearAndAssociation(corpus, table,
					isContextQuery, initialWord, word));
		return data.data;
	}

	static final Map<String, Object> getFrequencyJson(final DatabaseService db,
			final String corpus, final String word) throws Exception {
		return new JSON().addValues(word,
				db.getYearAndFrequency(corpus, word)).data;
	}

	private static Callable<List<String>> getMostSimilarAsync(
			final boolean first, final DatabaseService db, final String corpus,
			final String word) throws Exception {
		return () -> db.getMostSimilarWordsInYear(corpus, word, first
				? db.getFirstYear(corpus, word) : db.getLastYear(corpus, word),
				LIMIT);
	}

	static final String[] getMostSimilarAtBeginningAndEnd(
			final DatabaseService db, final String corpus, final String word)
			throws Exception {
		return executor
				.invokeAll(Arrays.asList(
						getMostSimilarAsync(true, db, corpus, word),
						getMostSimilarAsync(false, db, corpus, word)))
				.stream().map(future -> {
					try {
						return future.get();
					} catch (final Exception e) {
						throw new IllegalStateException(e);
					}
				}).flatMap(List::stream).distinct().toArray(String[]::new);
	}

	static final String[] getTopContextAtBeginningAndEnd(
			final DatabaseService db, final String table, final String corpus,
			final String word) throws Exception {
		final Set<String> topContext = new HashSet<>();
		topContext.addAll(db.getTopContextWordsInYear(corpus, table, word,
				db.getFirstYear(corpus, word), LIMIT));
		topContext.addAll(db.getTopContextWordsInYear(corpus, table, word,
				db.getLastYear(corpus, word), LIMIT));
		return topContext.toArray(new String[topContext.size()]);
	}

	public static void startServer(final DatabaseService db,
			final Configuration config) {
		if (config.coversServer()) {
			spark.Spark.ipAddress(config.getServer().getIp());
			spark.Spark.port(config.getServer().getPort());
			System.out.println("Using " + config.getServer().getIp() + ":"
					+ config.getServer().getPort());
		}
<commit_msg>fixes #3<commit_after>package server;

import static spark.Spark.get;
import static spark.Spark.redirect;
import static spark.Spark.staticFileLocation;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.google.gson.Gson;

import configuration.Configuration;
import database.DatabaseService;
import spark.ModelAndView;
import spark.Request;
import spark.template.thymeleaf.ThymeleafTemplateEngine;

public class Server {
	private static final int LIMIT = 2;
	private static final int THREADS = 12;
	private static final ExecutorService executor = Executors
			.newFixedThreadPool(THREADS);

	private static Map<String, Object> getAssociation(final Request request,
			final DatabaseService db, final String table,
			final boolean isContextQuery) throws Exception {
		final String corpus = request.queryParams("corpus");
		final String word1 = request.queryParams("word1");
		final String word2 = request.queryParams("word2");
		return getAssociationJson(db, corpus, table, isContextQuery, word1,
				word2);
	}

	static final Map<String, Object> getAssociationJson(
			final DatabaseService db, final String corpus, final String table,
			final boolean isContextQuery, final String initialWord,
			final String... moreWords) throws Exception {
		final JSON data = new JSON();
		for (final String word : moreWords)
			data.addValues(word, db.getYearAndAssociation(corpus, table,
					isContextQuery, initialWord, word));
		return data.data;
	}

	static final Map<String, Object> getFrequencyJson(final DatabaseService db,
			final String corpus, final String word) throws Exception {
		return new JSON().addValues(word,
				db.getYearAndFrequency(corpus, word)).data;
	}

	private static Callable<List<String>> getMostSimilarAsync(
			final boolean first, final DatabaseService db, final String corpus,
			final String word) throws Exception {
		return () -> db.getMostSimilarWordsInYear(corpus, word, first
				? db.getFirstYear(corpus, word) : db.getLastYear(corpus, word),
				LIMIT);
	}

	static final String[] getMostSimilarAtBeginningAndEnd(
			final DatabaseService db, final String corpus, final String word)
			throws Exception {
		return executor
				.invokeAll(Arrays.asList(
						getMostSimilarAsync(true, db, corpus, word),
						getMostSimilarAsync(false, db, corpus, word)))
				.stream().map(future -> {
					try {
						return future.get();
					} catch (final Exception e) {
						throw new IllegalStateException(e);
					}
				}).flatMap(List::stream).distinct().toArray(String[]::new);
	}

	static final String[] getTopContextAtBeginningAndEnd(
			final DatabaseService db, final String table, final String corpus,
			final String word) throws Exception {
		final Set<String> topContext = new HashSet<>();
		topContext.addAll(db.getTopContextWordsInYear(corpus, table, word,
				db.getFirstYear(corpus, word), LIMIT));
		topContext.addAll(db.getTopContextWordsInYear(corpus, table, word,
				db.getLastYear(corpus, word), LIMIT));
		return topContext.toArray(new String[topContext.size()]);
	}

	public static void startServer(final DatabaseService db,
			final Configuration config) {
		if (config.coversServer()) {
			spark.Spark.ipAddress(config.getServer().getIp());
			spark.Spark.port(config.getServer().getPort());
			System.out.println("Using " + config.getServer().getIp() + ":"
					+ config.getServer().getPort());
		}
		
		spark.Spark.threadPool(THREADS);

{'fraction_non_alphanumeric': 0.10539558289069052, 'fraction_numerical': 0.0026558568632932627, 'mean_word_length': 4.884046052631579, 'pattern_counts': {'":': 2, '<': 17, '<?xml version=': 0, '>': 21, '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': '3212270', 'n_tokens_mistral': 2366, 'n_tokens_neox': 2063, 'n_words': 560}