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);
   }