Bug 1116599 - Use a cache to create a GeckoMenu.findItem fast path r=rnewman
authorMark Finkle <mfinkle@mozilla.com>
Wed, 31 Dec 2014 14:32:44 -0500
changeset 221704 0d284cdc38f6a7031d811a12638f6d8f619e730a
parent 221703 d3c44062ebbb2606978acdf898b407dfbe9146ff
child 221705 e517f97929b49683fcc3804a9b9820597f33a075
push id10621
push usermfinkle@mozilla.com
push dateWed, 31 Dec 2014 19:32:59 +0000
treeherderfx-team@0d284cdc38f6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrnewman
bugs1116599
milestone37.0a1
Bug 1116599 - Use a cache to create a GeckoMenu.findItem fast path r=rnewman
mobile/android/base/menu/GeckoMenu.java
--- a/mobile/android/base/menu/GeckoMenu.java
+++ b/mobile/android/base/menu/GeckoMenu.java
@@ -10,16 +10,17 @@ import org.mozilla.gecko.util.ThreadUtil
 import org.mozilla.gecko.util.ThreadUtils.AssertBehavior;
 import org.mozilla.gecko.widget.GeckoActionProvider;
 
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.SubMenu;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
@@ -85,16 +86,19 @@ public class GeckoMenu extends ListView
         public void removeActionItem(View actionItem);
     }
 
     protected static final int NO_ID = 0;
 
     // List of all menu items.
     private final List<GeckoMenuItem> mItems;
 
+    // Quick lookup array used to make a fast path in findItem.
+    private final SparseArray<MenuItem> mItemsById;
+
     // Map of "always" action-items in action-bar and their views.
     private final Map<GeckoMenuItem, View> mPrimaryActionItems;
 
     // Map of "ifRoom" action-items in action-bar and their views.
     private final Map<GeckoMenuItem, View> mSecondaryActionItems;
 
     // Reference to a callback for menu events.
     private Callback mCallback;
@@ -129,16 +133,17 @@ public class GeckoMenu extends ListView
                                          LayoutParams.MATCH_PARENT));
 
         // Attach an adapter.
         mAdapter = new MenuItemsAdapter();
         setAdapter(mAdapter);
         setOnItemClickListener(this);
 
         mItems = new ArrayList<GeckoMenuItem>();
+        mItemsById = new SparseArray<MenuItem>();
         mPrimaryActionItems = new HashMap<GeckoMenuItem, View>();
         mSecondaryActionItems = new HashMap<GeckoMenuItem, View>();
 
         mPrimaryActionItemBar = (DefaultActionItemBar) LayoutInflater.from(context).inflate(R.layout.menu_action_bar, null);
         mSecondaryActionItemBar = (DefaultActionItemBar) LayoutInflater.from(context).inflate(R.layout.menu_secondary_action_bar, null);
     }
 
     private static void assertOnUiThread() {
@@ -357,25 +362,34 @@ public class GeckoMenu extends ListView
 
     private void showMenu(View viewForMenu) {
         if (mMenuPresenter != null)
             mMenuPresenter.showMenu(viewForMenu);
     }
 
     @Override
     public MenuItem findItem(int id) {
+        assertOnUiThread();
+        MenuItem quickItem = mItemsById.get(id);
+        if (quickItem != null) {
+            return quickItem;
+        }
+
         for (GeckoMenuItem menuItem : mItems) {
             if (menuItem.getItemId() == id) {
+                mItemsById.put(id, menuItem);
                 return menuItem;
             } else if (menuItem.hasSubMenu()) {
                 if (!menuItem.hasActionProvider()) {
                     SubMenu subMenu = menuItem.getSubMenu();
                     MenuItem item = subMenu.findItem(id);
-                    if (item != null)
+                    if (item != null) {
+                        mItemsById.put(id, item);
                         return item;
+                    }
                 }
             }
         }
         return null;
     }
 
     @Override
     public MenuItem getItem(int index) {
@@ -419,16 +433,19 @@ public class GeckoMenu extends ListView
 
     @Override
     public void removeItem(int id) {
         assertOnUiThread();
         GeckoMenuItem item = (GeckoMenuItem) findItem(id);
         if (item == null)
             return;
 
+        // Remove it from the cache.
+        mItemsById.remove(id);
+
         // Remove it from any sub-menu.
         for (GeckoMenuItem menuItem : mItems) {
             if (menuItem.hasSubMenu()) {
                 SubMenu subMenu = menuItem.getSubMenu();
                 if (subMenu != null && subMenu.findItem(id) != null) {
                     subMenu.removeItem(id);
                     return;
                 }
@@ -806,16 +823,17 @@ public class GeckoMenu extends ListView
 
         public void removeMenuItem(GeckoMenuItem menuItem) {
             // Remove it from the list.
             mItems.remove(menuItem);
             notifyDataSetChanged();
         }
 
         public void clear() {
+            mItemsById.clear();
             mItems.clear();
             notifyDataSetChanged();
         }
 
         public GeckoMenuItem getMenuItem(int id) {
             for (GeckoMenuItem item : mItems) {
                 if (item.getItemId() == id)
                     return item;