def __init__(self, lookup_map, referring_node): super(_LookupRelation, self).__init__(referring_node.table_id, lookup_map.table_id) self._lookup_map = lookup_map self._referring_node = referring_node # Maps referring rows to keys, where multiple rows may map to the same key AND one row may # map to multiple keys (if a formula does multiple lookup calls). self._row_key_map = twowaymap.TwoWayMap(left=set, right=set)
def test_strict_list(self): tmap = twowaymap.TwoWayMap(left="strict", right=list) self.assertFalse(tmap) tmap.insert(1, "a") self.assertTrue(tmap) self.assertTwoWayMap(tmap, {1: ["a"]}, {"a": 1}) tmap.insert(1, "a") # should be a no-op, since this pair already exists tmap.insert(1, "b") with self.assertRaises(ValueError): tmap.insert(2, "a") self.assertTwoWayMap(tmap, {1: ["a", "b"]}, {"a": 1, "b": 1}) tmap.insert(1, "b") with self.assertRaises(ValueError): tmap.insert(2, "b") tmap.insert(2, "c") self.assertTwoWayMap(tmap, { 1: ["a", "b"], 2: ["c"] }, { "a": 1, "b": 1, "c": 2 }) tmap.remove(1, "b") self.assertTwoWayMap(tmap, {1: ["a"], 2: ["c"]}, {"a": 1, "c": 2}) tmap.remove(2, "b") self.assertTwoWayMap(tmap, {1: ["a"], 2: ["c"]}, {"a": 1, "c": 2}) tmap.insert(1, "b") with self.assertRaises(ValueError): tmap.insert(2, "b") self.assertTwoWayMap(tmap, { 1: ["a", "b"], 2: ["c"] }, { "a": 1, "b": 1, "c": 2 }) tmap.remove_left(1) self.assertTwoWayMap(tmap, {2: ["c"]}, {"c": 2}) tmap.insert(1, "a") tmap.insert(2, "b") tmap.remove_right("b") self.assertTwoWayMap(tmap, {1: ["a"], 2: ["c"]}, {"a": 1, "c": 2}) self.assertTrue(tmap) tmap.clear() self.assertTwoWayMap(tmap, {}, {}) self.assertFalse(tmap)
def test_strict_single(self): tmap = twowaymap.TwoWayMap(left="strict", right="single") tmap.insert(1, "a") tmap.insert(2, "b") tmap.insert(2, "c") self.assertTwoWayMap(tmap, {1: "a", 2: "c"}, {"a": 1, "c": 2}) with self.assertRaises(ValueError): tmap.insert(2, "a") tmap.insert(2, "c") # This pair already exists, so not an error. self.assertTwoWayMap(tmap, {1: "a", 2: "c"}, {"a": 1, "c": 2})
def test_nonhashable(self): # Test that we don't get into an inconsistent state if we attempt to use a non-hashable value. tmap = twowaymap.TwoWayMap(left=list, right=list) tmap.insert(1, "a") self.assertTwoWayMap(tmap, {1: ["a"]}, {"a": [1]}) with self.assertRaises(TypeError): tmap.insert(1, {}) with self.assertRaises(TypeError): tmap.insert({}, "a") self.assertTwoWayMap(tmap, {1: ["a"]}, {"a": [1]})
def test_set_list(self): tmap = twowaymap.TwoWayMap(left=set, right=list) self.assertFalse(tmap) tmap.insert(1, "a") self.assertTrue(tmap) self.assertTwoWayMap(tmap, {1: ["a"]}, {"a": {1}}) tmap.insert(1, "a") # should be a no-op, since this pair already exists tmap.insert(1, "b") tmap.insert(2, "a") self.assertTwoWayMap(tmap, { 1: ["a", "b"], 2: ["a"] }, { "a": {1, 2}, "b": {1} }) tmap.insert(1, "b") tmap.insert(2, "b") self.assertTwoWayMap(tmap, { 1: ["a", "b"], 2: ["a", "b"] }, { "a": {1, 2}, "b": {1, 2} }) tmap.remove(1, "b") tmap.remove(2, "b") self.assertTwoWayMap(tmap, {1: ["a"], 2: ["a"]}, {"a": {1, 2}}) tmap.insert(1, "b") tmap.insert(2, "b") tmap.remove_left(1) self.assertTwoWayMap(tmap, {2: ["a", "b"]}, {"a": {2}, "b": {2}}) tmap.insert(1, "a") tmap.insert(2, "b") tmap.remove_right("b") self.assertTwoWayMap(tmap, {1: ["a"], 2: ["a"]}, {"a": {1, 2}}) self.assertTrue(tmap) tmap.clear() self.assertTwoWayMap(tmap, {}, {}) self.assertFalse(tmap)
def __init__(self, table, col_id, col_ids_tuple): # Note that self._recalc_rec_method is passed in as the formula's "method". col_info = column.ColInfo(usertypes.Any(), is_formula=True, method=self._recalc_rec_method) super(LookupMapColumn, self).__init__(table, col_id, col_info) self._col_ids_tuple = col_ids_tuple self._engine = table._engine # Two-way map between rowIds of the target table (on the left) and key tuples (on the right). # Multiple rows can map to the same key. The map is populated by engine's _recompute when this # node is brought up-to-date. self._row_key_map = twowaymap.TwoWayMap(left=set, right="single") self._engine.invalidate_column(self) # Map of referring Node to _LookupRelation. Different tables may do lookups using this # LookupMapColumn, and that creates a dependency from other Nodes to us, with a relation # between referring rows and the lookup keys. This map stores these relations. self._lookup_relations = {}
def _make_row_key_map(self): return twowaymap.TwoWayMap(left=set, right=set)