activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chir...@apache.org
Subject svn commit: r1232066 - in /activemq/activemq-apollo/trunk: apollo-cli/src/main/resources/META-INF/services/org.apache.activemq.apollo/ apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/ apollo-util/src/main/scala/org/apache/activemq/apo...
Date Mon, 16 Jan 2012 17:25:29 GMT
Author: chirino
Date: Mon Jan 16 17:25:28 2012
New Revision: 1232066

URL: http://svn.apache.org/viewvc?rev=1232066&view=rev
Log:
Moving the disk benchmark so that it's accessible via the apollo CLI.  Improved the memory
property editor so it supports both SI and IEC units up to exbibyte and exabytes. You can
now also format a long memory value.

Added:
    activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/DiskBenchmark.scala
Removed:
    activemq/activemq-apollo/trunk/apollo-util/src/main/scala/org/apache/activemq/apollo/util/DiskBenchmark.java
Modified:
    activemq/activemq-apollo/trunk/apollo-cli/src/main/resources/META-INF/services/org.apache.activemq.apollo/apollo-broker-commands.index
    activemq/activemq-apollo/trunk/apollo-cli/src/main/resources/META-INF/services/org.apache.activemq.apollo/apollo-commands.index
    activemq/activemq-apollo/trunk/apollo-util/src/main/scala/org/apache/activemq/apollo/util/MemoryPropertyEditor.java

Modified: activemq/activemq-apollo/trunk/apollo-cli/src/main/resources/META-INF/services/org.apache.activemq.apollo/apollo-broker-commands.index
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-cli/src/main/resources/META-INF/services/org.apache.activemq.apollo/apollo-broker-commands.index?rev=1232066&r1=1232065&r2=1232066&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-cli/src/main/resources/META-INF/services/org.apache.activemq.apollo/apollo-broker-commands.index
(original)
+++ activemq/activemq-apollo/trunk/apollo-cli/src/main/resources/META-INF/services/org.apache.activemq.apollo/apollo-broker-commands.index
Mon Jan 16 17:25:28 2012
@@ -22,4 +22,5 @@ org.apache.activemq.apollo.cli.commands.
 org.apache.activemq.apollo.cli.commands.StoreExport
 org.apache.activemq.apollo.cli.commands.StoreImport
 org.apache.activemq.apollo.cli.commands.DashHelp
-org.apache.activemq.apollo.cli.commands.Version
\ No newline at end of file
+org.apache.activemq.apollo.cli.commands.Version
+org.apache.activemq.apollo.cli.commands.DiskBenchmark
\ No newline at end of file

Modified: activemq/activemq-apollo/trunk/apollo-cli/src/main/resources/META-INF/services/org.apache.activemq.apollo/apollo-commands.index
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-cli/src/main/resources/META-INF/services/org.apache.activemq.apollo/apollo-commands.index?rev=1232066&r1=1232065&r2=1232066&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-cli/src/main/resources/META-INF/services/org.apache.activemq.apollo/apollo-commands.index
(original)
+++ activemq/activemq-apollo/trunk/apollo-cli/src/main/resources/META-INF/services/org.apache.activemq.apollo/apollo-commands.index
Mon Jan 16 17:25:28 2012
@@ -19,3 +19,4 @@ org.apache.activemq.apollo.cli.commands.
 org.apache.activemq.apollo.cli.commands.Help
 org.apache.activemq.apollo.cli.commands.DashHelp
 org.apache.activemq.apollo.cli.commands.Version
+org.apache.activemq.apollo.cli.commands.DiskBenchmark
\ No newline at end of file

