예제 #1
0
// 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()
}
예제 #2
0
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))
}