Automatic sources dropoff on 2020-06-10 18:32:38.095721

The change is generated with prebuilt drop tool.

Change-Id: I24cbf6ba6db262a1ae1445db1427a08fee35b3b4
diff --git a/android/sax/Children.java b/android/sax/Children.java
new file mode 100644
index 0000000..7aa8dcf
--- /dev/null
+++ b/android/sax/Children.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed 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 android.sax;
+
+/**
+ * Contains element children. Using this class instead of HashMap results in
+ * measurably better performance.
+ */
+class Children {
+
+    Child[] children = new Child[16];
+
+    /**
+     * Looks up a child by name and creates a new one if necessary.
+     */
+    Element getOrCreate(Element parent, String uri, String localName) {
+        int hash = uri.hashCode() * 31 + localName.hashCode();
+        int index = hash & 15;
+
+        Child current = children[index];
+        if (current == null) {
+            // We have no children in this bucket yet.
+            current = new Child(parent, uri, localName, parent.depth + 1, hash);
+            children[index] = current;
+            return current;
+        } else {
+            // Search this bucket.
+            Child previous;
+            do {
+                if (current.hash == hash
+                        && current.uri.compareTo(uri) == 0
+                        && current.localName.compareTo(localName) == 0) {
+                    // We already have a child with that name.
+                    return current;
+                }
+
+                previous = current;
+                current = current.next;
+            } while (current != null);
+
+            // Add a new child to the bucket.
+            current = new Child(parent, uri, localName, parent.depth + 1, hash);
+            previous.next = current;
+            return current;         
+        }
+    }
+
+    /**
+     * Looks up a child by name.
+     */
+    Element get(String uri, String localName) {
+        int hash = uri.hashCode() * 31 + localName.hashCode();
+        int index = hash & 15;
+
+        Child current = children[index];
+        if (current == null) {
+            return null;
+        } else {
+            do {
+                if (current.hash == hash
+                        && current.uri.compareTo(uri) == 0
+                        && current.localName.compareTo(localName) == 0) {
+                    return current;
+                }
+                current = current.next;
+            } while (current != null);
+
+            return null;
+        }
+    }
+
+    static class Child extends Element {
+
+        final int hash;
+        Child next;
+
+        Child(Element parent, String uri, String localName, int depth,
+                int hash) {
+            super(parent, uri, localName, depth);
+            this.hash = hash;
+        }
+    }
+}