EftarFile.java revision 0
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * CDDL HEADER START
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The contents of this file are subject to the terms of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Common Development and Distribution License (the "License").
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * You may not use this file except in compliance with the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * See LICENSE.txt included in this distribution for the specific
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * language governing permissions and limitations under the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * When distributing Covered Code, include this CDDL HEADER in each
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * file and include the License file at LICENSE.txt.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If applicable, add the following below this CDDL HEADER, with the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * fields enclosed by brackets "[]" replaced with your own identifying
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * information: Portions Copyright [yyyy] [name of copyright owner]
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * CDDL HEADER END
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Use is subject to license terms.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
9740fa737ef2ed9453ab46d145777dbbbf6a747bMark de Reeper/*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * ident "%Z%%M% %I% %E% SMI"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpackage org.opensolaris.opengrok.web;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.io.*;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.*;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * An Extremely Fast Tagged Attribute Read-only File System
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Created on October 12, 2005
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * A Eftar File has the following format
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * FILE --> Record ( Record | tagString ) *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Record --> 64bit:Hash 16bit:childrenOffset 16bit:(numberChildren|lenthOfTag) 16bit:tagOffset
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * It is a tree of tagged names,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * doing binary search in sorted list of children
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @author Chandan
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpublic class EftarFile {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static final int RECORD_LENGTH = 14;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private long offset;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private DataOutputStream out;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster class Node {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public long hash;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public String tag;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public java.util.TreeMap<Long, Node> children;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public long tagOffset;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public long childOffset;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public long myOffset;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public Node(long hash, String tag) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.hash = hash;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.tag = tag;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster children = new TreeMap<Long, Node>();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public Node put(long hash, String desc) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if(children.get(hash) == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster children.put(hash, new Node(hash, desc));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return children.get(hash);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public Node get(long hash) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest return children.get(hash);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest class FNode {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public long offset;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public long hash;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public int childOffset;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public int numChildren;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public int tagOffset;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public FNode(RandomAccessFile f) throws Throwable {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster offset = f.getFilePointer();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster hash = f.readLong();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster childOffset = f.readUnsignedShort();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster numChildren = f.readUnsignedShort();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster tagOffset = f.readUnsignedShort();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public FNode(long hash, long offset, int childOffset, int num, int tagOffset) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.hash = hash;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.offset = offset;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.childOffset = childOffset;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.numChildren = num;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.tagOffset = tagOffset;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public FNode get(long hash, RandomAccessFile f) throws Throwable {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest if (childOffset == 0) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest return null;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest return sbinSearch(offset + childOffset, numChildren, hash, f);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest private FNode sbinSearch(long start, int len, long hash, RandomAccessFile f) throws Throwable {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest int b = 0;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest int e = len;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest while(b <= e) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest int m = (b + e) /2;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest f.seek(start + m * RECORD_LENGTH);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest long mhash = f.readLong();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest if (hash > mhash) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest b = m + 1;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest } else if (hash < mhash) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest e = m - 1;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest } else {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest return new FNode(mhash, (f.getFilePointer() - 8l), f.readUnsignedShort(), f.readUnsignedShort(),f.readUnsignedShort());
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest return null;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public static long myHash(String name) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest if(name == null || name.length() == 0) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest return 0;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest long hash = 2861;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest int n = name.length();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest if(n > 100)
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest n = 100;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest for(int i = 0 ; i < n; i++) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest hash = (hash * 641 + name.charAt(i) * 2969 + hash << 6) % 9322397;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest return hash;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest private void write(Node n) throws IOException {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest if(n.tag != null) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest out.write(n.tag.getBytes());
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest offset += n.tag.length();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest for(Node childnode: n.children.values()) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest out.writeLong(childnode.hash);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest if(childnode.children.size() > 0) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest out.writeShort((short) (childnode.childOffset - offset));
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest out.writeShort((short) childnode.children.size());
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest } else {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest out.writeShort(0);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest if(childnode.tag != null) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest out.writeShort((short) childnode.tag.length());
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest } else {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest out.writeShort((short) 0);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (childnode.tag != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster out.writeShort((short) (childnode.tagOffset - offset));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster out.writeShort(0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster offset += RECORD_LENGTH;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for(Node childnode: n.children.values()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster write(childnode);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void traverse(Node n) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (n.tag == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster n.tagOffset = 0;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster n.tagOffset = offset;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster offset += n.tag.length();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if(n.children.size() > 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster n.childOffset = offset;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster offset += (RECORD_LENGTH * n.children.size());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster n.childOffset = 0;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for(Node childnode: n.children.values()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster traverse(childnode);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private Node root;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void readInput(String tagsPath) throws IOException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster BufferedReader r = new BufferedReader(new FileReader(tagsPath));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if(root == null) {
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk root = new Node(1, null);
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk }
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk String line;
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk int size = 0;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while ((line = r.readLine()) != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int tab = line.indexOf('\t');
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if(tab >0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String path = line.substring(0, tab);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String desc = line.substring(tab+1);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster size += desc.length() + 1 + 15;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringTokenizer toks = new StringTokenizer(path, File.separator);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Node n = root;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (toks.hasMoreTokens()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster n = n.put(myHash(toks.nextToken()), null);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster n.tag = desc;
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk }
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk }
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void write(String outPath) throws FileNotFoundException, IOException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster offset = RECORD_LENGTH;
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk traverse(root);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(outPath)));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster out.writeLong(0x5e33);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster out.writeShort(RECORD_LENGTH);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster out.writeShort(root.children.size());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster out.writeShort(0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster offset = RECORD_LENGTH;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster write(root);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster out.close();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void main(String args[]) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Date tn = new Date();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if(args.length < 2)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new Exception("Usage inputFile [inputFile ...] outputFile");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster EftarFile ef = new EftarFile();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for(int i=0; i< args.length-1; i++) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ef.readInput(args[i]);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ef.write(args[args.length-1]);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster //System.err.println("Took " + (new Date().getTime() - tn.getTime() ) + " msecs to build");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster System.err.println("EftarFile: Error in " + e.getStackTrace()[0] + "\n\t" + e.getMessage());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}