diff options
Diffstat (limited to 'sax/java/android/sax/Children.java')
-rw-r--r-- | sax/java/android/sax/Children.java | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/sax/java/android/sax/Children.java b/sax/java/android/sax/Children.java new file mode 100644 index 0000000..7aa8dcf --- /dev/null +++ b/sax/java/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; + } + } +} |