From 09c154925f1fd01d46ed67ad2faed41efba5a5ae Mon Sep 17 00:00:00 2001
From: Keisuke Kuroyanagi <ksk@google.com>
Date: Wed, 17 Sep 2014 21:16:31 +0900
Subject: [PATCH] Add firstOrDefault and lastOrDefault to IntArrayView.

Change-Id: I854c02eff3fa0b53c72a5f1cabce001f4854ada0
---
 .../v402/ver4_patricia_trie_policy.cpp        |  2 +-
 .../content/language_model_dict_content.cpp   |  4 ++--
 native/jni/src/utils/int_array_view.h         | 14 +++++++++++++
 .../jni/tests/utils/int_array_view_test.cpp   | 20 +++++++++++++++++++
 4 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp
index 41b9a11b11..ea8768811a 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp
@@ -397,7 +397,7 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor
     WordIdArray<MAX_PREV_WORD_COUNT_FOR_N_GRAM> prevWordIdArray;
     const WordIdArrayView prevWordIds = prevWordsInfo->getPrevWordIds(this, &prevWordIdArray,
             false /* tryLowerCaseSerch */);
-    if (prevWordIds.empty() || prevWordIds[0] == NOT_A_WORD_ID) {
+    if (prevWordIds.firstOrDefault(NOT_A_WORD_ID) == NOT_A_WORD_ID) {
         return false;
     }
     const int wordPos = getTerminalPtNodePosFromWordId(getWordId(wordCodePoints,
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp
index 85d6d434d5..35f0f768fd 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp
@@ -167,7 +167,7 @@ int LanguageModelDictContent::createAndGetBitmapEntryIndex(const WordIdArrayView
     if (lastBitmapEntryIndex == TrieMap::INVALID_INDEX) {
         return TrieMap::INVALID_INDEX;
     }
-    const int oldestPrevWordId = prevWordIds[prevWordIds.size() - 1];
+    const int oldestPrevWordId = prevWordIds.lastOrDefault(NOT_A_WORD_ID);
     const TrieMap::Result result = mTrieMap.get(oldestPrevWordId, lastBitmapEntryIndex);
     if (!result.mIsValid) {
         if (!mTrieMap.put(oldestPrevWordId,
@@ -175,7 +175,7 @@ int LanguageModelDictContent::createAndGetBitmapEntryIndex(const WordIdArrayView
             return TrieMap::INVALID_INDEX;
         }
     }
-    return mTrieMap.getNextLevelBitmapEntryIndex(prevWordIds[prevWordIds.size() - 1],
+    return mTrieMap.getNextLevelBitmapEntryIndex(prevWordIds.lastOrDefault(NOT_A_WORD_ID),
             lastBitmapEntryIndex);
 }
 
diff --git a/native/jni/src/utils/int_array_view.h b/native/jni/src/utils/int_array_view.h
index cc5f328ba9..f3a8589cab 100644
--- a/native/jni/src/utils/int_array_view.h
+++ b/native/jni/src/utils/int_array_view.h
@@ -115,6 +115,20 @@ class IntArrayView {
         memmove(buffer->data() + offset, mPtr, sizeof(int) * mSize);
     }
 
+    AK_FORCE_INLINE int firstOrDefault(const int defaultValue) const {
+        if (empty()) {
+            return defaultValue;
+        }
+        return mPtr[0];
+    }
+
+    AK_FORCE_INLINE int lastOrDefault(const int defaultValue) const {
+        if (empty()) {
+            return defaultValue;
+        }
+        return mPtr[mSize - 1];
+    }
+
  private:
     DISALLOW_ASSIGNMENT_OPERATOR(IntArrayView);
 
diff --git a/native/jni/tests/utils/int_array_view_test.cpp b/native/jni/tests/utils/int_array_view_test.cpp
index 934e27e1c5..487bd04b12 100644
--- a/native/jni/tests/utils/int_array_view_test.cpp
+++ b/native/jni/tests/utils/int_array_view_test.cpp
@@ -124,5 +124,25 @@ TEST(IntArrayViewTest, TestCopyToArray) {
     EXPECT_EQ(70, buffer[6]);
 }
 
+TEST(IntArrayViewTest, TestFirstOrDefault) {
+    const std::vector<int> intVector = {3, 2, 1, 0, -1, -2};
+    IntArrayView intArrayView(intVector);
+
+    EXPECT_EQ(3, intArrayView.firstOrDefault(10));
+    EXPECT_EQ(10, intArrayView.limit(0).firstOrDefault(10));
+    EXPECT_EQ(-10, intArrayView.limit(0).firstOrDefault(-10));
+    EXPECT_EQ(10, intArrayView.skip(6).firstOrDefault(10));
+}
+
+TEST(IntArrayViewTest, TestLastOrDefault) {
+    const std::vector<int> intVector = {3, 2, 1, 0, -1, -2};
+    IntArrayView intArrayView(intVector);
+
+    EXPECT_EQ(-2, intArrayView.lastOrDefault(10));
+    EXPECT_EQ(10, intArrayView.limit(0).lastOrDefault(10));
+    EXPECT_EQ(-10, intArrayView.limit(0).lastOrDefault(-10));
+    EXPECT_EQ(10, intArrayView.skip(6).lastOrDefault(10));
+}
+
 }  // namespace
 }  // namespace latinime
-- 
GitLab