// Return exit code, number of bits written func (this *BlockDecompressor) call() (int, uint64) { var msg string printOut("Input file name set to '"+this.inputName+"'", this.verbose) printOut("Output file name set to '"+this.outputName+"'", this.verbose) msg = fmt.Sprintf("Verbose set to %t", this.verbose) printOut(msg, this.verbose) msg = fmt.Sprintf("Overwrite set to %t", this.overwrite) printOut(msg, this.verbose) prefix := "" if this.jobs > 1 { prefix = "s" } msg = fmt.Sprintf("Using %d job%s", this.jobs, prefix) printOut(msg, this.verbose) var output kanzi.OutputStream if strings.ToUpper(this.outputName) == "NONE" { output, _ = io.NewNullOutputStream() } else { var err error output, err = os.OpenFile(this.outputName, os.O_RDWR, 666) if err == nil { // File exists if this.overwrite == false { fmt.Printf("The output file '%v' exists and the 'overwrite' command ", this.outputName) fmt.Println("line option has not been provided") output.Close() return io.ERR_OVERWRITE_FILE, 0 } } else { // File does not exist, create output, err = os.Create(this.outputName) if err != nil { fmt.Printf("Cannot open output file '%v' for writing: %v\n", this.outputName, err) return io.ERR_CREATE_FILE, 0 } } } defer output.Close() // Decode read := uint64(0) printOut("Decoding ...", !this.silent) input, err := os.Open(this.inputName) if err != nil { fmt.Printf("Cannot open input file '%v': %v\n", this.inputName, err) return io.ERR_OPEN_FILE, read } defer input.Close() verboseWriter := os.Stdout if this.verbose == false { verboseWriter = nil } bis, err := io.NewBufferedInputStream(input) if err != nil { fmt.Printf("Cannot create compressed stream: %v\n", err) return io.ERR_CREATE_DECOMPRESSOR, read } cis, err := io.NewCompressedInputStream(bis, verboseWriter, this.jobs) if err != nil { if err.(*io.IOError) != nil { fmt.Printf("%s\n", err.(*io.IOError).Message()) return err.(*io.IOError).ErrorCode(), read } else { fmt.Printf("Cannot create compressed stream: %v\n", err) return io.ERR_CREATE_DECOMPRESSOR, read } } for e := this.listeners.Front(); e != nil; e = e.Next() { cis.AddListener(e.Value.(io.BlockListener)) } buffer := make([]byte, DECOMP_DEFAULT_BUFFER_SIZE) decoded := len(buffer) before := time.Now() // Decode next block for decoded == len(buffer) { if decoded, err = cis.Read(buffer); err != nil { if ioerr, isIOErr := err.(*io.IOError); isIOErr == true { fmt.Printf("%s\n", ioerr.Message()) return ioerr.ErrorCode(), read } else { fmt.Printf("An unexpected condition happened. Exiting ...\n%v\n", err) return io.ERR_PROCESS_BLOCK, read } } if decoded > 0 { _, err = output.Write(buffer[0:decoded]) if err != nil { fmt.Printf("Failed to write decompressed block to file '%v': %v\n", this.outputName, err) return io.ERR_WRITE_FILE, read } read += uint64(decoded) } } // Close streams to ensure all data are flushed // Deferred close is fallback for error paths if err := cis.Close(); err != nil { fmt.Printf("%v\n", err) return io.ERR_PROCESS_BLOCK, read } after := time.Now() delta := after.Sub(before).Nanoseconds() / 1000000 // convert to ms printOut("", !this.silent) msg = fmt.Sprintf("Decoding: %d ms", delta) printOut(msg, !this.silent) msg = fmt.Sprintf("Input size: %d", cis.GetRead()) printOut(msg, !this.silent) msg = fmt.Sprintf("Output size: %d", read) printOut(msg, !this.silent) if delta > 0 { msg = fmt.Sprintf("Throughput (KB/s): %d", ((read*uint64(1000))>>10)/uint64(delta)) printOut(msg, !this.silent) } printOut("", !this.silent) return 0, cis.GetRead() }
func testSpeed() { fmt.Printf("Speed Test\n") var filename = flag.String("filename", "r:\\output.bin", "Ouput file name for speed test") flag.Parse() values := []uint64{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 31, 14, 41, 15, 59, 92, 26, 65, 53, 35, 58, 89, 97, 79, 93, 32} iter := 150 read := uint64(0) written := uint64(0) delta1 := int64(0) delta2 := int64(0) nn := 100000 * len(values) defer os.Remove(*filename) for test := 0; test < iter; test++ { file1, err := os.Create(*filename) if err != nil { fmt.Printf("Cannot create %s", *filename) return } bos, _ := io.NewBufferedOutputStream(file1) obs, _ := bitstream.NewDefaultOutputBitStream(bos, 16*1024) before := time.Now() for i := 0; i < nn; i++ { obs.WriteBits(values[i%len(values)], 1+uint(i&63)) } // Close first to force flush() obs.Close() delta1 += time.Now().Sub(before).Nanoseconds() written += obs.Written() file1.Close() file2, err := os.Open(*filename) if err != nil { fmt.Printf("Cannot open %s", *filename) return } bis, _ := io.NewBufferedInputStream(file2) ibs, _ := bitstream.NewDefaultInputBitStream(bis, 1024*1024) before = time.Now() for i := 0; i < nn; i++ { ibs.ReadBits(1 + uint(i&63)) } ibs.Close() delta2 += time.Now().Sub(before).Nanoseconds() read += ibs.Read() file2.Close() } println() fmt.Printf("%v bits written (%v MB)\n", written, written/1024/8192) fmt.Printf("%v bits read (%v MB)\n", read, read/1024/8192) println() fmt.Printf("Write [ms] : %v\n", delta1/1000000) fmt.Printf("Throughput [MB/s] : %d\n", (written/1024*1000/8192)/uint64(delta1/1000000)) fmt.Printf("Read [ms] : %v\n", delta2/1000000) fmt.Printf("Throughput [MB/s] : %d\n", (read/1024*1000/8192)/uint64(delta2/1000000)) }