summaryrefslogtreecommitdiffstats
path: root/libjava/gnu/gcj/tools/gcj_dbtool/Main.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/gnu/gcj/tools/gcj_dbtool/Main.java')
-rw-r--r--libjava/gnu/gcj/tools/gcj_dbtool/Main.java177
1 files changed, 144 insertions, 33 deletions
diff --git a/libjava/gnu/gcj/tools/gcj_dbtool/Main.java b/libjava/gnu/gcj/tools/gcj_dbtool/Main.java
index b9bea0e09fa..256b6196df5 100644
--- a/libjava/gnu/gcj/tools/gcj_dbtool/Main.java
+++ b/libjava/gnu/gcj/tools/gcj_dbtool/Main.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 Free Software Foundation
+/* Copyright (C) 2004, 2005 Free Software Foundation
This file is part of libgcj.
@@ -11,13 +11,15 @@ package gnu.gcj.tools.gcj_dbtool;
import gnu.gcj.runtime.PersistentByteMap;
import java.io.*;
+import java.nio.channels.*;
import java.util.*;
import java.util.jar.*;
import java.security.MessageDigest;
-import java.math.BigInteger;
public class Main
{
+ static private boolean verbose = false;
+
public static void main (String[] s)
{
insist (s.length >= 1);
@@ -29,7 +31,7 @@ public class Main
+ ") "
+ System.getProperty("java.vm.version"));
System.out.println();
- System.out.println("Copyright 2004 Free Software Foundation, Inc.");
+ System.out.println("Copyright 2004, 2005 Free Software Foundation, Inc.");
System.out.println("This is free software; see the source for copying conditions. There is NO");
System.out.println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
return;
@@ -42,26 +44,14 @@ public class Main
if (s[0].equals("-n"))
{
+ // Create a new database.
insist (s.length >= 2 && s.length <= 3);
int capacity = 32749;
if (s.length == 3)
- {
- // The user has explicitly provided a size for the table.
- // We're going to make that size prime. This isn't
- // strictly necessary but it can't hurt.
-
- BigInteger size = new BigInteger(s[2], 10);
- BigInteger two = BigInteger.ONE.add(BigInteger.ONE);
-
- if (size.getLowestSetBit() != 0) // A hard way to say isEven()
- size = size.add(BigInteger.ONE);
-
- while (! size.isProbablePrime(10))
- size = size.add(two);
-
- capacity = size.intValue();
+ {
+ capacity = Integer.parseInt(s[2]);
if (capacity <= 2)
{
@@ -73,7 +63,8 @@ public class Main
try
{
PersistentByteMap b
- = PersistentByteMap.emptyPersistentByteMap (s[1], capacity, capacity*64);
+ = PersistentByteMap.emptyPersistentByteMap(new File(s[1]),
+ capacity, capacity*32);
}
catch (Exception e)
{
@@ -86,18 +77,26 @@ public class Main
if (s[0].equals("-a"))
{
+ // Add a jar file to a database, creating it if necessary.
+ // Copies the database, adds the jar file to the copy, and
+ // then renames the new database over the old.
try
{
insist (s.length == 4);
- File jar = new File(s[2]);
- PersistentByteMap b
- = new PersistentByteMap(new File(s[1]),
- PersistentByteMap.AccessMode.READ_WRITE);
+ File database = new File(s[1]);
+ database = database.getAbsoluteFile();
+ File jar = new File(s[2]);
+ PersistentByteMap map;
+ if (database.isFile())
+ map = new PersistentByteMap(database,
+ PersistentByteMap.AccessMode.READ_ONLY);
+ else
+ map = PersistentByteMap.emptyPersistentByteMap(database,
+ 100, 100*32);
File soFile = new File(s[3]);
if (! soFile.isFile())
throw new IllegalArgumentException(s[3] + " is not a file");
-
- addJar(jar, b, soFile);
+ map = addJar(jar, map, soFile);
}
catch (Exception e)
{
@@ -110,6 +109,7 @@ public class Main
if (s[0].equals("-t"))
{
+ // Test
try
{
insist (s.length == 2);
@@ -142,8 +142,60 @@ public class Main
return;
}
+ if (s[0].equals("-m"))
+ {
+ // Merge databases.
+ insist (s.length >= 3);
+ try
+ {
+ File database = new File(s[1]);
+ database = database.getAbsoluteFile();
+ File temp = File.createTempFile(database.getName(), "",
+ database.getParentFile());
+
+ int newSize = 0;
+ int newStringTableSize = 0;
+ PersistentByteMap[] sourceMaps = new PersistentByteMap[s.length - 2];
+ // Scan all the input files, calculating worst case string
+ // table and hash table use.
+ for (int i = 2; i < s.length; i++)
+ {
+ PersistentByteMap b
+ = new PersistentByteMap(new File(s[i]),
+ PersistentByteMap.AccessMode.READ_ONLY);
+ newSize += b.size();
+ newStringTableSize += b.stringTableSize();
+ sourceMaps[i - 2] = b;
+ }
+
+ newSize *= 1.5; // Scaling the new size by 1.5 results in
+ // fewer collisions.
+ PersistentByteMap map
+ = PersistentByteMap.emptyPersistentByteMap
+ (temp, newSize, newStringTableSize);
+
+ for (int i = 0; i < sourceMaps.length; i++)
+ {
+ if (verbose)
+ System.err.println("adding " + sourceMaps[i].size()
+ + " elements from "
+ + sourceMaps[i].getFile());
+ map.putAll(sourceMaps[i]);
+ }
+ map.close();
+ temp.renameTo(database);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ System.exit(3);
+ }
+ return;
+ }
+
if (s[0].equals("-l"))
{
+ // List a database.
insist (s.length == 2);
try
{
@@ -180,6 +232,7 @@ public class Main
if (s[0].equals("-d"))
{
+ // For testing only: fill the byte map with random data.
insist (s.length == 2);
try
{
@@ -225,20 +278,49 @@ public class Main
+ " Usage: \n"
+ " gcj-dbtool -n file.gcjdb [size] - Create a new gcj map database\n"
+ " gcj-dbtool -a file.gcjdb file.jar file.so\n"
- + " - Add the contents of file.jar to the database\n"
+ + " - Add the contents of file.jar to a new gcj map database\n"
+ " gcj-dbtool -t file.gcjdb - Test a gcj map database\n"
- + " gcj-dbtool -l file.gcjdb - List a gcj map database\n");
+ + " gcj-dbtool -l file.gcjdb - List a gcj map database\n"
+ + " gcj-dbtool -m dest.gcjdb [source.gcjdb]...\n"
+ + " - Merge gcj map databases into dest\n"
+ + " Replaces dest\n"
+ + " To add to dest, include dest in the list of sources");
}
-
- private static void addJar(File f, PersistentByteMap b, File soFile)
- throws Exception
+ // Add a jar to a map. This copies the map first and returns a
+ // different map that contains the data. The original map is
+ // closed.
+
+ private static PersistentByteMap
+ addJar(File f, PersistentByteMap b, File soFile)
+ throws Exception
{
MessageDigest md = MessageDigest.getInstance("MD5");
JarFile jar = new JarFile (f);
+
+ int count = 0;
+ {
+ Enumeration entries = jar.entries();
+ while (entries.hasMoreElements())
+ {
+ JarEntry classfile = (JarEntry)entries.nextElement();
+ if (classfile.getName().endsWith(".class"))
+ count++;
+ }
+ }
+
+ if (verbose)
+ System.err.println("adding " + count + " elements from "
+ + f + " to " + b.getFile());
+
+ // Maybe resize the destination map. We're allowing plenty of
+ // extra space by using a loadFactor of 2.
+ b = resizeMap(b, (b.size() + count) * 2, true);
+
Enumeration entries = jar.entries();
+ byte[] soFileName = soFile.getCanonicalPath().getBytes("UTF-8");
while (entries.hasMoreElements())
{
JarEntry classfile = (JarEntry)entries.nextElement();
@@ -259,12 +341,41 @@ public class Main
+ classfile.getName());
pos += len;
}
- b.put(md.digest(data),
- soFile.getCanonicalPath().getBytes());
+ b.put(md.digest(data), soFileName);
}
- }
+ }
+ return b;
}
+ // Resize a map by creating a new one with the same data and
+ // renaming it. If close is true, close the original map.
+
+ static PersistentByteMap resizeMap(PersistentByteMap m, int newCapacity, boolean close)
+ throws IOException, IllegalAccessException
+ {
+ newCapacity = Math.max(m.capacity(), newCapacity);
+ File name = m.getFile();
+ File copy = File.createTempFile(name.getName(), "", name.getParentFile());
+ try
+ {
+ PersistentByteMap dest
+ = PersistentByteMap.emptyPersistentByteMap
+ (copy, newCapacity, newCapacity*32);
+ dest.putAll(m);
+ dest.force();
+ if (close)
+ m.close();
+ copy.renameTo(name);
+ return dest;
+ }
+ catch (Exception e)
+ {
+ copy.delete();
+ }
+ return null;
+ }
+
+
static String bytesToString(byte[] b)
{
StringBuffer hexBytes = new StringBuffer();
OpenPOWER on IntegriCloud