Example #1
0
func (this *BWT) Forward(src, dst []byte) (uint, uint, error) {
	count := int(this.size)

	if this.size == 0 {
		count = len(src)
	}

	if count < 2 {
		if count == 1 {
			dst[0] = src[0]
		}

		return uint(count), uint(count), nil
	}

	if this.saAlgo == nil {
		var err error

		if this.saAlgo, err = util.NewDivSufSort(); err != nil {
			return 0, 0, err
		}
	} else {
		this.saAlgo.Reset()
	}

	// Compute suffix array
	sa := this.saAlgo.ComputeSuffixArray(src[0:count])
	i := 0

	for i < count {
		// Found primary index
		if sa[i] == 0 {
			break
		}

		dst[i] = src[sa[i]-1]
		i++
	}

	dst[i] = src[count-1]
	this.SetPrimaryIndex(uint(i))
	i++

	for i < count {
		dst[i] = src[sa[i]-1]
		i++
	}

	return uint(count), uint(count), nil
}
Example #2
0
func (this *BWTS) Forward(src, dst []byte) (uint, uint, error) {
	count := int(this.size)

	if this.size == 0 {
		count = len(src)
	}

	if count < 2 {
		if count == 1 {
			dst[0] = src[0]
		}

		return uint(count), uint(count), nil
	}

	// Lazy dynamic memory allocations
	if len(this.buffer) < count {
		this.buffer = make([]int, count)
	}

	if this.saAlgo == nil {
		var err error

		if this.saAlgo, err = util.NewDivSufSort(); err != nil {
			return 0, 0, err
		}
	} else {
		this.saAlgo.Reset()
	}

	// Compute suffix array
	sa := this.saAlgo.ComputeSuffixArray(src[0:count])

	// Aliasing
	isa := this.buffer

	for i := 0; i < count; i++ {
		isa[sa[i]] = i
	}

	min := isa[0]
	idxMin := 0

	for i := 1; i < count && min > 0; i++ {
		if isa[i] >= min {
			continue
		}

		headRank := this.moveLyndonWordHead(sa, src, count, idxMin, i-idxMin, min)
		refRank := headRank

		for j := i - 1; j > idxMin; j-- {
			// iterate through the new lyndon word from end to start
			testRank := isa[j]
			startRank := testRank

			for testRank < count-1 {
				nextRankStart := sa[testRank+1]

				if j > nextRankStart || src[j] != src[nextRankStart] || refRank < isa[nextRankStart+1] {
					break
				}

				sa[testRank] = nextRankStart
				isa[nextRankStart] = testRank
				testRank++
			}

			sa[testRank] = j
			isa[j] = testRank
			refRank = testRank

			if startRank == testRank {
				break
			}
		}

		min = isa[i]
		idxMin = i
	}

	min = count

	for i := 0; i < count; i++ {
		if isa[i] >= min {
			dst[isa[i]] = src[i-1]
			continue
		}

		if min < count {
			dst[min] = src[i-1]
		}

		min = isa[i]
	}

	dst[0] = src[count-1]
	return uint(count), uint(count), nil
}