/* This file is part of VoltDB.
* Copyright (C) 2008-2017 VoltDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with VoltDB. If not, see <http://www.gnu.org/licenses/>.
*/
package org.voltdb.importer;
import java.net.URI;
import java.util.List;
import java.util.NavigableSet;
import java.util.Set;
import com.google_voltpatches.common.collect.ImmutableList;
import com.google_voltpatches.common.collect.ImmutableSet;
import com.google_voltpatches.common.collect.ImmutableSetMultimap;
import com.google_voltpatches.common.collect.SetMultimap;
import com.google_voltpatches.common.collect.Sets;
public class ChannelAssignment {
final Set<ChannelSpec> added;
final Set<ChannelSpec> removed;
final NavigableSet<ChannelSpec> channels;
final int version;
final List<ImporterChannelAssignment> assignments;
ChannelAssignment(NavigableSet<ChannelSpec> prev, NavigableSet<ChannelSpec> next, int version) {
this.version = version;
this.added = Sets.difference(next, prev);
this.removed = Sets.difference(prev, next);
this.channels = next;
this.assignments = perImporterAssignments();
}
public Set<ChannelSpec> getAdded() {
return added;
}
public Set<ChannelSpec> getRemoved() {
return removed;
}
public NavigableSet<ChannelSpec> getChannels() {
return channels;
}
public int getVersion() {
return version;
}
public boolean hasChanges() {
return !removed.isEmpty() || !added.isEmpty();
}
@Override
public String toString() {
return "ChannelAssignment [added=" + added + ", removed=" + removed
+ ", channels=" + channels + ", version=" + version + "]";
}
public List<ImporterChannelAssignment> getImporterChannelAssignments() {
return assignments;
}
private SetMultimap<String, URI> mapByImporter(Set<ChannelSpec> specs) {
ImmutableSetMultimap.Builder<String, URI> mmbldr = ImmutableSetMultimap.builder();
for (ChannelSpec spec: specs) {
mmbldr.put(spec.getImporter(),spec.getUri());
}
return mmbldr.build();
}
private List<ImporterChannelAssignment> perImporterAssignments() {
ImmutableSet.Builder<String> sbldr = ImmutableSet.builder();
for (ChannelSpec spec: Sets.union(added, removed)) {
sbldr.add(spec.getImporter());
}
ImmutableList.Builder<ImporterChannelAssignment> lbldr = ImmutableList.builder();
final SetMultimap<String, URI> added = mapByImporter(getAdded());
final SetMultimap<String, URI> removed = mapByImporter(getRemoved());
final SetMultimap<String, URI> assigned = mapByImporter(getChannels());
for (String importer: sbldr.build()) {
lbldr.add(new ImporterChannelAssignment(
importer,
added.get(importer),
removed.get(importer),
assigned.get(importer),
version
));
}
return lbldr.build();
}
}