Added: activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/DiskBenchmark.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/DiskBenchmark.scala?rev=1232066&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/DiskBenchmark.scala
(added)
+++ activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/DiskBenchmark.scala
Mon Jan 16 17:25:28 2012
@@ -0,0 +1,256 @@
+package org.apache.activemq.apollo.cli.commands
+
+/**
+ * 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.
+ */
+import org.apache.felix.gogo.commands.{Action, Option => option, Argument => argument,
Command => command}
+import org.apache.felix.service.command.CommandSession
+import java.io.{RandomAccessFile, File}
+import java.util.concurrent.TimeUnit
+import javax.management.ObjectName
+import management.ManagementFactory
+import org.apache.activemq.apollo.util.{MemoryPropertyEditor, IOHelper}
+
+
+class Report {
+  
+  var block_size: Int = 0
+  var async_writes: Int = 0
+  var async_write_duration: Long = 0L
+  var sync_writes: Int = 0
+  var sync_write_duration: Long = 0L
+  var reads: Int = 0
+  var read_duration: Long = 0L
+
+  def async_write_size_rate: Float = {
+    var rc: Float = async_writes
+    rc *= block_size
+    rc /= (1024 * 1024)
+    rc /= (async_write_duration / 1000.0f)
+    return rc
+  }
+
+  def async_write_rate: Float = {
+    var rc: Float = async_writes
+    rc /= (async_write_duration / 1000.0f)
+    return rc
+  }
+
+  def sync_write_size_rate: Float = {
+    var rc: Float = sync_writes
+    rc *= block_size
+    rc /= (1024 * 1024)
+    rc /= (sync_write_duration / 1000.0f)
+    return rc
+  }
+
+  def sync_write_rate: Float = {
+    var rc: Float = sync_writes
+    rc /= (sync_write_duration / 1000.0f)
+    return rc
+  }
+
+  def read_size_rate: Float = {
+    var rc: Float = reads
+    rc *= block_size
+    rc /= (1024 * 1024)
+    rc /= (read_duration / 1000.0f)
+    return rc
+  }
+
+  def read_rate: Float = {
+    var rc: Float = reads
+    rc /= (read_duration / 1000.0f)
+    return rc
+  }
+  
+  override def toString: String = {
+    return "Async writes: \n" + "  " + async_writes + " writes of size " + block_size + "
written in " + (async_write_duration / 1000.0) + " seconds.\n" +
+            "  " + async_write_rate + " writes/second.\n" +
+            "  " + async_write_size_rate + " megs/second.\n" +
+            "\n" +
+            "Sync writes: \n" + "  " + sync_writes + " writes of size " + block_size + "
written in " + (sync_write_duration / 1000.0) + " seconds.\n" +
+            "  " + sync_write_rate + " writes/second.\n" +
+            "  " + sync_write_size_rate + " megs/second.\n" +
+            "\n" +
+            "Reads: \n" + "  " + reads + " reads of size " + block_size + " read in " + (read_duration
/ 1000.0) + " seconds.\n" +
+            "  " + read_rate + " writes/second.\n" +
+            "  " + read_size_rate + " megs/second.\n" +
+            "\n" + ""
+  }
+
+}
+
+object DiskBenchmark {
+  
+  final val PHYSICAL_MEM_SIZE = MemoryPropertyEditor.format((try {
+    val mbean_server = ManagementFactory.getPlatformMBeanServer()
+    mbean_server.getAttribute(new ObjectName("java.lang:type=OperatingSystem"), "TotalPhysicalMemorySize")
match {
+      case x:java.lang.Long=> Some(x.longValue)
+      case _ => None
+    }
+  } catch {
+    case _ => None
+  }).getOrElse(1024*1024*500L))
+
+}
+
+
+/**
+ * The apollo encrypt command
+ */
+@command(scope="apollo", name = "disk-benchmark", description = "Benchmarks your disk's speed")
+class DiskBenchmark extends Action {
+  import DiskBenchmark._
+
+  @option(name = "--verbose", description = "Enable verbose output")
+  var verbose: Boolean = false
+  @option(name = "--sample-interval", description = "The number of milliseconds to spend
mesuring perfomance.")
+  var sampleInterval: Long = 10 * 1000
+  @argument(name="file", description="The file that will be used to benchmark your disk (must
NOT exist)")
+  var file = new File("disk-benchmark.dat")
+  
+  @option(name = "--block-size", description = "The size of each IO operation.")
+  var block_size_txt = "4k"
+  def block_size = MemoryPropertyEditor.parse(block_size_txt).toInt
+
+  @option(name = "--file-size", description = "The size of the data file to use, this should
be big enough to flush the OS write cache.")
+  var file_size_txt = PHYSICAL_MEM_SIZE
+  def file_size = MemoryPropertyEditor.parse(file_size_txt)
+
+  @option(name = "--warm-up-size", description = "The amount of data we should initial write
before measuring performance samples (used to flush the OS write cache).")
+  var warm_up_size_txt = PHYSICAL_MEM_SIZE
+  def warm_up_size = MemoryPropertyEditor.parse(warm_up_size_txt)
+
+  def execute(session: CommandSession):AnyRef = {
+    def out = session.getConsole
+    try {
+      if (file.exists) {
+        out.println("File " + file + " allready exists, will not benchmark.")
+      } else {
+        out.println("Benchmark using data file: " + file.getCanonicalPath)
+
+        // Initialize the block /w data..
+        var data = new Array[Byte](block_size)
+        var i: Int = 0
+        while (i < data.length) {
+          data(i) = ('a' + (i % 26)).asInstanceOf[Byte]
+          i += 1
+        }
+
+        val report = new Report
+        report.block_size = block_size
+
+        // Pre-allocate the file size..
+        var raf = new RandomAccessFile(file, "rw")
+        try {
+
+          out.println("Pre-allocating data file of size: "+file_size_txt)
+          raf.setLength(file_size)
+          raf.seek(file_size-1)
+          raf.writeByte(0);
+          IOHelper.sync(raf.getFD)
+
+          if( warm_up_size > 0 ) {
+            val max = warm_up_size
+            out.println("Warming up... writing async "+warm_up_size_txt+" so that async writes
don't have that much of an advantage due to the OS write cache.")
+            write(raf, data, (count)=>{
+              count > max
+            })
+          }
+
+
+          out.println("Benchmarking async writes")
+          var start = System.nanoTime()
+          var end = start
+          report.async_writes = write(raf, data, (count)=>{
+            end = System.nanoTime
+            TimeUnit.NANOSECONDS.toMillis(end-start) >  sampleInterval
+          })
+          report.async_write_duration = TimeUnit.NANOSECONDS.toMillis(end-start)
+
+          out.println("Syncing previous writes before measuring sync write performance..
(might take a while if your OS has a big write cache)")
+          IOHelper.sync(raf.getFD)
+
+          out.println("Benchmarking sync writes")
+          start = System.nanoTime()
+          end = start
+          report.sync_writes = write(raf, data, (count)=>{
+            IOHelper.sync(raf.getFD)
+            end = System.nanoTime
+            TimeUnit.NANOSECONDS.toMillis(end-start) >  sampleInterval
+          })
+          report.sync_write_duration = TimeUnit.NANOSECONDS.toMillis(end-start)
+
+          out.println("Benchmarking reads")
+          start = System.nanoTime()
+          end = start
+          report.reads = read(raf, data, (count)=>{
+            end = System.nanoTime
+            TimeUnit.NANOSECONDS.toMillis(end-start) >  sampleInterval
+          })
+          report.read_duration = TimeUnit.NANOSECONDS.toMillis(end-start)
+
+        } finally {
+          raf.close
+        }
+        file.delete
+        out.println(report)
+      }
+    } catch {
+      case x:Helper.Failure=> error(x.getMessage)
+      case e: Throwable =>
+        if (verbose) {
+          out.println("ERROR:")
+          e.printStackTrace(System.out)
+        } else {
+          out.println("ERROR: " + e)
+        }
+    }
+    null
+  }
+
+  private def write(raf: RandomAccessFile, data: Array[Byte], until: (Long)=>Boolean)
= {
+    var file_position = raf.getFilePointer
+    var counter = 0
+    while (!until(counter * data.length)) {
+      if(  file_position + data.length >= file_size ) {
+        file_position = 0;
+        raf.seek(file_position)
+      }
+      raf.write(data)
+      counter += 1;
+      file_position += data.length
+    }
+    counter
+  }
+
+  private def read(raf: RandomAccessFile, data: Array[Byte], until: (Long)=>Boolean) =
{
+    var file_position = raf.getFilePointer
+    var counter = 0
+    while (!until(counter * data.length)) {
+      if( file_position + data.length >= file_size ) {
+        file_position = 0;
+        raf.seek(file_position)
+      }
+      raf.readFully(data)
+      counter += 1;
+      file_position += data.length
+    }
+    counter
+  }
+
+}
\ No newline at end of file

Modified: activemq/activemq-apollo/trunk/apollo-util/src/main/scala/org/apache/activemq/apollo/util/MemoryPropertyEditor.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-util/src/main/scala/org/apache/activemq/apollo/util/MemoryPropertyEditor.java?rev=1232066&r1=1232065&r2=1232066&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-util/src/main/scala/org/apache/activemq/apollo/util/MemoryPropertyEditor.java
(original)
+++ activemq/activemq-apollo/trunk/apollo-util/src/main/scala/org/apache/activemq/apollo/util/MemoryPropertyEditor.java
Mon Jan 16 17:25:28 2012
@@ -21,46 +21,165 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 /**
- * Converts string values like "20 Mb", "1024kb", and "1g" to long values in
- * bytes.
+ * Converts string values like "20 Mib", "1024kb", and "1g" to long values in bytes.
  */
 public class MemoryPropertyEditor extends PropertyEditorSupport {
+
+    private static final Pattern BYTE_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*b?\\s*$",
Pattern.CASE_INSENSITIVE);
+
+    private static final Pattern KIB_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*k(ib)?\\s*$",
Pattern.CASE_INSENSITIVE);
+    private static final Pattern MIB_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*m(ib)?\\s*$",
Pattern.CASE_INSENSITIVE);
+    private static final Pattern GIB_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*g(ib)?\\s*$",
Pattern.CASE_INSENSITIVE);
+    private static final Pattern TIB_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*t(ib)?\\s*$",
Pattern.CASE_INSENSITIVE);
+    private static final Pattern PIB_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*p(ib)?\\s*$",
Pattern.CASE_INSENSITIVE);
+    private static final Pattern EIB_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*e(ib)?\\s*$",
Pattern.CASE_INSENSITIVE);
+
+    private static final Pattern KB_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*kb?\\s*$",
Pattern.CASE_INSENSITIVE);
+    private static final Pattern MB_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*mb?\\s*$",
Pattern.CASE_INSENSITIVE);
+    private static final Pattern GB_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*gb?\\s*$",
Pattern.CASE_INSENSITIVE);
+    private static final Pattern TB_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*tb?\\s*$",
Pattern.CASE_INSENSITIVE);
+    private static final Pattern PB_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*pb?\\s*$",
Pattern.CASE_INSENSITIVE);
+    private static final Pattern EB_PATTERN = Pattern.compile("^\\s*(\\d+)\\s*eb?\\s*$",
Pattern.CASE_INSENSITIVE);
+
     public void setAsText(String text) throws IllegalArgumentException {
 
-        Pattern p = Pattern.compile("^\\s*(\\d+)\\s*(b)?\\s*$", Pattern.CASE_INSENSITIVE);
-        Matcher m = p.matcher(text);
+        Matcher m = BYTE_PATTERN.matcher(text);
         if (m.matches()) {
             setValue(Long.valueOf(Long.parseLong(m.group(1))));
             return;
         }
-
-        p = Pattern.compile("^\\s*(\\d+)\\s*k(b)?\\s*$", Pattern.CASE_INSENSITIVE);
-        m = p.matcher(text);
+        m = KIB_PATTERN.matcher(text);
         if (m.matches()) {
             setValue(Long.valueOf(Long.parseLong(m.group(1)) * 1024));
             return;
         }
-
-        p = Pattern.compile("^\\s*(\\d+)\\s*m(b)?\\s*$", Pattern.CASE_INSENSITIVE);
-        m = p.matcher(text);
+        m = MIB_PATTERN.matcher(text);
         if (m.matches()) {
             setValue(Long.valueOf(Long.parseLong(m.group(1)) * 1024 * 1024));
             return;
         }
-
-        p = Pattern.compile("^\\s*(\\d+)\\s*g(b)?\\s*$", Pattern.CASE_INSENSITIVE);
-        m = p.matcher(text);
+        m = GIB_PATTERN.matcher(text);
         if (m.matches()) {
             setValue(Long.valueOf(Long.parseLong(m.group(1)) * 1024 * 1024 * 1024));
             return;
         }
+        m = TIB_PATTERN.matcher(text);
+        if (m.matches()) {
+            setValue(Long.valueOf(Long.parseLong(m.group(1)) * 1024 * 1024 * 1024 * 1024));
+            return;
+        }
+        m = PIB_PATTERN.matcher(text);
+        if (m.matches()) {
+            setValue(Long.valueOf(Long.parseLong(m.group(1)) * 1024 * 1024 * 1024 * 1024
* 1024));
+            return;
+        }
+        m = EIB_PATTERN.matcher(text);
+        if (m.matches()) {
+            setValue(Long.valueOf(Long.parseLong(m.group(1)) * 1024 * 1024 * 1024 * 1024
* 1024 * 1024));
+            return;
+        }
+
+        m = KB_PATTERN.matcher(text);
+        if (m.matches()) {
+            setValue(Long.valueOf(Long.parseLong(m.group(1)) * 1000));
+            return;
+        }
+        m = MB_PATTERN.matcher(text);
+        if (m.matches()) {
+            setValue(Long.valueOf(Long.parseLong(m.group(1)) * 1000 * 1000));
+            return;
+        }
+        m = GB_PATTERN.matcher(text);
+        if (m.matches()) {
+            setValue(Long.valueOf(Long.parseLong(m.group(1)) * 1000 * 1000 * 1000));
+            return;
+        }
+        m = TB_PATTERN.matcher(text);
+        if (m.matches()) {
+            setValue(Long.valueOf(Long.parseLong(m.group(1)) * 1000 * 1000 * 1000 * 1000));
+            return;
+        }
+        m = PB_PATTERN.matcher(text);
+        if (m.matches()) {
+            setValue(Long.valueOf(Long.parseLong(m.group(1)) * 1000 * 1000 * 1000 * 1000
* 1000));
+            return;
+        }
+        m = EB_PATTERN.matcher(text);
+        if (m.matches()) {
+            setValue(Long.valueOf(Long.parseLong(m.group(1)) * 1000 * 1000 * 1000 * 1000
* 1000 * 1000));
+            return;
+        }
 
         throw new IllegalArgumentException("Could convert not to a memory size: " + text);
     }
 
     public String getAsText() {
         Long value = (Long)getValue();
-        return value != null ? value.toString() : "";
+        if( value == null ) 
+            return "";
+        long v = value.longValue();
+        
+        if( (v % 1024) != 0) {
+            if( (v % 1000) != 0) {
+                return Long.toString(v);
+            } else {
+                v = v/1000;
+                if( (v % 1000) != 0) {
+                    return v+"kB";
+                } else {
+                    v = v/1000;
+                    if( (v % 1000) != 0) {
+                        return v+"MB";
+                    } else {
+                        v = v/1000;
+                        if( (v % 1000) != 0) {
+                            return v+"GB";
+                        } else {
+                            v = v/1000;
+                            if( (v % 1000) != 0) {
+                                return v+"TB";
+                            } else {
+                                v = v/1000;
+                                if( (v % 1000) != 0) {
+                                    return v+"PB";
+                                } else {
+                                    v = v/1000;
+                                    return v+"EB";
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } else {
+            v = v/1024;
+            if( (v % 1024) != 0) {
+                return v+"KiB";
+            } else {
+                v = v/1024;
+                if( (v % 1024) != 0) {
+                    return v+"MiB";
+                } else {
+                    v = v/1024;
+                    if( (v % 1024) != 0) {
+                        return v+"GiB";
+                    } else {
+                        v = v/1024;
+                        if( (v % 1024) != 0) {
+                            return v+"TiB";
+                        } else {
+                            v = v/1024;
+                            if( (v % 1024) != 0) {
+                                return v+"PiB";
+                            } else {
+                                v = v/1024;
+                                return v+"EiB";
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
 
     public static long parse(String value) {
@@ -68,4 +187,10 @@ public class MemoryPropertyEditor extend
         pe.setAsText(value);
         return (Long)pe.getValue();
     }
+    
+    public static String format(long value) {
+        MemoryPropertyEditor pe = new MemoryPropertyEditor();
+        pe.setValue(value);
+        return pe.getAsText();
+    }
 }



Mime
View raw message