| /* |
| * 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.ignite.internal.processors.igfs; |
| |
| import java.io.Externalizable; |
| import java.io.IOException; |
| import java.io.ObjectInput; |
| import java.io.ObjectOutput; |
| import java.net.InetAddress; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.LinkedHashSet; |
| import java.util.UUID; |
| import org.apache.ignite.IgniteCheckedException; |
| import org.apache.ignite.binary.BinaryObjectException; |
| import org.apache.ignite.binary.BinaryRawReader; |
| import org.apache.ignite.binary.BinaryRawWriter; |
| import org.apache.ignite.binary.BinaryReader; |
| import org.apache.ignite.binary.BinaryWriter; |
| import org.apache.ignite.binary.Binarylizable; |
| import org.apache.ignite.cluster.ClusterNode; |
| import org.apache.ignite.igfs.IgfsBlockLocation; |
| import org.apache.ignite.internal.util.tostring.GridToStringInclude; |
| import org.apache.ignite.internal.util.typedef.F; |
| import org.apache.ignite.internal.util.typedef.internal.S; |
| import org.apache.ignite.internal.util.typedef.internal.U; |
| import org.jetbrains.annotations.NotNull; |
| |
| /** |
| * File block location in the grid. |
| */ |
| public class IgfsBlockLocationImpl implements IgfsBlockLocation, Externalizable, Binarylizable { |
| /** */ |
| private static final long serialVersionUID = 0L; |
| |
| /** */ |
| private long start; |
| |
| /** */ |
| private long len; |
| |
| /** */ |
| @GridToStringInclude |
| private Collection<UUID> nodeIds; |
| |
| /** */ |
| private Collection<String> names; |
| |
| /** */ |
| @GridToStringInclude |
| private Collection<String> hosts; |
| |
| /** |
| * Empty constructor for externalizable. |
| */ |
| public IgfsBlockLocationImpl() { |
| // No-op. |
| } |
| |
| /** |
| * @param location HDFS block location. |
| * @param len New length. |
| */ |
| public IgfsBlockLocationImpl(IgfsBlockLocation location, long len) { |
| assert location != null; |
| |
| start = location.start(); |
| this.len = len; |
| |
| nodeIds = location.nodeIds(); |
| names = location.names(); |
| hosts = location.hosts(); |
| } |
| |
| /** |
| * @param start Start. |
| * @param len Length. |
| * @param nodes Affinity nodes. |
| */ |
| public IgfsBlockLocationImpl(long start, long len, Collection<ClusterNode> nodes) { |
| assert start >= 0; |
| assert len > 0; |
| assert nodes != null && !nodes.isEmpty(); |
| |
| this.start = start; |
| this.len = len; |
| |
| convertFromNodes(nodes); |
| } |
| |
| /** |
| * @param start Start. |
| * @param len Length. |
| * @param block Block. |
| */ |
| public IgfsBlockLocationImpl(long start, long len, IgfsBlockLocation block) { |
| assert start >= 0; |
| assert len > 0; |
| |
| this.start = start; |
| this.len = len; |
| |
| nodeIds = block.nodeIds(); |
| names = block.names(); |
| hosts = block.hosts(); |
| } |
| |
| /** |
| * @param start Start. |
| * @param len Length. |
| * @param names Collection of host:port addresses. |
| * @param hosts Collection of host:port addresses. |
| */ |
| public IgfsBlockLocationImpl(long start, long len, Collection<String> names, Collection<String> hosts) { |
| assert start >= 0; |
| assert len > 0; |
| assert names != null && !names.isEmpty(); |
| assert hosts != null && !hosts.isEmpty(); |
| |
| this.start = start; |
| this.len = len; |
| |
| nodeIds = Collections.emptySet(); |
| |
| this.names = names; |
| this.hosts = hosts; |
| } |
| |
| /** |
| * @return Start position. |
| */ |
| @Override public long start() { |
| return start; |
| } |
| |
| /** |
| * @return Length. |
| */ |
| @Override public long length() { |
| return len; |
| } |
| |
| /** |
| * @param addLen Length to increase. |
| */ |
| public void increaseLength(long addLen) { |
| len += addLen; |
| } |
| |
| /** |
| * @param len Block length. |
| */ |
| public void length(long len) { |
| this.len = len; |
| } |
| |
| /** |
| * @return Node IDs. |
| */ |
| @Override public Collection<UUID> nodeIds() { |
| return nodeIds; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public Collection<String> names() { |
| return names; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public Collection<String> hosts() { |
| return hosts; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int hashCode() { |
| int res = (int)(start ^ (start >>> 32)); |
| |
| res = 31 * res + (int)(len ^ (len >>> 32)); |
| res = 31 * res + nodeIds.hashCode(); |
| |
| return res; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean equals(Object o) { |
| if (o == this) |
| return true; |
| |
| if (o == null || getClass() != o.getClass()) |
| return false; |
| |
| IgfsBlockLocationImpl that = (IgfsBlockLocationImpl)o; |
| |
| return len == that.len && start == that.start && F.eq(nodeIds, that.nodeIds) && F.eq(names, that.names) && |
| F.eq(hosts, that.hosts); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public String toString() { |
| return S.toString(IgfsBlockLocationImpl.class, this); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void writeExternal(ObjectOutput out) throws IOException { |
| assert names != null; |
| assert hosts != null; |
| |
| out.writeLong(start); |
| out.writeLong(len); |
| |
| out.writeBoolean(nodeIds != null); |
| |
| if (nodeIds != null) { |
| out.writeInt(nodeIds.size()); |
| |
| for (UUID nodeId : nodeIds) |
| U.writeUuid(out, nodeId); |
| } |
| |
| out.writeInt(names.size()); |
| |
| for (String name : names) |
| out.writeUTF(name); |
| |
| out.writeInt(hosts.size()); |
| |
| for (String host : hosts) |
| out.writeUTF(host); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void readExternal(ObjectInput in) throws IOException { |
| start = in.readLong(); |
| len = in.readLong(); |
| |
| int size; |
| |
| if (in.readBoolean()) { |
| size = in.readInt(); |
| |
| nodeIds = new ArrayList<>(size); |
| |
| for (int i = 0; i < size; i++) |
| nodeIds.add(U.readUuid(in)); |
| } |
| |
| size = in.readInt(); |
| |
| names = new ArrayList<>(size); |
| |
| for (int i = 0; i < size; i++) |
| names.add(in.readUTF()); |
| |
| size = in.readInt(); |
| |
| hosts = new ArrayList<>(size); |
| |
| for (int i = 0; i < size; i++) |
| hosts.add(in.readUTF()); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException { |
| BinaryRawWriter rawWriter = writer.rawWriter(); |
| |
| assert names != null; |
| assert hosts != null; |
| |
| rawWriter.writeLong(start); |
| rawWriter.writeLong(len); |
| |
| rawWriter.writeBoolean(nodeIds != null); |
| |
| if (nodeIds != null) { |
| rawWriter.writeInt(nodeIds.size()); |
| |
| for (UUID nodeId : nodeIds) |
| U.writeUuid(rawWriter, nodeId); |
| } |
| |
| rawWriter.writeInt(names.size()); |
| |
| for (String name : names) |
| rawWriter.writeString(name); |
| |
| rawWriter.writeInt(hosts.size()); |
| |
| for (String host : hosts) |
| rawWriter.writeString(host); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void readBinary(BinaryReader reader) throws BinaryObjectException { |
| BinaryRawReader rawReader = reader.rawReader(); |
| |
| start = rawReader.readLong(); |
| len = rawReader.readLong(); |
| |
| int size; |
| |
| if (rawReader.readBoolean()) { |
| size = rawReader.readInt(); |
| |
| nodeIds = new ArrayList<>(size); |
| |
| for (int i = 0; i < size; i++) |
| nodeIds.add(U.readUuid(rawReader)); |
| } |
| |
| size = rawReader.readInt(); |
| |
| names = new ArrayList<>(size); |
| |
| for (int i = 0; i < size; i++) |
| names.add(rawReader.readString()); |
| |
| size = rawReader.readInt(); |
| |
| hosts = new ArrayList<>(size); |
| |
| for (int i = 0; i < size; i++) |
| hosts.add(rawReader.readString()); |
| } |
| |
| /** |
| * Converts collection of rich nodes to block location data. |
| * |
| * @param nodes Collection of affinity nodes. |
| */ |
| private void convertFromNodes(Collection<ClusterNode> nodes) { |
| Collection<String> names = new LinkedHashSet<>(); |
| Collection<String> hosts = new LinkedHashSet<>(); |
| Collection<UUID> nodeIds = new ArrayList<>(nodes.size()); |
| |
| for (final ClusterNode node : nodes) { |
| // Normalize host names into Hadoop-expected format. |
| try { |
| Collection<InetAddress> addrs = U.toInetAddresses(node); |
| |
| for (InetAddress addr : addrs) { |
| if (addr.getHostName() == null) |
| names.add(addr.getHostAddress() + ":" + 9001); |
| else { |
| names.add(addr.getHostName() + ":" + 9001); // hostname:portNumber |
| hosts.add(addr.getHostName()); |
| } |
| } |
| } |
| catch (IgniteCheckedException ignored) { |
| names.addAll(node.addresses()); |
| } |
| |
| nodeIds.add(node.id()); |
| } |
| |
| this.nodeIds = nodeIds; |
| this.names = names; |
| this.hosts = hosts; |
| } |
| } |