/* * Copyright (C) 2009 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xcmis.search.lucene.index; import org.xcmis.spi.utils.Logger; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Created by The eXo Platform SAS. * * @author <a href="mailto:Sergey.Kabashnyuk@gmail.com">Sergey Kabashnyuk</a> * @version $Id: IndexInfo.java 2 2010-02-04 17:21:49Z andrew00x $ */ public class IndexInfo { /** * Class logger. */ private final Logger log = Logger.getLogger(IndexInfo.class); /** * For new segment names. */ private int counter = 0; /** * Flag that indicates if index infos needs to be written to disk. */ private boolean dirty = false; /** * List of index names */ private List<String> indexes = new ArrayList<String>(); /** * Set of names for quick lookup. */ private Set<String> names = new HashSet<String>(); /** * Name of the file where the infos are stored. */ private final String name; /** * Creates a new IndexInfos using <code>fileName</code>. * * @param fileName the name of the file where infos are stored. */ public IndexInfo(String fileName) { this.name = fileName; } /** * Returns <code>true</code> if this index infos exists in <code>dir</code>. * * @param dir the directory where to look for the index infos. * @return <code>true</code> if it exists; <code>false</code> otherwise. */ public boolean exists(File dir) { return new File(dir, name).exists(); } /** * Returns the name of the file where infos are stored. * * @return the name of the file where infos are stored. */ public String getFileName() { return name; } /** * Reads the index infos. * * @param dir the directory from where to read the index infos. * @throws IOException if an error occurs. */ public void read(File dir) throws IndexException { try { InputStream in = new FileInputStream(new File(dir, name)); try { DataInputStream di = new DataInputStream(in); counter = di.readInt(); for (int i = di.readInt(); i > 0; i--) { String indexName = di.readUTF(); indexes.add(indexName); names.add(indexName); } } finally { in.close(); } } catch (FileNotFoundException e) { throw new IndexException(e.getLocalizedMessage(), e); } catch (IOException e) { throw new IndexException(e.getLocalizedMessage(), e); } } /** * Writes the index infos to disk if they are dirty. * * @param dir the directory where to write the index infos. * @throws IOException if an error occurs. */ public void write(File dir) throws IOException { // do not write if not dirty if (!dirty) { return; } File nu = new File(dir, name + ".new"); OutputStream out = new FileOutputStream(nu); try { DataOutputStream dataOut = new DataOutputStream(out); dataOut.writeInt(counter); dataOut.writeInt(indexes.size()); for (int i = 0; i < indexes.size(); i++) { dataOut.writeUTF(getName(i)); } } finally { out.close(); } // delete old File old = new File(dir, name); if (old.exists() && !old.delete()) { throw new IOException("Unable to delete file: " + old.getAbsolutePath()); } if (!nu.renameTo(old)) { throw new IOException("Unable to rename file: " + nu.getAbsolutePath()); } dirty = false; } /** * Returns the index name at position <code>i</code>. * * @param i the position. * @return the index name. */ public String getName(int i) { return indexes.get(i); } /** * Returns the number of index names. * * @return the number of index names. */ public int size() { return indexes.size(); } /** * Adds a name to the index infos. * * @param name the name to add. */ public void addName(String indexName) { if (names.contains(indexName)) { throw new IllegalArgumentException("already contains: " + indexName); } indexes.add(indexName); names.add(indexName); dirty = true; } /** * Removes the name from the index infos. * * @param name the name to remove. */ public void removeName(String indexName) { indexes.remove(indexName); names.remove(indexName); dirty = true; } /** * Removes the name from the index infos. * * @param i the position. */ public void removeName(int i) { String indexName = indexes.remove(i); names.remove(indexName); dirty = true; } /** * Returns <code>true</code> if <code>name</code> exists in this * <code>IndexInfos</code>; <code>false</code> otherwise. * * @param name the name to test existence. * @return <code>true</code> it is exists in this <code>IndexInfos</code>. */ public boolean contains(String indexName) { return names.contains(indexName); } /** * Returns a new unique name for an index folder. * * @return a new unique name for an index folder. */ public String newName() { dirty = true; return "_" + Integer.toString(counter++, Character.MAX_RADIX); } }