All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.saxon.expr.sort.CustomMap Maven / Gradle / Ivy

There is a newer version: 12.5
Show newest version
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2018-2022 Saxonica Limited
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package net.sf.saxon.expr.sort;

import net.sf.saxon.transpile.CSharpTypeBounds;
import net.sf.saxon.z.IntHashMap;

import java.util.ArrayList;
import java.util.List;

/**
 * A map implementation using a custom equality matcher, to avoid having to wrap
 * each entry in a wrapper object to achieve customised equality testing.
 *
 * 

Note: this doesn't implement {@code Map} to save the effort of implementing * methods like size() and iterator() that aren't required for our use cases. These * methods could easily be added without changing the basic design. *

*/ @CSharpTypeBounds(bounds = {"V:class"}) public class CustomMap { private final IntHashMap> buckets; private final EqualityMatcher equalityMatcher; public CustomMap(EqualityMatcher matcher) { buckets = new IntHashMap<>(); equalityMatcher = matcher; } /** * Add an entry to the map * @param key the new key * @param value the value to be added. * @return the previous value for the key if there was one, or null otherwise */ public V put(K key, V value) { int h = equalityMatcher.hash(key); CustomMapEntryChain bucket = buckets.get(h); if (bucket == null) { CustomMapEntryChain entry = new CustomMapEntryChain<>(key, value); buckets.put(h, entry); return null; } else { while (true) { if (equalityMatcher.equal(bucket.key, key)) { V existing = bucket.value; bucket.value = value; return existing; } else if (bucket.next == null) { @SuppressWarnings("UnnecessaryLocalVariable") CustomMapEntryChain entry = new CustomMapEntryChain<>(key, value); bucket.next = entry; return null; } else { bucket = bucket.next; } } } } /** * Get the value associated with a given key, or null if absemt * @param key the new key * @return the value for the key if there is one, or null otherwise */ public V get(K key) { int h = equalityMatcher.hash(key); CustomMapEntryChain bucket = buckets.get(h); if (bucket == null) { return null; } else { while (true) { if (equalityMatcher.equal(bucket.key, key)) { return bucket.value; } else if (bucket.next == null) { return null; } else { bucket = bucket.next; } } } } /** * Ask if a key exists in the set of keys * @param key the requested key * @return true if it exists */ public boolean containsKey(K key) { int h = equalityMatcher.hash(key); CustomMapEntryChain bucket = buckets.get(h); if (bucket == null) { return false; } else { while (true) { if (equalityMatcher.equal(bucket.key, key)) { return true; } else if (bucket.next == null) { return false; } else { bucket = bucket.next; } } } } /** * List all the keys. * @return a list of all the keys */ public List keys() { List result = new ArrayList<>(); for (CustomMapEntryChain entry : buckets.valueSet()) { CustomMapEntryChain e = entry; do { result.add(e.key); e = e.next; } while (e != null); } return result; } /** * List all the values. * @return a list of all the values */ public List values() { List result = new ArrayList<>(); for (CustomMapEntryChain entry : buckets.valueSet()) { CustomMapEntryChain e = entry; do { result.add(e.value); e = e.next; } while (e != null); } return result; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy