URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [compress/] [bzip2/] [move_to_front.go] - Rev 747
Compare with Previous | Blame | View Log
// Copyright 2011 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package bzip2// moveToFrontDecoder implements a move-to-front list. Such a list is an// efficient way to transform a string with repeating elements into one with// many small valued numbers, which is suitable for entropy encoding. It works// by starting with an initial list of symbols and references symbols by their// index into that list. When a symbol is referenced, it's moved to the front// of the list. Thus, a repeated symbol ends up being encoded with many zeros,// as the symbol will be at the front of the list after the first access.type moveToFrontDecoder struct {// Rather than actually keep the list in memory, the symbols are stored// as a circular, double linked list with the symbol indexed by head// at the front of the list.symbols []bytenext []uint8prev []uint8head uint8}// newMTFDecoder creates a move-to-front decoder with an explicit initial list// of symbols.func newMTFDecoder(symbols []byte) *moveToFrontDecoder {if len(symbols) > 256 {panic("too many symbols")}m := &moveToFrontDecoder{symbols: symbols,next: make([]uint8, len(symbols)),prev: make([]uint8, len(symbols)),}m.threadLinkedList()return m}// newMTFDecoderWithRange creates a move-to-front decoder with an initial// symbol list of 0...n-1.func newMTFDecoderWithRange(n int) *moveToFrontDecoder {if n > 256 {panic("newMTFDecoderWithRange: cannot have > 256 symbols")}m := &moveToFrontDecoder{symbols: make([]uint8, n),next: make([]uint8, n),prev: make([]uint8, n),}for i := 0; i < n; i++ {m.symbols[i] = byte(i)}m.threadLinkedList()return m}// threadLinkedList creates the initial linked-list pointers.func (m *moveToFrontDecoder) threadLinkedList() {if len(m.symbols) == 0 {return}m.prev[0] = uint8(len(m.symbols) - 1)for i := 0; i < len(m.symbols)-1; i++ {m.next[i] = uint8(i + 1)m.prev[i+1] = uint8(i)}m.next[len(m.symbols)-1] = 0}func (m *moveToFrontDecoder) Decode(n int) (b byte) {// Most of the time, n will be zero so it's worth dealing with this// simple case.if n == 0 {return m.symbols[m.head]}i := m.headfor j := 0; j < n; j++ {i = m.next[i]}b = m.symbols[i]m.next[m.prev[i]] = m.next[i]m.prev[m.next[i]] = m.prev[i]m.next[i] = m.headm.prev[i] = m.prev[m.head]m.next[m.prev[m.head]] = im.prev[m.head] = im.head = ireturn}// First returns the symbol at the front of the list.func (m *moveToFrontDecoder) First() byte {return m.symbols[m.head]}
