}
int size() {
- return next == null ? 1 : next.size() + 1;
+ int sz = 1;
+ for (ListMap<?, ?> wlk = next; wlk != null; wlk = wlk.next) {
+ sz++;
+ }
+ return sz;
}
Option<V> get(final K key) {
if (key.equals(k)) {
return Option.makeOption(v);
}
- return next == null ? Option.makeOption() : next.get(key);
+
+ // We do not perform recursion on purpose here, so we do not run out of stack if the key hashing fails.
+ for (ListMap<K, V> m = next; m != null; m = m.next) {
+ if (key.equals(m.k)) {
+ return Option.makeOption(m.v);
+ }
+ }
+
+ return Option.makeOption();
}
ListMap<K,V> add(final K key, final V value) {
}
private boolean contains(final K key) {
- if (key.equals(this.k)) {
+ if (key.equals(k)) {
return true;
}
- return next != null && next.contains(key);
+ // We do not perform recursion on purpose here, so we do not run out of stack if the key hashing fails.
+ for (ListMap<K, V> m = next; m != null; m = m.next) {
+ if (key.equals(m.k)) {
+ return true;
+ }
+ }
+
+ return false;
}
private ListMap<K, V> remove0(final K key) {
--- /dev/null
+/*
+ * (C) Copyright 2016 Pantheon Technologies, s.r.o. and others.
+ *
+ * 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 org.opendaylight.yangtools.triemap;
+
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+
+public class ListMapTest {
+
+ /**
+ * Test if Listmap.get() does not cause stack overflow.
+ */
+ @Test
+ public void testGetOverflow() {
+ ListMap<Integer, Boolean> map = ListMap.map(1, Boolean.TRUE, 2, Boolean.TRUE);
+
+ // 30K seems to be enough to trigger the problem locally
+ for (int i = 3; i < 30000; ++i) {
+ map = map.add(i, Boolean.TRUE);
+ }
+
+ final Option<Boolean> ret = map.get(0);
+ assertFalse(ret.nonEmpty());
+ }
+
+}