/*
* Copyright (C) 2014 Indeed Inc.
*
* Licensed 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 com.indeed.flamdex;
import com.google.common.base.Function;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multiset;
import com.indeed.flamdex.api.FlamdexReader;
import com.indeed.flamdex.utils.FlamdexReinverter;
import com.indeed.flamdex.writer.FlamdexDocument;
import it.unimi.dsi.fastutil.longs.LongList;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author jsgroth
*/
class FlamdexCompare {
static boolean unorderedEquals(FlamdexReader r1, FlamdexReader r2) {
return unorderedEquals(FlamdexReinverter.reinvertInMemory(r1), FlamdexReinverter.reinvertInMemory(r2));
}
static boolean unorderedEquals(List<FlamdexDocument> l1, List<FlamdexDocument> l2) {
if (l1.size() != l2.size()) return false;
Multiset<FlamdexDocumentWrapper> s1 = HashMultiset.create(Lists.transform(l1, new Function<FlamdexDocument, FlamdexDocumentWrapper>() {
@Override
public FlamdexDocumentWrapper apply(FlamdexDocument input) {
return new FlamdexDocumentWrapper(input);
}
}));
for (final FlamdexDocument doc : l2) {
final FlamdexDocumentWrapper w = new FlamdexDocumentWrapper(doc);
if (!s1.remove(w)) return false;
}
return s1.isEmpty();
}
private static class FlamdexDocumentWrapper {
private final Map<String, LongSet> intFields;
private final Map<String, Set<String>> stringFields;
private FlamdexDocumentWrapper(FlamdexDocument doc) {
intFields = rewriteIntFields(doc.getIntFields());
stringFields = rewriteStringFields(doc.getStringFields());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FlamdexDocumentWrapper that = (FlamdexDocumentWrapper) o;
if (intFields != null ? !intFields.equals(that.intFields) : that.intFields != null) return false;
if (stringFields != null ? !stringFields.equals(that.stringFields) : that.stringFields != null)
return false;
return true;
}
@Override
public int hashCode() {
int result = intFields != null ? intFields.hashCode() : 0;
result = 31 * result + (stringFields != null ? stringFields.hashCode() : 0);
return result;
}
public String toString() {
return "FlamdexDocumentWrapper{" +
"intFields=" + intFields +
", stringFields=" + stringFields +
'}';
}
}
private static Map<String, LongSet> rewriteIntFields(Map<String, LongList> map) {
Map<String, LongSet> ret = Maps.newHashMapWithExpectedSize(map.size());
for (String key : map.keySet()) {
ret.put(key, new LongOpenHashSet(map.get(key)));
}
return ret;
}
private static Map<String, Set<String>> rewriteStringFields(Map<String, List<String>> map) {
Map<String, Set<String>> ret = Maps.newHashMapWithExpectedSize(map.size());
for (String key : map.keySet()) {
ret.put(key, new HashSet<String>(map.get(key)));
}
return ret;
}
}