This is an automated email from the ASF dual-hosted git repository. sergeykamov pushed a commit to branch NLPCRAFT-477 in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
commit 613a751e7777f46470240c14353f018b7641be67 Author: Sergey Kamov <skhdlem...@gmail.com> AuthorDate: Fri Feb 18 12:36:00 2022 +0300 WIP. --- .../scala/org/apache/nlpcraft/NCConversation.java | 2 +- ...sationHolder.scala => NCConversationData.scala} | 23 ++++++---------------- .../conversation/NCConversationManager.scala | 7 +++---- .../internal/dialogflow/NCDialogFlowManager.scala | 5 +++-- .../nlpcraft/internal/impl/NCModelClientImpl.scala | 12 ++++++----- .../conversation/NCConversationManagerSpec.scala | 12 +++++------ .../dialogflow/NCDialogFlowManagerSpec.scala | 3 ++- 7 files changed, 27 insertions(+), 37 deletions(-) diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCConversation.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCConversation.java index e2dcfb5..7856601 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCConversation.java +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCConversation.java @@ -60,5 +60,5 @@ public interface NCConversation { * * @param filter Dialog flow filter. */ - void clearDialog(Predicate<String> filter); // TODO: was NCDialogFlowItem + void clearDialog(Predicate<NCDialogFlowItem> filter); } diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationData.scala similarity index 92% rename from nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala rename to nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationData.scala index 6f5f13c..f9d97ff 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationData.scala @@ -32,7 +32,7 @@ import scala.jdk.CollectionConverters.* /** * An active conversation is an ordered set of utterances for the specific user and data model. */ -case class NCConversationHolder( +case class NCConversationData( usrId: String, mdlId: String, timeoutMs: Long, @@ -111,7 +111,7 @@ case class NCConversationHolder( * * @param p Java-side predicate. */ - def clearEntities(p: Predicate[NCEntity]): Unit = + def clear(p: Predicate[NCEntity]): Unit = stm.synchronized { for (item <- stm) item.holders --= item.holders.filter(h => p.test(h.entity)) squeezeEntities() @@ -121,16 +121,6 @@ case class NCConversationHolder( logger.trace(s"STM is cleared [usrId=$usrId, mdlId=$mdlId]") /** - * Clears all entities from this conversation satisfying given predicate. - * - * @param p Scala-side predicate. - */ - def clearEntities(p: NCEntity => Boolean): Unit = - clearEntities(new Predicate[NCEntity]: - override def test(t: NCEntity): Boolean = p(t) - ) - - /** * * @param ents */ @@ -206,16 +196,15 @@ case class NCConversationHolder( * * @return */ - def getEntities: util.List[NCEntity] = + def getEntities: Seq[NCEntity] = + // TODO: copy? stm.synchronized { val reqIds = ctx.map(_.getRequestId).distinct.zipWithIndex.toMap - val ents = ctx.groupBy(_.getRequestId).toSeq.sortBy(p => reqIds(p._1)).reverse.flatMap(_._2) - - new util.ArrayList[NCEntity](ents.asJava) + ctx.groupBy(_.getRequestId).toSeq.sortBy(p => reqIds(p._1)).reverse.flatMap(_._2) } /** - * + * TODO: thread safe? */ val getUserData: NCPropertyMap = data } \ No newline at end of file diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationManager.scala index 77574da..1b1d052 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationManager.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationManager.scala @@ -28,22 +28,21 @@ import scala.jdk.CollectionConverters.* * Conversation manager. */ class NCConversationManager(cfg: NCModelConfig) extends LazyLogging: - case class Value(conv: NCConversationHolder, var tstamp: Long = 0) + case class Value(conv: NCConversationData, var tstamp: Long = 0) private final val convs: mutable.Map[String, Value] = mutable.HashMap.empty[String, Value] @volatile private var gc: Thread = _ - /** * Gets conversation for given user ID. * * @param usrId User ID. * @return New or existing conversation. */ - def getConversation(usrId: String): NCConversationHolder = + def getConversation(usrId: String): NCConversationData = convs.synchronized { val v = convs.getOrElseUpdate( usrId, - Value(NCConversationHolder(usrId, cfg.getId, cfg.getConversationTimeout, cfg.getConversationDepth)) + Value(NCConversationData(usrId, cfg.getId, cfg.getConversationTimeout, cfg.getConversationDepth)) ) v.tstamp = NCUtils.nowUtcMs() diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManager.scala index 1026e3d..adac2f1 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManager.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManager.scala @@ -117,6 +117,7 @@ class NCDialogFlowManager(cfg: NCModelConfig) extends LazyLogging: * @return Dialog flow. */ def getDialogFlow(usrId: String): Seq[NCDialogFlowItem] = + // TODO: copy? flow.synchronized { flow.get(usrId) } match case Some(buf) => buf.toSeq case None => Seq.empty @@ -166,8 +167,8 @@ class NCDialogFlowManager(cfg: NCModelConfig) extends LazyLogging: * @param pred Intent ID predicate. * @param parent Parent span, if any. */ - def clearForPredicate(usrId: String, pred: String => Boolean): Unit = + def clear(usrId: String, pred: NCDialogFlowItem => Boolean): Unit = flow.synchronized { - flow(usrId) = flow(usrId).filterNot(v => pred(v.getIntentMatch.getIntentId)) + flow(usrId) = flow(usrId).filterNot(pred) flow.notifyAll() } diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelClientImpl.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelClientImpl.scala index 6990e5a..facdabf 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelClientImpl.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelClientImpl.scala @@ -90,7 +90,6 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging: dlgMgr.start() plMgr.start() - /** * * @param data @@ -104,10 +103,10 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging: val conv: NCConversation = new NCConversation: override val getSession: NCPropertyMap = convHldr.getUserData - override val getStm: JList[NCEntity] = convHldr.getEntities + override val getStm: JList[NCEntity] = convHldr.getEntities.asJava override val getDialogFlow: JList[NCDialogFlowItem] = dlgMgr.getDialogFlow(userId).asJava - override def clearStm(filter: Predicate[NCEntity]): Unit = convHldr.clearEntities(filter) - override def clearDialog(filter: Predicate[String]): Unit = dlgMgr.clearForPredicate(userId, (s: String) => filter.test(s)) + override def clearStm(filter: Predicate[NCEntity]): Unit = convHldr.clear(filter) + override def clearDialog(filter: Predicate[NCDialogFlowItem]): Unit = dlgMgr.clear(userId, (s: NCDialogFlowItem) => filter.test(s)) val ctx: NCContext = new NCContext: @@ -146,7 +145,7 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging: * * @param usrId */ - def clearConversation(usrId: String): Unit = convMgr.getConversation(usrId).clearEntities(_ => true) + def clearConversation(usrId: String): Unit = convMgr.getConversation(usrId).clear(_ => true) /** * @@ -154,6 +153,9 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging: */ def clearDialog(usrId: String): Unit = dlgMgr.clear(usrId) + /** + * + */ def close(): Unit = plMgr.close() dlgMgr.close() diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/conversation/NCConversationManagerSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/conversation/NCConversationManagerSpec.scala index 4a3de41..c402a99 100644 --- a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/conversation/NCConversationManagerSpec.scala +++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/conversation/NCConversationManagerSpec.scala @@ -39,7 +39,7 @@ class NCConversationManagerSpec: val conv = mgr.getConversation("user1") def checkSize(size: Int): Unit = - require(conv.getEntities.size() == size, s"Unexpected entities size: ${conv.getEntities.size()}, expected: $size") + require(conv.getEntities.sizeIs == size, s"Unexpected entities size: ${conv.getEntities.size}, expected: $size") // Initial empty. checkSize(0) @@ -53,11 +53,9 @@ class NCConversationManagerSpec: checkSize(2) // Partially cleared. - conv.clearEntities(new Predicate[NCEntity]: - override def test(t: NCEntity): Boolean = t.getId == "e1" - ) + conv.clear(_.getId == "e1") checkSize(1) - require(conv.getEntities.get(0).getId == "e2") + require(conv.getEntities.head.getId == "e2") @Test def testTimeout(): Unit = @@ -68,11 +66,11 @@ class NCConversationManagerSpec: val reqId = "req1" // TODO: Drop method and use saved conversation instead - error is thrown - def getConversation: NCConversationHolder = mgr.getConversation("user1") + def getConversation: NCConversationData = mgr.getConversation("user1") def checkSize(size: Int): Unit = val conv = getConversation - require(conv.getEntities.size() == size, s"Unexpected entities size: ${conv.getEntities.size()}, expected: $size") + require(conv.getEntities.sizeIs == size, s"Unexpected entities size: ${conv.getEntities.size}, expected: $size") // Initial empty. checkSize(0) diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManagerSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManagerSpec.scala index 01d2ef7..b8d0736 100644 --- a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManagerSpec.scala +++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManagerSpec.scala @@ -23,6 +23,7 @@ import org.apache.nlpcraft.nlp.util.NCTestRequest import org.junit.jupiter.api.* import java.util +import java.util.function.Predicate /** * @@ -99,7 +100,7 @@ class NCDialogFlowManagerSpec: mgr.clear(usrId = "user1") check("user1" -> 0, "user2" -> 2, "user3" -> 1, "user4" -> 0) - mgr.clearForPredicate(usrId = "user2", _ == "i21") + mgr.clear(usrId = "user2", _.getIntentMatch.getIntentId == "i21") check("user1" -> 0, "user2" -> 1, "user3" -> 1, "user4" -> 0) mgr.clear(usrId = "user2")