1 /* 2 * Copyright (c) 2012-2019 The ANTLR Project. All rights reserved. 3 * Use of this file is governed by the BSD 3-clause license that 4 * can be found in the LICENSE.txt file in the project root. 5 */ 6 7 module antlr.v4.runtime.misc.DoubleKeyMap; 8 9 import std.typecons; 10 11 /** 12 * Sometimes we need to map a key to a value but key is two pieces of data. 13 * This nested hash table saves creating a single key each time we access 14 * map; avoids mem creation. 15 */ 16 class DoubleKeyMap(K1, K2, V) 17 { 18 19 public V[K1][K2] data; 20 21 public V put(K1 k1, K2 k2, V v) 22 { 23 data[k1][k2] = v; 24 return v; 25 } 26 27 public Nullable!V get(K1 k1, K2 k2) 28 { 29 Nullable!V v; 30 if (k1 !in data || k2 !in data[k1]) 31 { 32 return v; // null 33 } 34 v = data[k1][k2]; 35 return v; 36 } 37 38 public V[K2] get(K1 k1) 39 { 40 if (k1 !in data) 41 { 42 V[K2] v; 43 return v; 44 } 45 return data[k1]; 46 } 47 48 /** 49 * Get all values associated with a primary key. 50 */ 51 public V[] values(K1 k1) 52 { 53 V[] va; 54 if (k1 !in data) 55 { 56 return va; // [] 57 } 58 V[K2] data2 = data[k1]; 59 return data2.values; 60 } 61 62 /** 63 * get all primary keys 64 */ 65 public K1[] keySet() 66 { 67 return data.keys; 68 } 69 70 /** 71 * Get all secondary keys associated with a primary key. 72 */ 73 public K2[] keySet(K1 k1) 74 { 75 if (k1 !in data) 76 { 77 K2[] v; 78 return v; 79 } 80 V[K2] data2 = data[k1]; 81 return data2.keys; 82 } 83 84 } 85 86 version (AntlrUnittest) 87 { 88 import dshould; 89 90 @("construction DoubleKeyMap") 91 unittest 92 { 93 auto t1 = new DoubleKeyMap!(int, int, int); 94 t1.put(7, 1, 12); 95 t1.put(7, 1, 13); 96 auto x = t1.get(7, 1); 97 x.get.should.equal(13); 98 x = t1.get(7, 2); 99 x.isNull.should.equal(true); 100 } 101 102 @("comparing DoubleKeyMaps") 103 unittest 104 { 105 auto t1 = new DoubleKeyMap!(int, int, int); 106 t1.put(7, 1, 13); 107 auto y = t1.get(7); 108 int[int] c; 109 c[1] = 13; 110 c.should.equal(y); 111 y = t1.get(6); 112 y.length.should.equal(0); 113 t1.put(7, 4, 71); 114 c[4] = 71; 115 y = t1.get(7); 116 c.should.equal(y); 117 118 auto v1 = t1.values(7); 119 v1.should.equal([71, 13]); 120 v1 = t1.values(0); 121 v1.should.equal([]); 122 123 auto kx = t1.keySet; 124 auto kk = [7]; 125 kk.should.equal(kx); 126 127 auto tx = t1.keySet(8); 128 tx.should.equal([]); 129 tx = t1.keySet(7); 130 tx.should.equal([4, 1]); 131 } 132 }