Index: src/0dev.org/commands/pdc/main.go ================================================================== --- src/0dev.org/commands/pdc/main.go +++ src/0dev.org/commands/pdc/main.go @@ -1,25 +1,31 @@ package main import ( + pprof "0dev.org/debug/pprof" iou "0dev.org/ioutil" predictor "0dev.org/predictor" - "bufio" + // "bufio" "fmt" "io" "os" ) func main() { + var code int switch { case len(os.Args) == 1: - os.Exit(compress(os.Stdout, os.Stdin)) + code = compress(os.Stdout, os.Stdin) case len(os.Args) == 2 && os.Args[1] == "-d": - os.Exit(decompress(os.Stdout, os.Stdin)) + code = decompress(os.Stdout, os.Stdin) default: fmt.Fprintln(os.Stdout, "Usage: pdc [-d]") } + + pprof.Stop() + + os.Exit(code) } // Compress the data from the given io.Reader and write it to the given io.Writer // I/O is buffered for better performance func compress(output io.Writer, input io.Reader) int { @@ -56,11 +62,12 @@ // I/O is buffered for better performance func decompress(output io.Writer, input io.Reader) int { var ( err error buffer io.Writer = iou.SizedWriter(output, 4096) - decompressor io.Reader = predictor.Decompressor(bufio.NewReader(input)) + decompressor io.Reader = predictor.Decompressor(iou.SizedReader(input, 4096)) + //decompressor io.Reader = predictor.Decompressor(bufio.NewReader(input)) ) _, err = io.Copy(buffer, decompressor) if err != nil { fmt.Fprintln(os.Stderr, "Error while decompressing.\n", err) Index: src/0dev.org/ioutil/ioutil.go ================================================================== --- src/0dev.org/ioutil/ioutil.go +++ src/0dev.org/ioutil/ioutil.go @@ -79,60 +79,67 @@ return write(input[count:]) } return write } + +type sizedReader struct { + reader io.Reader + buffer []byte + from, to, size int +} // Returns a reader that delegates calls to Read(...) while ensuring // that the output buffer is never smaller than the required size // and is downsized to a multiple of the required size if larger. func SizedReader(reader io.Reader, size int) io.Reader { - var ( - buffer []byte = make([]byte, size) - from, to int = 0, 0 - ) - - return ReaderFunc(func(output []byte) (int, error) { - var ( - count int - err error - ) - - start: - // Reply with the buffered data if there is any - if to-from > 0 { - count = copy(output, buffer[from:to]) - - // Advance the data in the buffer - from += count - - // Check whether we have reached the end of the buffer - if to-from == 0 { - // Reset the buffer - from, to = 0, 0 - - return count, err - } - - // Do not propagate an error until the buffer is exhausted - return count, nil - } - - // Delegate if the buffer is empty and the destination buffer is large enough - if len(output) >= size { - return reader.Read(output[:(len(output)/size)*size]) - } - - // Perform a read into the buffer - count, err = reader.Read(buffer) - - // Size the buffer down to the read data size - // and restart if we have successfully read some bytes - from, to = 0, count - if to-from > 0 { - goto start - } - - // Returning on err/misbehaving noop reader - return 0, err - }) + var sr sizedReader + sr.reader = reader + sr.buffer = make([]byte, size) + sr.size, sr.from, sr.to = size, 0, 0 + return &sr +} + +func (sr *sizedReader) Read(output []byte) (int, error) { + var ( + count int + err error + ) + +start: + // Reply with the buffered data if there is any + if sr.to-sr.from > 0 { + count = copy(output, sr.buffer[sr.from:sr.to]) + + // Advance the data in the buffer + sr.from += count + + // Check whether we have reached the end of the buffer + if sr.to-sr.from == 0 { + // Reset the buffer + sr.from, sr.to = 0, 0 + + return count, err + } + + // Do not propagate an error until the buffer is exhausted + return count, nil + } + + // Delegate if the buffer is empty and the destination buffer is large enough + if len(output) >= sr.size { + return sr.reader.Read(output[:(len(output)/sr.size)*sr.size]) + } + + // Perform a read into the buffer + count, err = sr.reader.Read(sr.buffer) + + // Size the buffer down to the read data size + // and restart if we have successfully read some bytes + sr.from, sr.to = 0, count + if sr.to-sr.from > 0 { + goto start + } + + // Returning on err/misbehaving noop reader + return 0, err }