Overview
| Comment: | encoding/mtf.Encoder now returns an io.Reader. This allows to encoding in place without allocating buffers. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
470d7e947b552686794784b96cdb8dca |
| User & Date: | spaskalev on 2015-01-04 12:24:08.924 |
| Other Links: | manifest | tags |
Context
|
2015-01-04
| ||
| 12:52 | commands/mtf now uses fibonacci representation when encoding check-in: 6bd6e6d5c7 user: spaskalev tags: trunk | |
| 12:24 | encoding/mtf.Encoder now returns an io.Reader. This allows to encoding in place without allocating buffers. check-in: 470d7e947b user: spaskalev tags: trunk | |
|
2015-01-02
| ||
| 17:55 | update the copyright notice for 2015 check-in: 783d0b7f51 user: spaskalev tags: trunk | |
Changes
Modified src/0dev.org/commands/mtf/main.go
from [8212c2eba2]
to [a9b931eec8].
1 2 3 4 5 6 7 8 9 10 11 12 |
package main
import (
mtf "0dev.org/encoding/mtf"
iou "0dev.org/ioutil"
"fmt"
"io"
"os"
)
func main() {
var code int
| > > > > | < | | | < < > | < | | < < < < < < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
package main
import (
mtf "0dev.org/encoding/mtf"
iou "0dev.org/ioutil"
"flag"
"fmt"
"io"
"os"
)
func main() {
d := flag.Bool("d", false, "Use to toggle decode mode")
flag.Parse()
var code int
if *d {
code = decode(os.Stdout, os.Stdin)
} else {
code = encode(os.Stdout, os.Stdin)
}
os.Exit(code)
}
// Transforms the data according to the move-to-front algorithm
// I/O is buffered for better performance
func encode(output io.Writer, input io.Reader) int {
var (
err error
encoder io.Reader = mtf.Encoder(iou.SizedReader(input, 4096))
)
_, err = io.Copy(output, encoder)
if err != nil {
fmt.Fprintln(os.Stderr, "Error while encoding.\n", err)
return 1
}
return 0
}
// Reverses MTF`ed data and writes back the original bytes
// I/O is buffered for better performance
func decode(output io.Writer, input io.Reader) int {
var (
err error
decoder io.Reader = mtf.Decoder(iou.SizedReader(input, 4096))
)
_, err = io.Copy(output, decoder)
if err != nil {
|
| ︙ | ︙ |
Modified src/0dev.org/encoding/mtf/mtf.go
from [f2ad12a795]
to [cebf1719c8].
| ︙ | ︙ | |||
25 26 27 28 29 30 31 |
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
}
type context struct {
table [256]byte
}
| < < < < < < < | < < < < | < < < < < < < < < < < | | | > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > | > | < < < < < < < < < | < < < < < < < < < < < < < | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
}
type context struct {
table [256]byte
}
// Encodes data in place
func (c *context) encode(data []byte) {
for index, value := range data {
// Shortcut for sequential, equal values
if c.table[0] == value {
data[index] = 0
continue
}
// Loop over the MTF table
for j := byte(1); j != 0; j++ {
if c.table[j] == value {
// Output the value
data[index] = j
// Shift the table
copy(c.table[1:], c.table[:j])
// Restore the value in front and break
c.table[0] = value
break
}
}
}
}
// Decode data in place
func (c *context) decode(data []byte) {
for index, value := range data {
position := value
// Shortcut for sequential, equal values
if position == 0 {
data[index] = c.table[0]
continue
}
// Output the value
data[index] = c.table[position]
// Shift the table and restore the value in front
copy(c.table[1:], c.table[:position])
c.table[0] = data[index]
}
}
// Returns an MTF encoder over the provided io.Reader
func Encoder(reader io.Reader) io.Reader {
var enc encoder
enc.table = initial
enc.source = reader
return &enc
}
type encoder struct {
context
source io.Reader
}
// Read and encode data in place
func (c *encoder) Read(output []byte) (count int, err error) {
count, err = c.source.Read(output)
c.encode(output[:count])
return count, err
}
// Returns an MTF decoder over the provided io.Reader
func Decoder(reader io.Reader) io.Reader {
var dec decoder
dec.table = initial
dec.source = reader
return &dec
}
type decoder struct {
context
source io.Reader
}
// Read and decode data in place
func (c *decoder) Read(output []byte) (count int, err error) {
count, err = c.source.Read(output)
c.decode(output[:count])
return count, err
}
|
Modified src/0dev.org/encoding/mtf/mtf_test.go
from [efb3f6ccdb]
to [8e70ad85db].
1 2 3 4 5 6 7 8 9 | package mtf import ( diff "0dev.org/diff" "bytes" "io" "testing" ) | | | < | | > | > | < < < | < < < | | < | | | | | | < | | > | > > > > > > > | | | > > > > > > | > > > > > > > > > > > > > > | | > | < | | | | | < < > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
package mtf
import (
diff "0dev.org/diff"
"bytes"
"io"
"testing"
)
func TestMTF(t *testing.T) {
var (
data []byte = []byte{1, 1, 0, 0}
input *bytes.Reader = bytes.NewReader(data)
encoder io.Reader = Encoder(input)
decoder io.Reader = Decoder(encoder)
output bytes.Buffer
)
io.Copy(&output, decoder)
processed := output.Bytes()
delta := diff.Diff(diff.D{Len1: len(data), Len2: len(processed),
EqualFunc: func(i, j int) bool { return data[i] == processed[j] }})
if len(delta.Added) > 0 || len(delta.Removed) > 0 {
t.Error("Differences detected ", delta)
}
}
// func TestEncoder(t *testing.T) {
// var (
// input []byte = []byte{1, 1, 0, 0}
// expected []byte = []byte{1, 0, 1, 0}
// buffer bytes.Buffer
// encoder io.Writer = Encoder(&buffer)
// )
// count, err := encoder.Write(input)
// if count != len(input) {
// t.Error("Unexpected write count from encoder", count)
// }
// if err != nil {
// t.Error("Unexpected write error from encoder", err)
// }
// output := buffer.Bytes()
// // Diff the output against the expected result
// delta := diff.Diff(diff.D{Len1: len(expected), Len2: len(output),
// EqualFunc: func(i, j int) bool { return expected[i] == output[j] }})
// if len(delta.Added) > 0 || len(delta.Removed) > 0 {
// t.Error("Differences detected ", delta)
// }
// }
// func TestDecoder(t *testing.T) {
// var (
// input []byte = []byte{1, 0, 1, 0}
// expected []byte = []byte{1, 1, 0, 0}
// output []byte = make([]byte, 4)
// reader *bytes.Reader = bytes.NewReader(input)
// decoder io.Reader = Decoder(reader)
// )
// count, err := decoder.Read(output)
// if count != len(output) {
// t.Error("Unexpected read count from decoder", count)
// }
// if err != nil {
// t.Error("Unexpected read error from decoder", err)
// }
// // Diff the output against the expected result
// delta := diff.Diff(diff.D{Len1: len(expected), Len2: len(output),
// EqualFunc: func(i, j int) bool { return expected[i] == output[j] }})
// if len(delta.Added) > 0 || len(delta.Removed) > 0 {
// t.Error("Differences detected ", delta)
// }
// }
|