/** * 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.hadoop.contrib.index.mapred; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.StringTokenizer; import org.apache.hadoop.io.Text; import org.apache.hadoop.io.WritableComparable; /** * This class represents the metadata of a shard. Version is the version number * of the entire index. Directory is the directory where this shard resides in. * Generation is the Lucene index's generation. Version and generation are * reserved for future use. * * Note: Currently the version number of the entire index is not used and * defaults to -1. */ public class Shard implements WritableComparable { // This method is copied from Path. public static String normalizePath(String path) { // remove double slashes & backslashes path = path.replace("//", "/"); path = path.replace("\\", "/"); // trim trailing slash from non-root path (ignoring windows drive) if (path.length() > 1 && path.endsWith("/")) { path = path.substring(0, path.length() - 1); } return path; } public static void setIndexShards(IndexUpdateConfiguration conf, Shard[] shards) { StringBuilder shardsString = new StringBuilder(shards[0].toString()); for (int i = 1; i < shards.length; i++) { shardsString.append(","); shardsString.append(shards[i].toString()); } conf.setIndexShards(shardsString.toString()); } public static Shard[] getIndexShards(IndexUpdateConfiguration conf) { String shards = conf.getIndexShards(); if (shards != null) { ArrayList<Object> list = Collections.list(new StringTokenizer(shards, ",")); Shard[] result = new Shard[list.size()]; for (int i = 0; i < list.size(); i++) { result[i] = Shard.createShardFromString((String) list.get(i)); } return result; } else { return null; } } // assume str is formatted correctly as a shard string private static Shard createShardFromString(String str) { int first = str.indexOf("@"); int second = str.indexOf("@", first + 1); long version = Long.parseLong(str.substring(0, first)); String dir = str.substring(first + 1, second); long gen = Long.parseLong(str.substring(second + 1)); return new Shard(version, dir, gen); } // index/shard version // the shards in the same version of an index have the same version number private long version; private String dir; private long gen; // Lucene's generation /** * Constructor. */ public Shard() { this.version = -1; this.dir = null; this.gen = -1; } /** * Construct a shard from a versio number, a directory and a generation * number. * @param version the version number of the entire index * @param dir the directory where this shard resides * @param gen the generation of the Lucene instance */ public Shard(long version, String dir, long gen) { this.version = version; this.dir = normalizePath(dir); this.gen = gen; } /** * Construct using a shard object. * @param shard the shard used by the constructor */ public Shard(Shard shard) { this.version = shard.version; this.dir = shard.dir; this.gen = shard.gen; } /** * Get the version number of the entire index. * @return the version number of the entire index */ public long getVersion() { return version; } /** * Get the directory where this shard resides. * @return the directory where this shard resides */ public String getDirectory() { return dir; } /** * Get the generation of the Lucene instance. * @return the generation of the Lucene instance */ public long getGeneration() { return gen; } /* (non-Javadoc) * @see java.lang.Object#toString() */ public String toString() { return version + "@" + dir + "@" + gen; } // /////////////////////////////////// // Writable // /////////////////////////////////// /* (non-Javadoc) * @see org.apache.hadoop.io.Writable#write(java.io.DataOutput) */ public void write(DataOutput out) throws IOException { out.writeLong(version); Text.writeString(out, dir); out.writeLong(gen); } /* (non-Javadoc) * @see org.apache.hadoop.io.Writable#readFields(java.io.DataInput) */ public void readFields(DataInput in) throws IOException { version = in.readLong(); dir = Text.readString(in); gen = in.readLong(); } // /////////////////////////////////// // Comparable // /////////////////////////////////// /* (non-Javadoc) * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(Object o) { return compareTo((Shard) o); } /** * Compare to another shard. * @param other another shard * @return compare version first, then directory and finally generation */ public int compareTo(Shard other) { // compare version if (version < other.version) { return -1; } else if (version > other.version) { return 1; } // compare dir int result = dir.compareTo(other.dir); if (result != 0) { return result; } // compare gen if (gen < other.gen) { return -1; } else if (gen == other.gen) { return 0; } else { return 1; } } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Shard)) { return false; } Shard other = (Shard) o; return version == other.version && dir.equals(other.dir) && gen == other.gen; } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ public int hashCode() { return (int) version ^ dir.hashCode() ^ (int) gen; } }