6868503: RuleBasedBreakIterator is inefficient

Reviewed-by: okutsu
diff --git a/jdk/src/share/classes/java/text/RuleBasedBreakIterator.java b/jdk/src/share/classes/java/text/RuleBasedBreakIterator.java
index 8f0e6cb..4e46560 100644
--- a/jdk/src/share/classes/java/text/RuleBasedBreakIterator.java
+++ b/jdk/src/share/classes/java/text/RuleBasedBreakIterator.java
@@ -621,6 +621,8 @@
         return handleNext();
     }
 
+    private int cachedLastKnownBreak = BreakIterator.DONE;
+
     /**
      * Advances the iterator backwards, to the last boundary preceding this one.
      * @return The position of the last boundary position preceding this one.
@@ -638,8 +640,16 @@
         // the current position), but not necessarily the last one before
         // where we started
         int start = current();
-        getPrevious();
-        int lastResult = handlePrevious();
+        int lastResult = cachedLastKnownBreak;
+        if (lastResult >= start || lastResult <= BreakIterator.DONE) {
+            getPrevious();
+            lastResult = handlePrevious();
+        } else {
+            //it might be better to check if handlePrevious() give us closer
+            //safe value but handlePrevious() is slow too
+            //So, this has to be done carefully
+            text.setIndex(lastResult);
+        }
         int result = lastResult;
 
         // iterate forward from the known break position until we pass our
@@ -653,6 +663,7 @@
         // set the current iteration position to be the last break position
         // before where we started, and then return that value
         text.setIndex(lastResult);
+        cachedLastKnownBreak = lastResult;
         return lastResult;
     }
 
@@ -757,7 +768,8 @@
         // then we can just use next() to get our return value
         text.setIndex(offset);
         if (offset == text.getBeginIndex()) {
-            return handleNext();
+            cachedLastKnownBreak = handleNext();
+            return cachedLastKnownBreak;
         }
 
         // otherwise, we have to sync up first.  Use handlePrevious() to back
@@ -767,10 +779,19 @@
         // position at or before our starting position.  Advance forward
         // from here until we've passed the starting position.  The position
         // we stop on will be the first break position after the specified one.
-        int result = handlePrevious();
+        int result = cachedLastKnownBreak;
+        if (result >= offset || result <= BreakIterator.DONE) {
+            result = handlePrevious();
+        } else {
+            //it might be better to check if handlePrevious() give us closer
+            //safe value but handlePrevious() is slow too
+            //So, this has to be done carefully
+            text.setIndex(result);
+        }
         while (result != BreakIterator.DONE && result <= offset) {
             result = handleNext();
         }
+        cachedLastKnownBreak = result;
         return result;
     }
 
@@ -865,6 +886,8 @@
             text = new SafeCharIterator(newText);
         }
         text.first();
+
+        cachedLastKnownBreak = BreakIterator.DONE;
     }