krickert commented on code in PR #1163:
URL: https://github.com/apache/opennlp/pull/1163#discussion_r3566265571
##########
opennlp-api/src/main/java/opennlp/tools/stemmer/Stemmer.java:
##########
@@ -17,10 +17,37 @@
package opennlp.tools.stemmer;
+import java.util.List;
+
/**
- * The stemmer is reducing a word to its stem.
+ * Reduces a word to its root form.
+ *
+ * <p>Thread safety is implementation-specific: check the implementation's
documentation before
+ * sharing an instance across threads. Stateful engines mutate internal
buffers on each
+ * {@link #stem(CharSequence)} call; when an implementation is not documented
as thread-safe,
+ * share a {@link StemmerFactory} across threads and confine each {@code
Stemmer} to one thread,
+ * or wrap the factory in a thread-local adapter when a single {@code Stemmer}
reference must be
+ * shared.</p>
*/
public interface Stemmer {
+ /**
+ * Stems {@code word}.
+ *
+ * @param word The input word. Must not be {@code null}.
Review Comment:
Documented as IllegalArgumentException and enforced: guards added across the
API (Snowball, factory products, the caching and sharing wrappers, and
PorterStemmer), pinned by a test.
##########
opennlp-api/src/main/java/opennlp/tools/stemmer/Stemmer.java:
##########
@@ -17,10 +17,37 @@
package opennlp.tools.stemmer;
+import java.util.List;
+
/**
- * The stemmer is reducing a word to its stem.
+ * Reduces a word to its root form.
+ *
+ * <p>Thread safety is implementation-specific: check the implementation's
documentation before
+ * sharing an instance across threads. Stateful engines mutate internal
buffers on each
+ * {@link #stem(CharSequence)} call; when an implementation is not documented
as thread-safe,
+ * share a {@link StemmerFactory} across threads and confine each {@code
Stemmer} to one thread,
+ * or wrap the factory in a thread-local adapter when a single {@code Stemmer}
reference must be
+ * shared.</p>
*/
public interface Stemmer {
+ /**
+ * Stems {@code word}.
+ *
+ * @param word The input word. Must not be {@code null}.
+ * @return The stemmed form.
+ */
CharSequence stem(CharSequence word);
+
+ /**
+ * {@return every stem form for {@code word}} The default returns a
single-element list with
+ * {@link #stem(CharSequence)}. Dictionary-based engines that can produce
several root forms for
+ * one word override this; wrappers that delegate to another {@code Stemmer}
must forward this
+ * method so a multi-output delegate keeps its full result list.
+ *
+ * @param word The input word. Must not be {@code null}.
Review Comment:
Same as above: documented and guarded.
##########
opennlp-core/opennlp-runtime/src/main/java/opennlp/tools/stemmer/SharingStemmer.java:
##########
@@ -0,0 +1,69 @@
+/*
+ * 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 opennlp.tools.stemmer;
+
+import java.util.List;
+
+import opennlp.tools.commons.ThreadSafe;
+import opennlp.tools.util.OwnerOrPerThreadState;
+
+/**
+ * A {@link Stemmer} that is safe to share across threads by routing each call
to a per-thread
+ * delegate minted from a {@link StemmerFactory}. Use it to share a stemmer
whose implementation is
+ * <em>not</em> itself thread-safe, such as {@link PorterStemmer}; thread-safe
implementations like
+ * {@code SnowballStemmer} do not need this wrapper.
+ *
+ * <p>The first thread uses a single owner delegate without touching {@link
ThreadLocal} until a
+ * second thread appears, matching the {@link OwnerOrPerThreadState} pattern
used by the
+ * thread-safe {@code *ME} components.</p>
+ */
+@ThreadSafe
+public final class SharingStemmer implements Stemmer {
Review Comment:
The generic part already lives in OwnerOrPerThreadState; the real
duplication was SnowballStemmer re-implementing the same routing. It now
composes a SharingStemmer internally, so the pattern exists in exactly one
class.
##########
opennlp-core/opennlp-runtime/src/main/java/opennlp/tools/stemmer/snowball/SnowballStemmerFactory.java:
##########
@@ -0,0 +1,91 @@
+/*
+ * 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 opennlp.tools.stemmer.snowball;
+
+import opennlp.tools.commons.ThreadSafe;
+import opennlp.tools.stemmer.Stemmer;
+import opennlp.tools.stemmer.StemmerFactory;
+
+/**
+ * A thread-safe factory that captures a Snowball stemmer configuration for
APIs that accept a
+ * {@link StemmerFactory}.
+ *
+ * <p>{@link #newStemmer()} returns a thread-confined stemmer that drives its
generated engine
Review Comment:
Done, used your framing: the javadoc now reads 'Use this factory for the
classic one-stemmer-per-thread pattern.'
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]