package uk.ac.imperial.lsds.seep.tools; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import java.util.Map.Entry; import java.util.Properties; import joptsimple.OptionParser; import joptsimple.OptionSet; import joptsimple.OptionSpec; import uk.ac.imperial.lsds.seep.api.data.OTuple; import uk.ac.imperial.lsds.seep.api.data.Schema; import uk.ac.imperial.lsds.seep.api.data.Schema.SchemaBuilder; import uk.ac.imperial.lsds.seep.api.data.TupleInfo; import uk.ac.imperial.lsds.seep.api.data.Type; public class GenerateBinaryFile { private static int FILE_SIZE = 10; // 10MB private static int BATCH_SIZE = 10; public static void main(String[] args){ /** * EXAMPLE parameters command line: * --output test.txt --schema "param1, param2" --types "int, int" --values 0 1 --filesize 10 * The right name for types: look at the method that does the parsing below */ OptionParser parser = new OptionParser(); parser.accepts("schema", "Schema fields").withRequiredArg().required(); parser.accepts("types", "Seed values").withRequiredArg().required(); parser.accepts("values", "Seed values").withRequiredArg().required(); parser.accepts("output", "Absolute path to output generated file").withRequiredArg().required(); parser.accepts("filesize", "Desired file size in MB").withRequiredArg(); OptionSet os = parser.parse(args); Properties p = asProperties(os); Schema s = createSchema(p.getProperty("schema"), p.getProperty("types")); int fileSize = p.containsKey("filesize") ? Integer.parseInt((String) p.getProperty("filesize")) : FILE_SIZE; String path = p.getProperty("output"); createFile(s, p.getProperty("output"), fileSize); System.out.println("-> Created file: "+path+" of size: "+fileSize); } // TODO: just fill with ints for now... public static void createFile(Schema s, String path, int targetSize){ File output = new File(path); int currentSize = 0; BufferedOutputStream bos = null; DataOutputStream dos = null; try { bos = new BufferedOutputStream(new FileOutputStream(output)); dos = new DataOutputStream(bos); Object[] values = new Object[s.names().length]; while((currentSize/1000000) < targetSize){ for(int i = 0; i < values.length; i++){ values[i] = values[i] == null ? 2 : (int)values[i] + 2; } byte[] data = OTuple.create(s, s.names(), values); int batchSize = data.length * BATCH_SIZE + TupleInfo.TUPLE_SIZE_OVERHEAD * BATCH_SIZE; dos.write(0); // control byte dos.writeInt(BATCH_SIZE); // num tuples in batch dos.writeInt(batchSize); // total batch size for(int i = 0; i < BATCH_SIZE; i++){ dos.writeInt(data.length); dos.write(data); currentSize = currentSize + data.length + 4; } currentSize = currentSize + 1 + 4 + 4; } dos.flush(); dos.close(); bos.flush(); bos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static Schema createSchema(String schema, String types){ String[] sTokens = schema.split(","); String[] tTokens = types.split(","); System.out.println("#Fields: "+sTokens.length+" #Types: "+tTokens.length); if(sTokens.length != tTokens.length || sTokens.length == 0 || tTokens.length == 0){ System.out.println("schema, types do not match (size) or is 0"); System.exit(0); } SchemaBuilder sb = SchemaBuilder.getInstance(); for(int i = 0; i < sTokens.length; i++){ Type type = getType(tTokens[i].trim()); sb.newField(type, sTokens[i]); } return sb.build(); } private static Type getType(String type){ switch(type){ case "int": return Type.INT; case "long": return Type.LONG; case "short": return Type.SHORT; case "byte": return Type.BYTE; case "bytes": return Type.BYTES; case "shortstring": return Type.SHORTSTRING; case "string": return Type.STRING; default: System.out.println("Non-recognized type"); System.exit(0); return null; } } private static Properties asProperties(OptionSet options) { Properties properties = new Properties(); for ( Entry<OptionSpec<?>, List<?>> entry : options.asMap().entrySet() ) { OptionSpec<?> spec = entry.getKey(); String key = asPropertyKey(spec); String value = asPropertyValue(entry.getValue(), options.has(spec)); properties.setProperty(key, value); } return properties; } private static String asPropertyKey(OptionSpec<?> spec) { List<String> flags = (List<String>) spec.options(); for ( String flag : flags ) if ( 1 < flag.length() ) return flag; throw new IllegalArgumentException( "No usable non-short flag: " + flags ); } private static String asPropertyValue( List<?> values, boolean present ) { // Simple flags have no values; treat presence/absence as true/false String value = ""; if(values.isEmpty()){ return String.valueOf(present); } else{ for(int i = 0; i < values.size(); i++){ if(i != 0){ value.concat(","); } value = value.concat(String.valueOf(values.get(i))); } } return value; } }