You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@joshua.apache.org by mj...@apache.org on 2016/08/29 16:49:19 UTC
[06/10] incubator-joshua git commit: Renamed Translations class to
TranslationResponseStream
Renamed Translations class to TranslationResponseStream
Project: http://git-wip-us.apache.org/repos/asf/incubator-joshua/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-joshua/commit/6d8f6848
Tree: http://git-wip-us.apache.org/repos/asf/incubator-joshua/tree/6d8f6848
Diff: http://git-wip-us.apache.org/repos/asf/incubator-joshua/diff/6d8f6848
Branch: refs/heads/7
Commit: 6d8f684836ddc25e40bb32f91d24d3f6e5eb745b
Parents: 0bb2932
Author: Kellen Sunderland <ke...@amazon.com>
Authored: Mon Aug 29 13:58:52 2016 +0200
Committer: Kellen Sunderland <ke...@amazon.com>
Committed: Mon Aug 29 13:58:52 2016 +0200
----------------------------------------------------------------------
.../java/org/apache/joshua/decoder/Decoder.java | 12 +-
.../apache/joshua/decoder/JoshuaDecoder.java | 4 +-
.../decoder/TranslationResponseStream.java | 176 +++++++++++++++++++
.../org/apache/joshua/decoder/Translations.java | 176 -------------------
.../org/apache/joshua/server/ServerThread.java | 10 +-
.../system/MultithreadedTranslationTests.java | 10 +-
6 files changed, 194 insertions(+), 194 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-joshua/blob/6d8f6848/src/main/java/org/apache/joshua/decoder/Decoder.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/joshua/decoder/Decoder.java b/src/main/java/org/apache/joshua/decoder/Decoder.java
index c7b2168..682e290 100644
--- a/src/main/java/org/apache/joshua/decoder/Decoder.java
+++ b/src/main/java/org/apache/joshua/decoder/Decoder.java
@@ -66,7 +66,7 @@ import org.slf4j.LoggerFactory;
*
* After initialization, the main entry point to the Decoder object is
* decodeAll(TranslationRequest), which returns a set of Translation objects wrapped in an iterable
- * Translations object. It is important that we support multithreading both (a) across the sentences
+ * TranslationResponseStream object. It is important that we support multithreading both (a) across the sentences
* within a request and (b) across requests, in a round-robin fashion. This is done by maintaining a
* fixed sized concurrent thread pool. When a new request comes in, a RequestParallelizer thread is
* launched. This object iterates over the request's sentences, obtaining a thread from the
@@ -78,7 +78,7 @@ import org.slf4j.LoggerFactory;
*
* A decoding thread is handled by DecoderTask and launched from DecoderThreadRunner. The purpose
* of the runner is to record where to place the translated sentence when it is done (i.e., which
- * Translations object). Translations itself is an iterator whose next() call blocks until the next
+ * TranslationResponseStream object). TranslationResponseStream itself is an iterator whose next() call blocks until the next
* translation is available.
*
* @author Matt Post post@cs.jhu.edu
@@ -172,16 +172,16 @@ public class Decoder {
*
* @param request the populated {@link TranslationRequestStream}
* @throws RuntimeException if any fatal errors occur during translation
- * @return an iterable, asynchronously-filled list of Translations
+ * @return an iterable, asynchronously-filled list of TranslationResponseStream
*/
- public Translations decodeAll(TranslationRequestStream request) {
- Translations results = new Translations(request);
+ public TranslationResponseStream decodeAll(TranslationRequestStream request) {
+ TranslationResponseStream results = new TranslationResponseStream(request);
CompletableFuture.runAsync(() -> decodeAllAsync(request, results));
return results;
}
private void decodeAllAsync(TranslationRequestStream request,
- Translations responseStream) {
+ TranslationResponseStream responseStream) {
// Give the threadpool a friendly name to help debuggers
final ThreadFactory threadFactory = new ThreadFactoryBuilder()
http://git-wip-us.apache.org/repos/asf/incubator-joshua/blob/6d8f6848/src/main/java/org/apache/joshua/decoder/JoshuaDecoder.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/joshua/decoder/JoshuaDecoder.java b/src/main/java/org/apache/joshua/decoder/JoshuaDecoder.java
index b1b9d1e..d10de8c 100644
--- a/src/main/java/org/apache/joshua/decoder/JoshuaDecoder.java
+++ b/src/main/java/org/apache/joshua/decoder/JoshuaDecoder.java
@@ -101,14 +101,14 @@ public class JoshuaDecoder {
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
TranslationRequestStream fileRequest = new TranslationRequestStream(reader, joshuaConfiguration);
- Translations translations = decoder.decodeAll(fileRequest);
+ TranslationResponseStream translationResponseStream = decoder.decodeAll(fileRequest);
// Create the n-best output stream
FileWriter nbest_out = null;
if (joshuaConfiguration.n_best_file != null)
nbest_out = new FileWriter(joshuaConfiguration.n_best_file);
- for (Translation translation: translations) {
+ for (Translation translation: translationResponseStream) {
/**
* We need to munge the feature value outputs in order to be compatible with Moses tuners.
http://git-wip-us.apache.org/repos/asf/incubator-joshua/blob/6d8f6848/src/main/java/org/apache/joshua/decoder/TranslationResponseStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/joshua/decoder/TranslationResponseStream.java b/src/main/java/org/apache/joshua/decoder/TranslationResponseStream.java
new file mode 100644
index 0000000..f64df69
--- /dev/null
+++ b/src/main/java/org/apache/joshua/decoder/TranslationResponseStream.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.joshua.decoder;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import com.google.common.base.Throwables;
+import org.apache.joshua.decoder.io.TranslationRequestStream;
+
+/**
+ * This class represents a streaming sequence of translations. It is returned by the main entry
+ * point to the Decoder object, the call to decodeAll. The translations here are parallel to the
+ * input sentences in the corresponding TranslationRequest object. Because of parallelization, the
+ * translated sentences might be computed out of order. Each Translation is sent to this
+ * TranslationResponseStream object by a DecoderThreadRunner via the record() function, which places the
+ * Translation in the right place. When the next translation in a sequence is available, next() is
+ * notified.
+ *
+ * @author Matt Post post@cs.jhu.edu
+ */
+public class TranslationResponseStream implements Iterator<Translation>, Iterable<Translation> {
+
+ /* The source sentences to be translated. */
+ private TranslationRequestStream request = null;
+
+ /*
+ * This records the index of the sentence at the head of the underlying list. The iterator's
+ * next() blocks when the value at this position in the translations LinkedList is null.
+ */
+ private int currentID = 0;
+
+ /* The set of translated sentences. */
+ private LinkedList<Translation> translations = null;
+
+ private boolean spent = false;
+
+ private Translation nextTranslation;
+ private Throwable fatalException;
+
+ public TranslationResponseStream(TranslationRequestStream request) {
+ this.request = request;
+ this.translations = new LinkedList<>();
+ }
+
+ /**
+ * This is called when null is received from the TranslationRequest, indicating that there are no
+ * more input sentences to translated. That in turn means that the request size will no longer
+ * grow. We then notify any waiting thread if the last ID we've processed is the last one, period.
+ */
+ public void finish() {
+ synchronized (this) {
+ spent = true;
+ if (currentID == request.size()) {
+ this.notifyAll();
+ }
+ }
+ }
+
+ /**
+ * This is called whenever a translation is completed by one of the decoder threads. There may be
+ * a current output thread waiting for the current translation, which is determined by checking if
+ * the ID of the translation is the same as the one being waited for (currentID). If so, the
+ * thread waiting for it is notified.
+ *
+ * @param translation a translated input object
+ */
+ public void record(Translation translation) {
+ synchronized (this) {
+
+ /* Pad the set of translations with nulls to accommodate the new translation. */
+ int offset = translation.id() - currentID;
+ while (offset >= translations.size())
+ translations.add(null);
+ translations.set(offset, translation);
+
+ /*
+ * If the id of the current translation is at the head of the list (first element), then we
+ * have the next Translation to be return, and we should notify anyone waiting on next(),
+ * which will then remove the item and increment the currentID.
+ */
+ if (translation.id() == currentID) {
+ this.notify();
+ }
+ }
+ }
+
+ /**
+ * Returns the next Translation, blocking if necessary until it's available, since the next
+ * Translation might not have been produced yet.
+ *
+ * @return first element from the list of {@link org.apache.joshua.decoder.Translation}'s
+ */
+ @Override
+ public Translation next() {
+ synchronized(this) {
+ if (this.hasNext()) {
+ Translation t = this.nextTranslation;
+ this.nextTranslation = null;
+ return t;
+ }
+
+ return null;
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ synchronized (this) {
+
+ if (nextTranslation != null)
+ return true;
+
+ /*
+ * If there are no more input sentences, and we've already distributed what we then know is
+ * the last one, we're done.
+ */
+ if (spent && currentID == request.size())
+ return false;
+
+ /*
+ * Otherwise, there is another sentence. If it's not available already, we need to wait for
+ * it.
+ */
+ if (translations.size() == 0 || translations.peek() == null) {
+ try {
+ this.wait();
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ fatalErrorCheck();
+
+ /* We now have the sentence and can return it. */
+ currentID++;
+ this.nextTranslation = translations.poll();
+ return this.nextTranslation != null;
+ }
+ }
+
+ @Override
+ public Iterator<Translation> iterator() {
+ return this;
+ }
+
+ public void propagate(Throwable ex) {
+ synchronized (this) {
+ fatalException = ex;
+ notify();
+ }
+ }
+
+ private void fatalErrorCheck() {
+ if (fatalException != null) {
+ Throwables.propagate(fatalException);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-joshua/blob/6d8f6848/src/main/java/org/apache/joshua/decoder/Translations.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/joshua/decoder/Translations.java b/src/main/java/org/apache/joshua/decoder/Translations.java
deleted file mode 100644
index b3f3633..0000000
--- a/src/main/java/org/apache/joshua/decoder/Translations.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.joshua.decoder;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import com.google.common.base.Throwables;
-import org.apache.joshua.decoder.io.TranslationRequestStream;
-
-/**
- * This class represents a streaming sequence of translations. It is returned by the main entry
- * point to the Decoder object, the call to decodeAll. The translations here are parallel to the
- * input sentences in the corresponding TranslationRequest object. Because of parallelization, the
- * translated sentences might be computed out of order. Each Translation is sent to this
- * Translations object by a DecoderThreadRunner via the record() function, which places the
- * Translation in the right place. When the next translation in a sequence is available, next() is
- * notified.
- *
- * @author Matt Post post@cs.jhu.edu
- */
-public class Translations implements Iterator<Translation>, Iterable<Translation> {
-
- /* The source sentences to be translated. */
- private TranslationRequestStream request = null;
-
- /*
- * This records the index of the sentence at the head of the underlying list. The iterator's
- * next() blocks when the value at this position in the translations LinkedList is null.
- */
- private int currentID = 0;
-
- /* The set of translated sentences. */
- private LinkedList<Translation> translations = null;
-
- private boolean spent = false;
-
- private Translation nextTranslation;
- private Throwable fatalException;
-
- public Translations(TranslationRequestStream request) {
- this.request = request;
- this.translations = new LinkedList<>();
- }
-
- /**
- * This is called when null is received from the TranslationRequest, indicating that there are no
- * more input sentences to translated. That in turn means that the request size will no longer
- * grow. We then notify any waiting thread if the last ID we've processed is the last one, period.
- */
- public void finish() {
- synchronized (this) {
- spent = true;
- if (currentID == request.size()) {
- this.notifyAll();
- }
- }
- }
-
- /**
- * This is called whenever a translation is completed by one of the decoder threads. There may be
- * a current output thread waiting for the current translation, which is determined by checking if
- * the ID of the translation is the same as the one being waited for (currentID). If so, the
- * thread waiting for it is notified.
- *
- * @param translation a translated input object
- */
- public void record(Translation translation) {
- synchronized (this) {
-
- /* Pad the set of translations with nulls to accommodate the new translation. */
- int offset = translation.id() - currentID;
- while (offset >= translations.size())
- translations.add(null);
- translations.set(offset, translation);
-
- /*
- * If the id of the current translation is at the head of the list (first element), then we
- * have the next Translation to be return, and we should notify anyone waiting on next(),
- * which will then remove the item and increment the currentID.
- */
- if (translation.id() == currentID) {
- this.notify();
- }
- }
- }
-
- /**
- * Returns the next Translation, blocking if necessary until it's available, since the next
- * Translation might not have been produced yet.
- *
- * @return first element from the list of {@link org.apache.joshua.decoder.Translation}'s
- */
- @Override
- public Translation next() {
- synchronized(this) {
- if (this.hasNext()) {
- Translation t = this.nextTranslation;
- this.nextTranslation = null;
- return t;
- }
-
- return null;
- }
- }
-
- @Override
- public boolean hasNext() {
- synchronized (this) {
-
- if (nextTranslation != null)
- return true;
-
- /*
- * If there are no more input sentences, and we've already distributed what we then know is
- * the last one, we're done.
- */
- if (spent && currentID == request.size())
- return false;
-
- /*
- * Otherwise, there is another sentence. If it's not available already, we need to wait for
- * it.
- */
- if (translations.size() == 0 || translations.peek() == null) {
- try {
- this.wait();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- fatalErrorCheck();
-
- /* We now have the sentence and can return it. */
- currentID++;
- this.nextTranslation = translations.poll();
- return this.nextTranslation != null;
- }
- }
-
- @Override
- public Iterator<Translation> iterator() {
- return this;
- }
-
- public void propagate(Throwable ex) {
- synchronized (this) {
- fatalException = ex;
- notify();
- }
- }
-
- private void fatalErrorCheck() {
- if (fatalException != null) {
- Throwables.propagate(fatalException);
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-joshua/blob/6d8f6848/src/main/java/org/apache/joshua/server/ServerThread.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/joshua/server/ServerThread.java b/src/main/java/org/apache/joshua/server/ServerThread.java
index 32c7b91..976e543 100644
--- a/src/main/java/org/apache/joshua/server/ServerThread.java
+++ b/src/main/java/org/apache/joshua/server/ServerThread.java
@@ -38,7 +38,7 @@ import com.sun.net.httpserver.HttpHandler;
import org.apache.joshua.decoder.Decoder;
import org.apache.joshua.decoder.JoshuaConfiguration;
import org.apache.joshua.decoder.Translation;
-import org.apache.joshua.decoder.Translations;
+import org.apache.joshua.decoder.TranslationResponseStream;
import org.apache.joshua.decoder.ff.tm.Rule;
import org.apache.joshua.decoder.ff.tm.Trie;
import org.apache.joshua.decoder.ff.tm.format.HieroFormatReader;
@@ -89,11 +89,11 @@ public class ServerThread extends Thread implements HttpHandler {
TranslationRequestStream request = new TranslationRequestStream(reader, joshuaConfiguration);
try {
- Translations translations = decoder.decodeAll(request);
+ TranslationResponseStream translationResponseStream = decoder.decodeAll(request);
OutputStream out = socket.getOutputStream();
- for (Translation translation: translations) {
+ for (Translation translation: translationResponseStream) {
out.write(translation.toString().getBytes());
}
@@ -162,12 +162,12 @@ public class ServerThread extends Thread implements HttpHandler {
BufferedReader reader = new BufferedReader(new StringReader(query));
TranslationRequestStream request = new TranslationRequestStream(reader, joshuaConfiguration);
- Translations translations = decoder.decodeAll(request);
+ TranslationResponseStream translationResponseStream = decoder.decodeAll(request);
JSONMessage message = new JSONMessage();
if (meta != null && ! meta.isEmpty())
handleMetadata(meta, message);
- for (Translation translation: translations) {
+ for (Translation translation: translationResponseStream) {
LOG.info("TRANSLATION: '{}' with {} k-best items", translation, translation.getStructuredTranslations().size());
message.addTranslation(translation);
}
http://git-wip-us.apache.org/repos/asf/incubator-joshua/blob/6d8f6848/src/test/java/org/apache/joshua/system/MultithreadedTranslationTests.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/joshua/system/MultithreadedTranslationTests.java b/src/test/java/org/apache/joshua/system/MultithreadedTranslationTests.java
index 7a1d9f4..8192cb3 100644
--- a/src/test/java/org/apache/joshua/system/MultithreadedTranslationTests.java
+++ b/src/test/java/org/apache/joshua/system/MultithreadedTranslationTests.java
@@ -29,7 +29,7 @@ import java.util.ArrayList;
import org.apache.joshua.decoder.Decoder;
import org.apache.joshua.decoder.JoshuaConfiguration;
import org.apache.joshua.decoder.Translation;
-import org.apache.joshua.decoder.Translations;
+import org.apache.joshua.decoder.TranslationResponseStream;
import org.apache.joshua.decoder.io.TranslationRequestStream;
import org.apache.joshua.decoder.segment_file.Sentence;
import org.mockito.Mockito;
@@ -130,14 +130,14 @@ public class MultithreadedTranslationTests {
// WHEN
// Translate all segments in parallel.
- Translations translations = this.decoder.decodeAll(req);
+ TranslationResponseStream translationResponseStream = this.decoder.decodeAll(req);
ArrayList<Translation> translationResults = new ArrayList<Translation>();
final long translationStartTime = System.nanoTime();
try {
- for (Translation t: translations)
+ for (Translation t: translationResponseStream)
translationResults.add(t);
} finally {
if (output != null) {
@@ -168,10 +168,10 @@ public class MultithreadedTranslationTests {
// WHEN
// Translate all segments in parallel.
- Translations translations = this.decoder.decodeAll(spyReq);
+ TranslationResponseStream translationResponseStream = this.decoder.decodeAll(spyReq);
ArrayList<Translation> translationResults = new ArrayList<>();
- for (Translation t: translations)
+ for (Translation t: translationResponseStream)
translationResults.add(t);
}