...

Source file src/pkg/compress/bzip2/move_to_front.go

     1	// Copyright 2011 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package bzip2
     6	
     7	// moveToFrontDecoder implements a move-to-front list. Such a list is an
     8	// efficient way to transform a string with repeating elements into one with
     9	// many small valued numbers, which is suitable for entropy encoding. It works
    10	// by starting with an initial list of symbols and references symbols by their
    11	// index into that list. When a symbol is referenced, it's moved to the front
    12	// of the list. Thus, a repeated symbol ends up being encoded with many zeros,
    13	// as the symbol will be at the front of the list after the first access.
    14	type moveToFrontDecoder []byte
    15	
    16	// newMTFDecoder creates a move-to-front decoder with an explicit initial list
    17	// of symbols.
    18	func newMTFDecoder(symbols []byte) moveToFrontDecoder {
    19		if len(symbols) > 256 {
    20			panic("too many symbols")
    21		}
    22		return moveToFrontDecoder(symbols)
    23	}
    24	
    25	// newMTFDecoderWithRange creates a move-to-front decoder with an initial
    26	// symbol list of 0...n-1.
    27	func newMTFDecoderWithRange(n int) moveToFrontDecoder {
    28		if n > 256 {
    29			panic("newMTFDecoderWithRange: cannot have > 256 symbols")
    30		}
    31	
    32		m := make([]byte, n)
    33		for i := 0; i < n; i++ {
    34			m[i] = byte(i)
    35		}
    36		return moveToFrontDecoder(m)
    37	}
    38	
    39	func (m moveToFrontDecoder) Decode(n int) (b byte) {
    40		// Implement move-to-front with a simple copy. This approach
    41		// beats more sophisticated approaches in benchmarking, probably
    42		// because it has high locality of reference inside of a
    43		// single cache line (most move-to-front operations have n < 64).
    44		b = m[n]
    45		copy(m[1:], m[:n])
    46		m[0] = b
    47		return
    48	}
    49	
    50	// First returns the symbol at the front of the list.
    51	func (m moveToFrontDecoder) First() byte {
    52		return m[0]
    53	}
    54	

View as plain text