| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.pig.data.utils; |
| |
| import org.apache.pig.impl.logicalLayer.schema.Schema; |
| import org.apache.pig.impl.logicalLayer.schema.Schema.FieldSchema; |
| |
| public class StructuresHelper { |
| private StructuresHelper() { |
| } |
| |
| /** |
| * This encapsulates a Schema and allows it to be used in such a way that |
| * any aliases are ignored in equality. |
| */ |
| public static class SchemaKey { |
| private Schema s; |
| |
| public SchemaKey(Schema s) { |
| this.s = s; |
| } |
| |
| private static int[] primeList = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, |
| 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, |
| 83, 89, 97, 101, 103, 107, 109, 1133}; |
| |
| /** |
| * The hashcode logic is taken from the Schema class, including how fields |
| * are handled. The difference is that aliases are ignored. |
| */ |
| @Override |
| public int hashCode() { |
| return hashCode(s); |
| } |
| |
| public static int hashCode(Schema s) { |
| if (s == null) { |
| return 0; |
| } |
| int idx = 0 ; |
| int hashCode = 0 ; |
| for(FieldSchema fs : s.getFields()) { |
| hashCode += hashCode(fs) * (primeList[idx % primeList.length]) ; |
| idx++ ; |
| } |
| return hashCode ; |
| } |
| |
| private static int hashCode(FieldSchema fs) { |
| return (fs.type * 17) + ( (fs.schema == null? 0 : hashCode(fs.schema)) * 23 ); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (!(o instanceof SchemaKey)) { |
| return false; |
| } |
| Schema other = ((SchemaKey)o).get(); |
| return (s == null && other == null) || Schema.equals(s, other, false, true); |
| } |
| |
| public Schema get() { |
| return s; |
| } |
| |
| public String toString() { |
| return s.toString(); |
| } |
| } |
| |
| /** |
| * This is a helper class which makes it easy to have pairs of values, |
| * and to use them as keys and values in Maps. |
| */ |
| public static class Pair<T1, T2> { |
| private final T1 t1; |
| private final T2 t2; |
| |
| public Pair(T1 t1, T2 t2) { |
| this.t1 = t1; |
| this.t2 = t2; |
| } |
| |
| public T1 getFirst() { |
| return t1; |
| } |
| |
| public T2 getSecond() { |
| return t2; |
| } |
| |
| public static <A,B> Pair<A,B> make(A t1, B t2) { |
| return new Pair<A,B>(t1, t2); |
| } |
| |
| @Override |
| public int hashCode() { |
| return (t1 == null ? 0 : t1.hashCode()) + (t2 == null ? 0 : 31 * t2.hashCode()); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (!(o instanceof Pair<?,?>)) { |
| return false; |
| } |
| Pair<?,?> pr = (Pair<?,?>)o; |
| if (t1 == null) { |
| return pr.getFirst() == null; |
| } |
| if (!t1.equals(pr.getFirst())) { |
| return false; |
| } |
| if (t2 == null) { |
| return pr.getSecond() == null; |
| } |
| return t2.equals(pr.getSecond()); |
| } |
| |
| @Override |
| public String toString() { |
| return new StringBuilder() |
| .append("[") |
| .append(t1) |
| .append(",") |
| .append(t2) |
| .append("]") |
| .toString(); |
| } |
| } |
| |
| public static class Triple<T1, T2, T3> { |
| private final T1 t1; |
| private final T2 t2; |
| private final T3 t3; |
| |
| public Triple(T1 t1, T2 t2, T3 t3) { |
| this.t1 = t1; |
| this.t2 = t2; |
| this.t3 = t3; |
| } |
| |
| public T1 getFirst() { |
| return t1; |
| } |
| |
| public T2 getSecond() { |
| return t2; |
| } |
| |
| public T3 getThird() { |
| return t3; |
| } |
| |
| public static <A,B,C> Triple<A,B,C> make(A t1, B t2, C t3) { |
| return new Triple<A,B,C>(t1, t2, t3); |
| } |
| |
| @Override |
| public int hashCode() { |
| return (t1 == null ? 0 : t1.hashCode()) |
| + (t2 == null ? 0 : 31 * t2.hashCode()) |
| + (t3 == null ? 0 : 527 * t3.hashCode()); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (!(o instanceof Triple<?,?,?>)) { |
| return false; |
| } |
| Triple<?,?,?> tr = (Triple<?,?,?>)o; |
| if (t1 == null) { |
| return tr.getFirst() == null; |
| } |
| if (!t1.equals(tr.getFirst())) { |
| return false; |
| } |
| if (t2 == null) { |
| return tr.getSecond() == null; |
| } |
| if (!t2.equals(tr.getSecond())) { |
| return false; |
| } |
| if (t3 == null) { |
| return tr.getThird() ==null; |
| } |
| if (!t3.equals(tr.getThird())) { |
| return false; |
| } |
| return true; |
| } |
| |
| @Override |
| public String toString() { |
| return new StringBuilder() |
| .append("[") |
| .append(t1) |
| .append(",") |
| .append(t2) |
| .append(",") |
| .append(t3) |
| .append("]") |
| .toString(); |
| } |
| } |
| } |