diff --git a/pom.xml b/pom.xml
index 04d1878..f76ad3e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,6 +11,17 @@
commons-cli
1.4
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.9.1
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.9.1
+
+
junit
diff --git a/src/main/java/fr/pavnay/scrabble/DictionaryBuilder.java b/src/main/java/fr/pavnay/scrabble/DictionaryBuilder.java
index bae9e54..083811d 100644
--- a/src/main/java/fr/pavnay/scrabble/DictionaryBuilder.java
+++ b/src/main/java/fr/pavnay/scrabble/DictionaryBuilder.java
@@ -3,14 +3,9 @@ package fr.pavnay.scrabble;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
public class DictionaryBuilder {
@@ -58,7 +53,7 @@ public class DictionaryBuilder {
public static Enigma generateEnigma(String language, int minLength, int maxLength) {
Resolver resolver;
try {
- resolver = loadResolver(language);
+ resolver = ScrabbleUtils.loadResolver(language);
} catch (Exception e) {
e.printStackTrace();
return null;
@@ -66,51 +61,19 @@ public class DictionaryBuilder {
return resolver.generateEnigma(minLength, maxLength);
}
- public static void generateResolver(String language) throws IOException {
- File file = new File(
- "C:/Users/viaduc105.smallbusiness/Documents/workspace-sts/SocialArena/resources/" + language);
- if (!file.exists()) {
- System.out.println("No dictionary for " + language);
- return;
- }
- Resolver resolver = generateResolver(new Resolver(), file, 3, 7);
- resolver.computeStatistics();
- ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
- new File("C:/Users/viaduc105.smallbusiness/Documents/workspace-sts/SocialArena/resources/resolver/"
- + language)));
- oos.writeObject(resolver);
- oos.flush();
- oos.close();
- }
-
- public static void loadResolvers() throws IOException, ClassNotFoundException {
- List languages = ScrabbleUtils.loadLanguages();
- for (String language : languages) {
- long t1 = System.currentTimeMillis();
- loadResolver(language);
- System.out.println("Resolver in " + language + " loaded in " + (System.currentTimeMillis() - t1) + "ms.");
- }
- }
-
- private static Resolver loadResolver(String language)
- throws FileNotFoundException, IOException, ClassNotFoundException {
- Resolver resolver = (Resolver) resolvers.get(language);
- if (resolver == null) {
- long t1 = System.currentTimeMillis();
- String path = DictionaryBuilder.class.getResource("/resolvers/" + language).getPath();
- File file = new File(path);
- if (!file.exists()) {
- System.out.println("No resolver for " + language);
- return null;
+ public static void main(String[] args) throws Exception {
+ for( String language : new String[] {"english", "french"} ) {
+ long avg = 0;
+ for( int i = 0; i < 100; i++) {
+ resolvers.clear();
+ long t1 = System.currentTimeMillis();
+ ScrabbleUtils.loadResolver(language);
+ long t2 = System.currentTimeMillis() - t1;
+ avg += t2;
}
- ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
- resolver = (Resolver) ois.readObject();
- ois.close();
-
- resolvers.put(language, resolver);
- System.out.println("Resolver in " + language + " loaded in " + (System.currentTimeMillis() - t1) + "ms.");
+ System.out.println(language + " : " + (avg/100));
}
- return resolver;
}
+
}
diff --git a/src/main/java/fr/pavnay/scrabble/Main.java b/src/main/java/fr/pavnay/scrabble/Main.java
index 7d95bbb..2a43cf5 100644
--- a/src/main/java/fr/pavnay/scrabble/Main.java
+++ b/src/main/java/fr/pavnay/scrabble/Main.java
@@ -1,9 +1,7 @@
package fr.pavnay.scrabble;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.ObjectOutputStream;
import java.util.List;
import org.apache.commons.cli.CommandLine;
@@ -70,16 +68,15 @@ public class Main {
try {
Resolver resolver = DictionaryBuilder.generateResolver(new Resolver(), file, min, max);
resolver.computeStatistics();
+ resolver.displayStatistics();
- ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("src/main/resources/resolvers/" + language)));
- oos.writeObject(resolver);
- oos.flush();
- oos.close();
+ ScrabbleUtils.writeResolver(resolver, language);
} catch( IOException e) {
System.err.println(e.getMessage());
}
}
+
private static void getEnigma(CommandLine line) {
final String language = line.getOptionValue("lang", "");
final int min = Integer.parseInt(line.getOptionValue("min", "3"));
diff --git a/src/main/java/fr/pavnay/scrabble/Node.java b/src/main/java/fr/pavnay/scrabble/Node.java
index eab84a2..4d66c04 100644
--- a/src/main/java/fr/pavnay/scrabble/Node.java
+++ b/src/main/java/fr/pavnay/scrabble/Node.java
@@ -1,73 +1,14 @@
package fr.pavnay.scrabble;
import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
-public class Node implements Serializable {
- private static final long serialVersionUID = 3539215265338287172L;
- private Node[] nodes = new Node[26];
- private List words;
- private String parent;
+public interface Node extends Serializable {
+
+ public void addWord(String word);
+ public List getWords();
+ public Node getNode(char character);
+ public Object getNodes();
+ public int getWordsCount();
- public Node(String parent) {
- this.parent = parent;
- }
-
- public void addWord(String word) {
- if (this.words == null) {
- this.words = new ArrayList();
- }
- if (!this.words.contains(word)) {
- this.words.add(word);
- }
- }
-
- public List getWords() {
- if (this.words == null) {
- return null;
- }
- Collections.sort(this.words);
- return this.words;
- }
-
- public Node getNode(char character) {
- Node node = this.nodes[(character - 'a')];
- if (node == null) {
- node = new Node(this.parent + character);
- this.nodes[(character - 'a')] = node;
- }
- return node;
- }
-
- public int getWordsCount() {
- int total = 0;
- for (int i = 0; i < 26; i++) {
- Node current = this.nodes[i];
- if (current != null) {
- total += current.getWordsCount();
- }
- if (this.words != null) {
- total += this.words.size();
- }
- }
- return total;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder("Parent " + this.parent);
- if (this.words != null) {
- sb.append(this.words.toString());
- } else {
- sb.append('-');
- }
- for (int i = 0; i < 26; i++) {
- Node current = this.nodes[i];
- if (current != null) {
- sb.append(current);
- }
- }
- return sb.toString();
- }
}
diff --git a/src/main/java/fr/pavnay/scrabble/Resolver.java b/src/main/java/fr/pavnay/scrabble/Resolver.java
index 3193dd9..a95f6b9 100644
--- a/src/main/java/fr/pavnay/scrabble/Resolver.java
+++ b/src/main/java/fr/pavnay/scrabble/Resolver.java
@@ -8,20 +8,20 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
+import fr.pavnay.scrabble.impl.HashNodeImpl;
+
public class Resolver implements Serializable {
- private static final long serialVersionUID = 8267126995323709570L;
- private Node[] nodes = new Node[26];
+
+ private static final long serialVersionUID = 3424195161013074975L;
+
+ public Node nodes = new HashNodeImpl();
private float[] statistics = new float[26];
private float totalCharacter = 0.0F;
public Node getNode(char character) {
- Node node = this.nodes[(character - 'a')];
+ Node node = nodes.getNode(character);
this.statistics[(character - 'a')] += 1.0F;
this.totalCharacter += 1.0F;
- if (node == null) {
- node = new Node(Character.toString(character));
- this.nodes[(character - 'a')] = node;
- }
return node;
}
@@ -132,7 +132,7 @@ public class Resolver implements Serializable {
int setSize = letters.length;
if (size == setSize) {
- Node currentNode = this.nodes[(sortLetters[0] - 'a')];
+ Node currentNode = nodes.getNode(sortLetters[0]);
if (currentNode == null) {
return null;
}
@@ -175,7 +175,8 @@ public class Resolver implements Serializable {
public int countWords() {
int total = 0;
for (int i = 0; i < 26; i++) {
- Node current = this.nodes[i];
+// Node current = this.nodes[i];
+ Node current = nodes.getNode((char)(i + 'a'));
if (current != null) {
total += current.getWordsCount();
}
diff --git a/src/main/java/fr/pavnay/scrabble/ScrabbleUtils.java b/src/main/java/fr/pavnay/scrabble/ScrabbleUtils.java
index d7a7787..c26747e 100644
--- a/src/main/java/fr/pavnay/scrabble/ScrabbleUtils.java
+++ b/src/main/java/fr/pavnay/scrabble/ScrabbleUtils.java
@@ -1,9 +1,24 @@
package fr.pavnay.scrabble;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleAbstractTypeResolver;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+import fr.pavnay.scrabble.impl.HashNodeImpl;
+import fr.pavnay.scrabble.serializer.NodeSerializer;
public class ScrabbleUtils {
@@ -14,4 +29,82 @@ public class ScrabbleUtils {
return Arrays.asList(files);
}
+ public static Resolver loadResolver(String language) {
+ long t1 = System.currentTimeMillis();
+ String path = DictionaryBuilder.class.getResource("/resolvers/" + language).getPath();
+ File file = new File(path);
+ if (!file.exists()) {
+ System.out.println("No resolver for " + language);
+ return null;
+ }
+
+ Resolver resolver = null;
+
+ try {
+ ObjectMapper mapper = getObjectMapper();
+ resolver = mapper.readerFor(Resolver.class).readValue(loadFile(file) );
+ } catch(IOException ioe) {
+
+ }
+ System.out.println("Resolver in " + language + " loaded in " + (System.currentTimeMillis() - t1) + "ms.");
+ return resolver;
+ }
+
+ public static boolean writeResolver(Resolver resolver, String language) {
+ ObjectMapper mapper = getObjectMapper();
+
+ try {
+ String serialized = mapper.writeValueAsString(resolver);
+ writeFile(serialized.getBytes(), language);
+ }catch(IOException e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private static void writeFile(byte[] content, String language) throws IOException {
+
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+
+ GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
+ gzipOutputStream.write(content);
+ gzipOutputStream.close();
+
+ FileOutputStream out = new FileOutputStream( "src/main/resources/resolvers/" + language );
+ out.write(byteArrayOutputStream.toByteArray());
+ out.flush();
+ out.close();
+ }
+
+
+ private static InputStream loadFile(File file) throws IOException {
+ FileInputStream fis = new FileInputStream(file);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int count = 0;
+ while ((count = fis.read(buffer))!=-1){
+ out.write(buffer, 0, count);
+ }
+ byte[] b = out.toByteArray();
+ fis.close();
+
+ return new GZIPInputStream(new ByteArrayInputStream(b));
+ }
+
+ private static ObjectMapper getObjectMapper() {
+ ObjectMapper mapper = new ObjectMapper();
+
+ SimpleModule module = new SimpleModule();
+
+ SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver();
+ resolver.addMapping(Node.class, HashNodeImpl.class);
+
+ module.setAbstractTypes(resolver);
+ module.addSerializer(Node.class, new NodeSerializer());
+ mapper.registerModule(module);
+
+ return mapper;
+ }
+
}
diff --git a/src/main/java/fr/pavnay/scrabble/impl/HashNodeImpl.java b/src/main/java/fr/pavnay/scrabble/impl/HashNodeImpl.java
new file mode 100644
index 0000000..f1eeec6
--- /dev/null
+++ b/src/main/java/fr/pavnay/scrabble/impl/HashNodeImpl.java
@@ -0,0 +1,81 @@
+package fr.pavnay.scrabble.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import fr.pavnay.scrabble.Node;
+
+public class HashNodeImpl implements Node {
+
+ private static final long serialVersionUID = 4221818951064573126L;
+
+ private Map nodes = new HashMap();
+ private List words;
+ private String parent;
+
+ public HashNodeImpl() {
+ }
+
+ public HashNodeImpl(String parent) {
+ this.parent = parent;
+ }
+
+ public void addWord(String word) {
+ if (this.words == null) {
+ this.words = new ArrayList();
+ }
+ if (!this.words.contains(word)) {
+ this.words.add(word);
+ }
+ }
+
+ public List getWords() {
+ if (this.words == null) {
+ return null;
+ }
+ Collections.sort(this.words);
+ return this.words;
+ }
+
+ public Map getNodes() {
+ return nodes;
+ }
+
+ public Node getNode(char character) {
+ Node node = this.nodes.get(character);
+ if (node == null) {
+ node = new HashNodeImpl(this.parent + character);
+ nodes.put(character, node);
+ }
+ return node;
+ }
+
+ public int getWordsCount() {
+ int total = 0;
+
+ for(Map.Entry node : nodes.entrySet()) {
+ total += node.getValue().getWordsCount();
+ }
+ if (this.words != null) {
+ total += this.words.size();
+ }
+
+ return total;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder("Parent " + this.parent);
+ if (this.words != null) {
+ sb.append(this.words.toString());
+ } else {
+ sb.append('-');
+ }
+ for(Map.Entry node : nodes.entrySet()) {
+ sb.append(node.getValue());
+ }
+ return sb.toString();
+ }
+}
diff --git a/src/main/java/fr/pavnay/scrabble/impl/NodeImpl.java b/src/main/java/fr/pavnay/scrabble/impl/NodeImpl.java
new file mode 100644
index 0000000..4351c3c
--- /dev/null
+++ b/src/main/java/fr/pavnay/scrabble/impl/NodeImpl.java
@@ -0,0 +1,81 @@
+package fr.pavnay.scrabble.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import fr.pavnay.scrabble.Node;
+
+public class NodeImpl implements Node {
+ private static final long serialVersionUID = 6637351994367583747L;
+
+ public Node[] nodes = new Node[26];
+ public List words;
+ private String parent;
+
+ public NodeImpl() {}
+
+ public NodeImpl(String parent) {
+ this.parent = parent;
+ }
+
+ public void addWord(String word) {
+ if (this.words == null) {
+ this.words = new ArrayList();
+ }
+ if (!this.words.contains(word)) {
+ this.words.add(word);
+ }
+ }
+
+ public List getWords() {
+ if (this.words == null) {
+ return null;
+ }
+ Collections.sort(this.words);
+ return this.words;
+ }
+
+ public Node[] getNodes() {
+ return this.nodes;
+ }
+
+ public Node getNode(char character) {
+ Node node = this.nodes[(character - 'a')];
+ if (node == null) {
+ node = new NodeImpl(this.parent + character);
+ this.nodes[(character - 'a')] = node;
+ }
+ return node;
+ }
+
+ public int getWordsCount() {
+ int total = 0;
+ for (int i = 0; i < 26; i++) {
+ Node current = this.nodes[i];
+ if (current != null) {
+ total += current.getWordsCount();
+ }
+ if (this.words != null) {
+ total += this.words.size();
+ }
+ }
+ return total;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder("Parent " + this.parent);
+ if (this.words != null) {
+ sb.append(this.words.toString());
+ } else {
+ sb.append('-');
+ }
+ for (int i = 0; i < 26; i++) {
+ Node current = this.nodes[i];
+ if (current != null) {
+ sb.append(current);
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/src/main/java/fr/pavnay/scrabble/serializer/NodeSerializer.java b/src/main/java/fr/pavnay/scrabble/serializer/NodeSerializer.java
new file mode 100644
index 0000000..7d78994
--- /dev/null
+++ b/src/main/java/fr/pavnay/scrabble/serializer/NodeSerializer.java
@@ -0,0 +1,29 @@
+package fr.pavnay.scrabble.serializer;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+import fr.pavnay.scrabble.Node;
+
+public class NodeSerializer extends StdSerializer {
+ private static final long serialVersionUID = -5136242177329213286L;
+
+ public NodeSerializer() {
+ this(null);
+ }
+
+ public NodeSerializer(Class t) {
+ super(t);
+ }
+
+ @Override
+ public void serialize(Node node, JsonGenerator generator, SerializerProvider provider) throws IOException {
+ generator.writeStartObject();
+ generator.writeObjectField("nodes", node.getNodes());
+ generator.writeObjectField("words", node.getWords());
+ generator.writeEndObject();
+ }
+}
diff --git a/src/main/resources/resolvers/english b/src/main/resources/resolvers/english
index 72d1b80..68f082a 100644
Binary files a/src/main/resources/resolvers/english and b/src/main/resources/resolvers/english differ
diff --git a/src/main/resources/resolvers/french b/src/main/resources/resolvers/french
index a490ee0..d7771dd 100644
Binary files a/src/main/resources/resolvers/french and b/src/main/resources/resolvers/french differ