001/* 002 * Copyright (c) 2015-2020, Oracle and/or its affiliates. All rights reserved. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.tribuo.util.infotheory.impl; 018 019import java.io.Serializable; 020import java.util.Objects; 021import java.util.logging.Logger; 022 023/** 024 * A triple of things. The inner pairs are cached, as is the hashcode. 025 * <p> 026 * The cache is calculated on construction, and the objects inside the triple are thus expected to be immutable. 027 * If they aren't then the behaviour is undefined (and you shouldn't use this class). 028 * @param <T1> The type of the first object. 029 * @param <T2> The type of the second object. 030 * @param <T3> The type of the third object. 031 */ 032public class CachedTriple<T1, T2, T3> implements Serializable { 033 private static final long serialVersionUID = 1L; 034 035 private static final Logger logger = Logger.getLogger(CachedTriple.class.getName()); 036 037 private final CachedPair<T1,T2> ab; 038 private final CachedPair<T1,T3> ac; 039 private final CachedPair<T2,T3> bc; 040 041 protected final T1 a; 042 protected final T2 b; 043 protected final T3 c; 044 045 private final int cachedHash; 046 047 public CachedTriple(T1 a, T2 b, T3 c) { 048 this.a = a; 049 this.b = b; 050 this.c = c; 051 this.ab = new CachedPair<>(a,b); 052 this.ac = new CachedPair<>(a,c); 053 this.bc = new CachedPair<>(b,c); 054 this.cachedHash = calculateHashCode(); 055 } 056 057 public T1 getA() { 058 return a; 059 } 060 061 public T2 getB() { 062 return b; 063 } 064 065 public T3 getC() { 066 return c; 067 } 068 069 public CachedPair<T1,T2> getAB() { 070 return ab; 071 } 072 073 public CachedPair<T1,T3> getAC() { 074 return ac; 075 } 076 077 public CachedPair<T2,T3> getBC() { 078 return bc; 079 } 080 081 /** 082 * Used to mix the integers in hashcode. 083 * Returns the 32 high bits of Stafford variant 4 mix64 function as int. 084 */ 085 private static int mix32(long z) { 086 z *= 0x62a9d9ed799705f5L; 087 return (int)(((z ^ (z >>> 28)) * 0xcb24d0a5c88c35b3L) >>> 32); 088 } 089 090 @Override 091 public int hashCode() { 092 return cachedHash; 093 } 094 095 /** 096 * Overridden hashcode. Checks to see if the types are ints or longs, and 097 * runs them through the mixing function if 098 * they are. Then XORs the two hashcodes together. 099 * @return A 32-bit integer. 100 */ 101 public int calculateHashCode() { 102 int aCode, bCode, cCode; 103 104 if (a instanceof Integer) { 105 aCode = mix32((Integer) a); 106 } else if (a instanceof Long) { 107 aCode = mix32((Long) a); 108 } else { 109 aCode = a.hashCode(); 110 } 111 112 if (b instanceof Integer) { 113 bCode = mix32((Integer) b); 114 } else if (b instanceof Long) { 115 bCode = mix32((Long) b); 116 } else { 117 bCode = b.hashCode(); 118 } 119 120 if (c instanceof Integer) { 121 cCode = mix32((Integer) c); 122 } else if (c instanceof Long) { 123 cCode = mix32((Long) c); 124 } else { 125 cCode = c.hashCode(); 126 } 127 128 return (aCode ^ bCode) ^ cCode; 129 } 130 131 @Override 132 public boolean equals(Object obj) { 133 if(obj == null) { 134 return false; 135 } 136 if(!(obj instanceof CachedTriple)) { 137 return false; 138 } 139 final CachedTriple<?,?,?> other = (CachedTriple<?,?,?>) obj; 140 if(!Objects.equals(this.a, other.a)) { 141 return false; 142 } 143 if(!Objects.equals(this.b, other.b)) { 144 return false; 145 } 146 return Objects.equals(this.c, other.c); 147 } 148 149 @Override 150 public String toString() { 151 return "Triple{" + "a=" + a + ", b=" + b + ", c=" + c + '}'; 152 } 153}