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 (unittest) 87 { 88 import dshould : be, equal, not, should; 89 import unit_threaded; 90 91 class Test 92 { 93 94 @Tags("DoubleKeyMap") 95 @("construction DoubleKeyMap") 96 unittest 97 { 98 auto t1 = new DoubleKeyMap!(int, int, int); 99 t1.put(7, 1, 12); 100 t1.put(7, 1, 13); 101 auto x = t1.get(7, 1); 102 x.get.should.equal(13); 103 x = t1.get(7, 2); 104 x.isNull.should.equal(true); 105 } 106 107 @Tags("DoubleKeyMap") 108 @("comparing DoubleKeyMaps") 109 unittest 110 { 111 auto t1 = new DoubleKeyMap!(int, int, int); 112 t1.put(7, 1, 13); 113 auto y = t1.get(7); 114 int[int] c; 115 c[1] = 13; 116 c.should.equal(y); 117 y = t1.get(6); 118 y.length.should.equal(0); 119 t1.put(7, 4, 71); 120 c[4] = 71; 121 y = t1.get(7); 122 c.should.equal(y); 123 124 auto v1 = t1.values(7); 125 v1.should.equal([71, 13]); 126 v1 = t1.values(0); 127 v1.should.equal([]); 128 129 auto kx = t1.keySet; 130 auto kk = [7]; 131 kk.should.equal(kx); 132 133 auto tx = t1.keySet(8); 134 tx.should.equal([]); 135 tx = t1.keySet(7); 136 tx.should.equal([4, 1]); 137 } 138 139 } 140 141 }