import { JavaMapEntry, cast_java_util_Map_Entry } from '../../../java/util/JavaMapEntry'; import { Comparable, cast_java_lang_Comparable } from '../../../java/lang/Comparable'; import { NavigableSet, cast_java_util_NavigableSet } from '../../../java/util/NavigableSet'; import { JavaSet, cast_java_util_Set } from '../../../java/util/JavaSet'; import { NavigableMap, cast_java_util_NavigableMap } from '../../../java/util/NavigableMap'; import { AVLMapIntervall, cast_de_nrw_schule_svws_core_adt_map_AVLMapIntervall } from '../../../core/adt/map/AVLMapIntervall'; import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString'; import { Comparator, cast_java_util_Comparator } from '../../../java/util/Comparator'; import { NullPointerException, cast_java_lang_NullPointerException } from '../../../java/lang/NullPointerException'; import { AVLMapNode, cast_de_nrw_schule_svws_core_adt_map_AVLMapNode } from '../../../core/adt/map/AVLMapNode'; import { ClassCastException, cast_java_lang_ClassCastException } from '../../../java/lang/ClassCastException'; import { SortedMap, cast_java_util_SortedMap } from '../../../java/util/SortedMap'; import { Collection, cast_java_util_Collection } from '../../../java/util/Collection'; import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject'; import { JavaMap, cast_java_util_Map } from '../../../java/util/JavaMap'; import { IllegalArgumentException, cast_java_lang_IllegalArgumentException } from '../../../java/lang/IllegalArgumentException'; import { NoSuchElementException, cast_java_util_NoSuchElementException } from '../../../java/util/NoSuchElementException'; import { AVLMapSubMap, cast_de_nrw_schule_svws_core_adt_map_AVLMapSubMap } from '../../../core/adt/map/AVLMapSubMap'; import { UnsupportedOperationException, cast_java_lang_UnsupportedOperationException } from '../../../java/lang/UnsupportedOperationException'; export class AVLMap extends JavaObject implements NavigableMap { private readonly _infinityMinus : K = AVLMapIntervall._INFINITY_MINUS as unknown as K; private readonly _infinityPlus : K = AVLMapIntervall._INFINITY_PLUS as unknown as K; private readonly _dummyValue : V = new Object() as unknown as V; private readonly _sub : AVLMapSubMap = new AVLMapSubMap(this, new AVLMapIntervall(this._infinityMinus, false, this._infinityPlus, false), true); private readonly _comparator : Comparator; private readonly _comparatorNatural : Comparator = { compare : (key1: K, key2: K) => { if ((key1 === null) || (key2 === null)) throw new NullPointerException() if (!((((key1 instanceof JavaObject) && (key1.isTranspiledInstanceOf('java.lang.Comparable')))) && (((key2 instanceof JavaObject) && (key2.isTranspiledInstanceOf('java.lang.Comparable')))))) throw new ClassCastException() let k1 : Comparable = cast_java_lang_Comparable(key1); return k1.compareTo(key2); } }; private _root : AVLMapNode | null = null; private _allowKeyAlone : boolean = false; /** * Erzeugt einen leere Map, welche bei den Schlüsselwerten die natürliche Ordnung des {@link Comparable} - * Interface nutzt. */ public constructor(); /** * Erstellt eine neue leere Map und nutzt dabei die angegeben Ordnung der Schlüssel. * * @param comparator Die Ordnung für die Schlüssel. */ public constructor(comparator : Comparator); /** * Erstellt eine neue Map mit den Daten aus der angegebenen Map und nutzt dabei die Ordnung dieser Map. * * @param map Die Map mit den Daten. */ public constructor(map : SortedMap); /** * Implementation for method overloads of 'constructor' */ public constructor(__param0? : Comparator | SortedMap) { super(); if ((typeof __param0 === "undefined")) { this._comparator = this._comparatorNatural; } else if (((typeof __param0 !== "undefined") && ((typeof __param0 !== 'undefined') && (__param0 instanceof Object) && (__param0 !== null) && ('compare' in __param0) && (typeof __param0.compare === 'function')) || (__param0 === null))) { let comparator : Comparator = cast_java_util_Comparator(__param0); this._comparator = comparator; } else if (((typeof __param0 !== "undefined") && ((__param0 instanceof JavaObject) && (__param0.isTranspiledInstanceOf('java.util.SortedMap'))) || (__param0 === null))) { let map : SortedMap = cast_java_util_SortedMap(__param0); this._comparator = cast_java_util_Comparator(map.comparator()); this._sub.putAll(map); } else throw new Error('invalid method overload'); } public toString() : String { return this._sub.toString(); } /** * Bewirkt, dass das Hinzufügen von Keys ohne Value durch {@link AVLMapSubKeySet} erlaubt ist. Die Keys werden * auf einen Dummy-Wert gemapped. * * @param b Falls TRUE, dürfen KEYs ohne VALUE hinzugefügt werden. */ public allowKeyAlone(b : boolean) : void { this._allowKeyAlone = b; } public equals(o : unknown) : boolean { return JavaObject.equalsTranspiler(this._sub, (o)); } public hashCode() : number { return JavaObject.getTranspilerHashCode(this._sub); } public comparator() : Comparator { return this._sub.comparator(); } public firstKey() : K { return this._sub.firstKey(); } public lastKey() : K { return this._sub.lastKey(); } public keySet() : JavaSet { return this._sub.keySet(); } public values() : Collection { return this._sub.values(); } public entrySet() : JavaSet> { return this._sub.entrySet(); } public size() : number { return this._sub.size(); } public isEmpty() : boolean { return this._sub.isEmpty(); } public containsKey(key : unknown) : boolean { return this._sub.containsKey(key); } public containsValue(value : unknown) : boolean { return this._sub.containsValue(value); } public get(key : unknown) : V | null { return this._sub.get(key); } public put(key : K, value : V) : V | null { return this._sub.put(key, value); } public remove(key : unknown) : V | null { return this._sub.remove(key); } public putAll(m : JavaMap) : void { this._sub.putAll(m); } public clear() : void { this._sub.clear(); } public lowerEntry(key : K) : JavaMapEntry | null { return this._sub.lowerEntry(key); } public lowerKey(key : K) : K | null { return this._sub.lowerKey(key); } public floorEntry(key : K) : JavaMapEntry | null { return this._sub.floorEntry(key); } public floorKey(key : K) : K | null { return this._sub.floorKey(key); } public ceilingEntry(key : K) : JavaMapEntry | null { return this._sub.ceilingEntry(key); } public ceilingKey(key : K) : K | null { return this._sub.ceilingKey(key); } public higherEntry(key : K) : JavaMapEntry | null { return this._sub.higherEntry(key); } public higherKey(key : K) : K | null { return this._sub.higherKey(key); } public firstEntry() : JavaMapEntry | null { return this._sub.firstEntry(); } public lastEntry() : JavaMapEntry | null { return this._sub.lastEntry(); } public pollFirstEntry() : JavaMapEntry | null { return this._sub.pollFirstEntry(); } public pollLastEntry() : JavaMapEntry | null { return this._sub.pollLastEntry(); } public descendingMap() : NavigableMap { return this._sub.descendingMap(); } public navigableKeySet() : NavigableSet { return this._sub.navigableKeySet(); } public descendingKeySet() : NavigableSet { return this._sub.descendingKeySet(); } public subMap(fromKey : K, fromInclusive : boolean, toKey : K, toInclusive : boolean) : NavigableMap; public subMap(fromKey : K, toKey : K) : SortedMap; /** * Implementation for method overloads of 'subMap' */ public subMap(__param0 : K, __param1 : K | boolean, __param2? : K, __param3? : boolean) : NavigableMap | SortedMap { if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean") && ((typeof __param2 !== "undefined") && (typeof __param2 !== "undefined")) && ((typeof __param3 !== "undefined") && typeof __param3 === "boolean")) { let fromKey : K = __param0 as unknown as K; let fromInclusive : boolean = __param1 as boolean; let toKey : K = __param2 as unknown as K; let toInclusive : boolean = __param3 as boolean; return this._sub.subMap(fromKey, fromInclusive, toKey, toInclusive); } else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && (typeof __param1 !== "undefined")) && (typeof __param2 === "undefined") && (typeof __param3 === "undefined")) { let fromKey : K = __param0 as unknown as K; let toKey : K = __param1 as unknown as K; return this._sub.subMap(fromKey, toKey); } else throw new Error('invalid method overload'); } public headMap(toKey : K, inclusive : boolean) : NavigableMap; public headMap(toKey : K) : SortedMap; /** * Implementation for method overloads of 'headMap' */ public headMap(__param0 : K, __param1? : boolean) : NavigableMap | SortedMap { if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) { let toKey : K = __param0 as unknown as K; let inclusive : boolean = __param1 as boolean; return this._sub.headMap(toKey, inclusive); } else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) { let toKey : K = __param0 as unknown as K; return this._sub.headMap(toKey); } else throw new Error('invalid method overload'); } public tailMap(fromKey : K, inclusive : boolean) : NavigableMap; public tailMap(fromKey : K) : SortedMap; /** * Implementation for method overloads of 'tailMap' */ public tailMap(__param0 : K, __param1? : boolean) : NavigableMap | SortedMap { if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) { let fromKey : K = __param0 as unknown as K; let inclusive : boolean = __param1 as boolean; return this._sub.tailMap(fromKey, inclusive); } else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) { let fromKey : K = __param0 as unknown as K; return this._sub.tailMap(fromKey); } else throw new Error('invalid method overload'); } bcAddEntryReturnBool(e : JavaMapEntry, iv : AVLMapIntervall) : boolean { let old : V | null = this.bcAddEntryReturnOldValueOrNull(e.getKey(), e.getValue(), iv); return !this._valEquals(old, e.getValue()); } bcAddAllEntries(c : Collection>, iv : AVLMapIntervall) : boolean { let changed : boolean = false; for (let entry of c) changed = changed || this.bcAddEntryReturnBool(entry, iv); return changed; } bcAddEntryReturnOldValueOrNull(key : K, value : V, iv : AVLMapIntervall) : V | null { if (key === null) throw new NullPointerException("TreeMap erlaubt keine NULL keys.") if (this._isOutOfRange(key, iv)) throw new IllegalArgumentException("Der Schlüsselwert liegt nicht im gültigen Bereich.") if (this._root === null) { this._root = new AVLMapNode(key, value); return null; } let node : AVLMapNode | null = this._nodeGetOrNull(key, iv); let old : V | null = (node === null) ? null : node._val; this._root = this._nodePutRecursive(this._root, key, value); return old; } bcAddValue(e : V, iv : AVLMapIntervall) : boolean { throw new UnsupportedOperationException() } bcAddKey(e : K, iv : AVLMapIntervall) : boolean { if (this._allowKeyAlone === false) throw new UnsupportedOperationException() if (this.bcContainsKey(e, iv)) return false; this.bcAddEntryReturnOldValueOrNull(e, this._dummyValue, iv); return true; } bcAddAllKeys(c : Collection, iv : AVLMapIntervall) : boolean { let changed : boolean = false; for (let key of c) changed = changed || this.bcAddKey(key, iv); return changed; } bcAddAllEntriesOfMap(map : JavaMap, iv : AVLMapIntervall) : void { for (let entry of map.entrySet()) this.bcAddEntryReturnOldValueOrNull(entry.getKey(), entry.getValue(), iv); } bcContainsKey(objKey : unknown, iv : AVLMapIntervall) : boolean { return this._nodeGetOrNull(objKey as unknown as K, iv) !== null; } bcContainsAllKeys(c : Collection, iv : AVLMapIntervall) : boolean { for (let key of c) if (!this.bcContainsKey(key, iv)) return false; return true; } bcContainsValue(objValue : unknown, iv : AVLMapIntervall) : boolean { let value : V = objValue as unknown as V; let n1 : AVLMapNode | null = this._nodeFirstOrNull(iv); if (n1 === null) return false; let n2 : AVLMapNode | null = this._nodeLastOrNull(iv); if (n2 === null) return false; while (n1 as unknown !== n2 as unknown) { if (n1 === null) throw new NullPointerException() if (this._valEquals(n1._val, value)) return true; n1 = n1._next; } return this._valEquals(n2._val, value); } bcContainsAllValues(col : Collection, iv : AVLMapIntervall) : boolean { for (let val of col) if (!this.bcContainsValue(val, iv)) return false; return true; } bcContainsEntry(o : unknown, iv : AVLMapIntervall) : boolean { if (((o instanceof JavaObject) && (o.isTranspiledInstanceOf('java.util.Map.Entry'))) === false) return false; let e : JavaMapEntry = cast_java_util_Map_Entry(o); let node : AVLMapNode | null = this._nodeGetOrNull(e.getKey(), iv); return (node === null) ? false : this._valEquals(node._val, e.getValue()); } bcContainsAllEntries(c : Collection, iv : AVLMapIntervall) : boolean { for (let entry of c) if (!this.bcContainsEntry(entry, iv)) return false; return true; } bcRemoveKeyReturnBool(o : unknown, iv : AVLMapIntervall) : boolean { if (!this.bcContainsKey(o, iv)) return false; this.bcRemoveKeyReturnOldValueOrNull(o, iv); return true; } bcRemoveAllKeys(c : Collection, iv : AVLMapIntervall) : boolean { let changed : boolean = false; for (let obj of c) changed = changed || this.bcRemoveKeyReturnBool(obj, iv); return changed; } bcRemoveEntry(o : unknown, iv : AVLMapIntervall) : boolean { if (!this.bcContainsEntry(o, iv)) return false; if (((o instanceof JavaObject) && (o.isTranspiledInstanceOf('java.util.Map.Entry'))) === false) return false; if (this._root === null) throw new NullPointerException() let e : JavaMapEntry = cast_java_util_Map_Entry(o); this._root = this._nodeRemoveKeyRecursive(this._root, e.getKey()); return true; } bcRemoveAllEntries(c : Collection, iv : AVLMapIntervall) : boolean { let removedAny : boolean = false; for (let entry of c) removedAny = removedAny || this.bcRemoveEntry(entry, iv); return removedAny; } bcRemoveKeyReturnOldValueOrNull(obj : unknown, iv : AVLMapIntervall) : V | null { if (obj === null) throw new NullPointerException("TreeMap unterstützt keine NULL-Schlüssel.") let key : K = obj as unknown as K; let old : AVLMapNode | null = this._nodeGetOrNull(key, iv); if (old === null) return null; if (this._root === null) throw new NullPointerException() this._root = this._nodeRemoveKeyRecursive(this._root, key); return old._val; } bcPollFirstEntryOrNull(iv : AVLMapIntervall) : JavaMapEntry | null { let node : AVLMapNode | null = this._nodeFirstOrNull(iv); if (node === null) return node; if (this._root === null) throw new NullPointerException() this._root = this._nodeRemoveKeyRecursive(this._root, node._key); return node; } bcPollFirstKeyOrNull(iv : AVLMapIntervall) : K | null { let node : AVLMapNode | null = this._nodeFirstOrNull(iv); if (node === null) return null; if (this._root === null) throw new NullPointerException() this._root = this._nodeRemoveKeyRecursive(this._root, node._key); return node._key; } bcPollLastEntryOrNull(iv : AVLMapIntervall) : JavaMapEntry | null { let node : AVLMapNode | null = this._nodeLastOrNull(iv); if (node === null) return null; if (this._root === null) throw new NullPointerException() this._root = this._nodeRemoveKeyRecursive(this._root, node._key); return node; } bcPollLastKeyOrNull(iv : AVLMapIntervall) : K | null { let node : AVLMapNode | null = this._nodeLastOrNull(iv); if (node === null) return null; if (this._root === null) throw new NullPointerException() this._root = this._nodeRemoveKeyRecursive(this._root, node._key); return node._key; } bcIsEmpty(iv : AVLMapIntervall) : boolean { return this._nodeFirstOrNull(iv) === null; } bcGetComparator(iv : AVLMapIntervall) : Comparator { return this._comparator; } bcGetFirstKeyOrException(iv : AVLMapIntervall) : K { return this._keyOrExeption(this._nodeFirstOrNull(iv)); } bcGetFirstEntryOrNull(iv : AVLMapIntervall) : AVLMapNode | null { return this._nodeFirstOrNull(iv); } bcGetLastKeyOrException(iv : AVLMapIntervall) : K { return this._keyOrExeption(this._nodeLastOrNull(iv)); } bcGetLastEntryOrNull(iv : AVLMapIntervall) : AVLMapNode | null { return this._nodeLastOrNull(iv); } bcGetNextEntryOrNull(current : AVLMapNode, iv : AVLMapIntervall) : AVLMapNode | null { return this._nodeNextOrNull(current, iv); } bcGetPrevEntryOrNull(current : AVLMapNode, iv : AVLMapIntervall) : AVLMapNode | null { return this._nodePrevOrNull(current, iv); } bcGetSize(iv : AVLMapIntervall) : number { let n1 : AVLMapNode | null = this._nodeFirstOrNull(iv); if (n1 === null) return 0; let n2 : AVLMapNode | null = this._nodeLastOrNull(iv); if (n2 === null) return 0; return this._nodeIndexOf(n2._key) - this._nodeIndexOf(n1._key) + 1; } bcGetValueOfKeyOrNull(objKey : unknown, iv : AVLMapIntervall) : V | null { let key : K = objKey as unknown as K; let node : AVLMapNode | null = this._nodeGetOrNull(key, iv); return (node === null) ? null : node._val; } bcGetLowerEntryOrNull(key : K, iv : AVLMapIntervall) : AVLMapNode | null { return this._nodeLowerOrNull(key, iv); } bcGetLowerKeyOrNull(key : K, iv : AVLMapIntervall) : K | null { return this._keyOrNull(this._nodeLowerOrNull(key, iv)); } bcGetFloorEntryOrNull(key : K, iv : AVLMapIntervall) : AVLMapNode | null { return this._nodeFloorOrNull(key, iv); } bcGetFloorKeyOrNull(key : K, iv : AVLMapIntervall) : K | null { return this._keyOrNull(this._nodeFloorOrNull(key, iv)); } bcGetCeilingEntryOrNull(key : K, iv : AVLMapIntervall) : AVLMapNode | null { return this._nodeCeilingOrNull(key, iv); } bcGetCeilingKeyOrNull(key : K, iv : AVLMapIntervall) : K | null { return this._keyOrNull(this._nodeCeilingOrNull(key, iv)); } bcGetHigherEntryOrNull(key : K, iv : AVLMapIntervall) : AVLMapNode | null { return this._nodeHigherOrNull(key, iv); } bcGetHigherKeyOrNull(key : K, iv : AVLMapIntervall) : K | null { return this._keyOrNull(this._nodeHigherOrNull(key, iv)); } bcCheckOutOfIntervall(key : K, inc : boolean, iv : AVLMapIntervall) : boolean { if ((key === this._infinityMinus) || (key === this._infinityPlus)) return false; let cmpF : number = this._compare(key, iv.from); if (cmpF < 0) return true; if ((cmpF === 0) && (!iv.fromInc) && (inc)) return true; let cmpT : number = this._compare(key, iv.to); if (cmpT > 0) return true; if ((cmpT === 0) && (!iv.toInc) && (inc)) return true; return false; } private _keyOrNull(node : AVLMapNode | null) : K | null { return (node === null) ? null : node._key; } private _valEquals(v1 : V | null, v2 : V | null) : boolean { return (v1 === null) ? v2 === null : JavaObject.equalsTranspiler(v1, (v2)); } private _keyOrExeption(node : AVLMapNode | null) : K { if (node === null) throw new NoSuchElementException() return node._key; } private _compare(key1 : K, key2 : K) : number { if ((key1 === this._infinityMinus) || (key2 === this._infinityPlus)) return -1; if ((key1 === this._infinityPlus) || (key2 === this._infinityMinus)) return +1; return this._comparator.compare(key1, key2); } private _isOutOfRange(key : K, iv : AVLMapIntervall) : boolean { let cmpKeyFrom : number = this._compare(key, iv.from); if ((cmpKeyFrom < 0) || (cmpKeyFrom === 0) && (!iv.fromInc)) return true; let cmpKeyTo : number = this._compare(key, iv.to); if ((cmpKeyTo > 0) || (cmpKeyTo === 0) && (!iv.toInc)) return true; return false; } private _nodeFirstOrNull(iv : AVLMapIntervall) : AVLMapNode | null { return iv.fromInc ? this._nodeCeilingOrNull(iv.from, iv) : this._nodeHigherOrNull(iv.from, iv); } private _nodeLastOrNull(iv : AVLMapIntervall) : AVLMapNode | null { return iv.toInc ? this._nodeFloorOrNull(iv.to, iv) : this._nodeLowerOrNull(iv.to, iv); } private _nodeCeilingOrNull(key : K, iv : AVLMapIntervall) : AVLMapNode | null { let node : AVLMapNode | null = this._nodeDeepestOrNull(key, iv); if (node === null) return null; let cmpNodeKey : number = this._compare(node._key, key); return cmpNodeKey >= 0 ? node : this._nodeNextOrNull(node, iv); } private _nodeHigherOrNull(key : K, iv : AVLMapIntervall) : AVLMapNode | null { let node : AVLMapNode | null = this._nodeDeepestOrNull(key, iv); if (node === null) return null; let cmpNodeKey : number = this._compare(node._key, key); return cmpNodeKey > 0 ? node : this._nodeNextOrNull(node, iv); } private _nodeFloorOrNull(key : K, iv : AVLMapIntervall) : AVLMapNode | null { let node : AVLMapNode | null = this._nodeDeepestOrNull(key, iv); if (node === null) return null; let cmpNodeKey : number = this._compare(node._key, key); return cmpNodeKey <= 0 ? node : this._nodePrevOrNull(node, iv); } private _nodeLowerOrNull(key : K, iv : AVLMapIntervall) : AVLMapNode | null { let node : AVLMapNode | null = this._nodeDeepestOrNull(key, iv); if (node === null) return null; let cmpNodeKey : number = this._compare(node._key, key); return cmpNodeKey < 0 ? node : this._nodePrevOrNull(node, iv); } private _nodeNextOrNull(node : AVLMapNode, iv : AVLMapIntervall) : AVLMapNode | null { let next : AVLMapNode | null = node._next; return (next === null) ? null : this._isOutOfRange(next._key, iv) ? null : next; } private _nodePrevOrNull(node : AVLMapNode, iv : AVLMapIntervall) : AVLMapNode | null { let prev : AVLMapNode | null = node._prev; return (prev === null) ? null : this._isOutOfRange(prev._key, iv) ? null : prev; } private _nodeGetOrNull(key : K, iv : AVLMapIntervall) : AVLMapNode | null { let node : AVLMapNode | null = this._nodeDeepestOrNull(key, iv); if (node === null) return null; return this._compare(key, node._key) === 0 ? node : null; } private _nodeIndexOf(key : K) : number { let current : AVLMapNode | null = this._root; let index : number = 0; while (true) { if (current === null) throw new NullPointerException() let cmp : number = this._compare(key, current._key); if (cmp < 0) { current = current._childL; continue; } let left : AVLMapNode | null = current._childL; let sizeL : number = (left === null) ? 0 : left._size; if (cmp > 0) { index += sizeL + 1; current = current._childR; continue; } return index + sizeL; } } private _nodeDeepestOrNull(key : K, iv : AVLMapIntervall) : AVLMapNode | null { let current : AVLMapNode | null = this._root; let last : AVLMapNode | null = null; while (current !== null) { let cmpToKey : number = this._compare(iv.to, current._key); if ((cmpToKey < 0) || (cmpToKey === 0) && (!iv.toInc)) { current = current._childL; continue; } let cmpFromKey : number = this._compare(iv.from, current._key); if ((cmpFromKey > 0) || (cmpFromKey === 0) && (!iv.fromInc)) { current = current._childR; continue; } last = current; let cmp : number = this._compare(key, current._key); if (cmp < 0) { current = current._childL; continue; } if (cmp > 0) { current = current._childR; continue; } return current; } return last; } private _nodePutRecursive(current : AVLMapNode, key : K, value : V) : AVLMapNode { let cmp : number = this._compare(key, current._key); if (cmp === 0) { current._val = value; return current; } if (cmp < 0) current._childL = (current._childL === null) ? this._nodeCreateLeaf(current._prev, current, key, value) : this._nodePutRecursive(current._childL, key, value); else current._childR = (current._childR === null) ? this._nodeCreateLeaf(current, current._next, key, value) : this._nodePutRecursive(current._childR, key, value); return this._nodeRevalidate(current); } private _nodeCreateLeaf(prev : AVLMapNode | null, next : AVLMapNode | null, key : K, value : V) : AVLMapNode { let child : AVLMapNode | null = new AVLMapNode(key, value); if (prev !== null) { prev._next = child; child._prev = prev; } if (next !== null) { next._prev = child; child._next = next; } return child; } private _nodeRemoveKeyRecursive(current : AVLMapNode, key : K) : AVLMapNode | null { let cmp : number = this._compare(key, current._key); if (cmp < 0) { if (current._childL === null) throw new NullPointerException() current._childL = this._nodeRemoveKeyRecursive(current._childL, key); return this._nodeRevalidate(current); } if (cmp > 0) { if (current._childR === null) throw new NullPointerException() current._childR = this._nodeRemoveKeyRecursive(current._childR, key); return this._nodeRevalidate(current); } if (current._childL === null) { this._nodeRemovePrevNext(current); return current._childR; } if (current._childR === null) { this._nodeRemovePrevNext(current); return current._childL; } let next : AVLMapNode | null = current._next; if (next === null) throw new NullPointerException() current._childR = this._nodeRemoveKeyRecursive(current._childR, next._key); return this._nodeRevalidate(this._nodeReplaceReferencesFromAwithB(next, current)); } private _nodeReplaceReferencesFromAwithB(a : AVLMapNode, b : AVLMapNode) : AVLMapNode { a._childL = b._childL; a._childR = b._childR; let p : AVLMapNode | null = b._prev; let n : AVLMapNode | null = b._next; a._prev = p; a._next = n; if (p !== null) p._next = a; if (n !== null) n._prev = a; return a; } private _nodeRemovePrevNext(current : AVLMapNode) : void { let nodeP : AVLMapNode | null = current._prev; let nodeN : AVLMapNode | null = current._next; if (nodeP !== null) nodeP._next = nodeN; if (nodeN !== null) nodeN._prev = nodeP; } /** * Aktualisiert {@code node} und liefert, wenn es zur Rotation kommt, eine neue Sub-Wurzel. * * @param node Der Knoten, der revalidiert werden soll. * * @return node, oder die neue Sub-Wurzel, wenn es zur Rotation kam. */ private _nodeRevalidate(node : AVLMapNode) : AVLMapNode { let heightBalance : number = this._nodeGetHeightBalance(node); if (heightBalance > +1) { if (node._childR === null) throw new NullPointerException() if (this._nodeGetHeightBalance(node._childR) < 0) node._childR = this._nodeRotateRight(node._childR); return this._nodeRotateLeft(node); } if (heightBalance < -1) { if (node._childL === null) throw new NullPointerException() if (this._nodeGetHeightBalance(node._childL) > 0) node._childL = this._nodeRotateLeft(node._childL); return this._nodeRotateRight(node); } this._nodeRevalidateHeightAndSize(node); return node; } private _nodeRotateLeft(nodeM : AVLMapNode) : AVLMapNode { if (nodeM._childR === null) throw new NullPointerException() let nodeR : AVLMapNode = nodeM._childR; nodeM._childR = nodeR._childL; nodeR._childL = nodeM; this._nodeRevalidateHeightAndSize(nodeM); this._nodeRevalidateHeightAndSize(nodeR); return nodeR; } private _nodeRotateRight(nodeM : AVLMapNode) : AVLMapNode { if (nodeM._childL === null) throw new NullPointerException() let nodeL : AVLMapNode = nodeM._childL; nodeM._childL = nodeL._childR; nodeL._childR = nodeM; this._nodeRevalidateHeightAndSize(nodeM); this._nodeRevalidateHeightAndSize(nodeL); return nodeL; } private _nodeRevalidateHeightAndSize(node : AVLMapNode) : void { let sizeL : number = (node._childL === null) ? 0 : node._childL._size; let sizeR : number = (node._childR === null) ? 0 : node._childR._size; node._size = sizeL + sizeR + 1; let heightL : number = (node._childL === null) ? 0 : node._childL._height; let heightR : number = (node._childR === null) ? 0 : node._childR._height; node._height = Math.max(heightL, heightR) + 1; } private _nodeGetHeightBalance(node : AVLMapNode) : number { let heightL : number = (node._childL === null) ? 0 : node._childL._height; let heightR : number = (node._childR === null) ? 0 : node._childR._height; return heightR - heightL; } isTranspiledInstanceOf(name : string): boolean { return ['java.util.Map', 'de.nrw.schule.svws.core.adt.map.AVLMap', 'java.util.NavigableMap', 'java.util.SortedMap'].includes(name); } } export function cast_de_nrw_schule_svws_core_adt_map_AVLMap(obj : unknown) : AVLMap { return obj as AVLMap; }