ivanovrvl / fast_ring

Fast and flexible implementation of the ring buffer algorithm in Go but simply portable on any another language.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Fast ring buffer

Fast and flexible implementation of the ring buffer algorithm in Go but simply portable to any another language. It provides add/remove to/from the tail or head of the ring buffer by single element or by coping array of elements. Access to any element or to any continiuos subset (slice) of the ring buffer is prodived as well.

It is based on the following abstractions:

  • Buffer - the ring buffer. It can be any fixed size indexed collection. Index [0..length-1] is preferred.
  • Ring - a logical representation of the ring buffer over Buffer having Content between tail anf head.
  • Range - a continiuos subset (slice) of the Content. It is consint of one or two Segments of the Buffer.
  • Segment - a continiuos subset (slice) of the Buffer
	// Initialization
	ring := Ring{ // the ring provider
		Size:          100,
		CheckOverflow: false, // will override tail if needed
	}
	ringBuffer := make([]byte, ring.Size) // the ring buffer

	// Usage

	// add one byte to the head
	ringBuffer[ring.AddToHead()] = 1
	fmt.Println("Len", ring.Length())

	// add one byte to the tail
	ringBuffer[ring.AddToTail()] = 100
	fmt.Println("Len", ring.Length())

	// add bytes to the head
	var toWrite1 = [8]byte{2, 3, 4, 5, 6, 7, 8, 9}
	// using loop over segments
	for _, seg := range ring.AddRangeToHead(len(toWrite1)) {
		copy(ringBuffer[seg.Start:seg.Start+seg.Length], toWrite1[seg.RStart:seg.RStart+seg.Length])
	}

	// add bytes to the tail
	var toWrite2 = [3]byte{103, 102, 101}
	// without loop
	seg := ring.AddRangeToTail(len(toWrite2))
	copy(ringBuffer[seg[0].Start:seg[0].Start+seg[0].Length], toWrite2[0:seg[0].Length])
	if seg[1].Length > 0 {
		copy(ringBuffer[seg[1].Start:seg[1].Start+seg[1].Length], toWrite2[seg[1].Length:])
	}

	// iterate over all elements from the tail to head
	for _, seg := range ring.GetRangeFromTail(ring.Length()) {
		for i := 0; i < seg.Length; i++ {
			fmt.Print(" ", ringBuffer[seg.Start+i])
		}
	}
	fmt.Println()

	// read bytes from the tail
	var toRead [10]byte
	for _, seg := range ring.RemoveRangeFromTail(len(toRead)) {
		copy(toRead[seg.RStart:seg.RStart+seg.Length], ringBuffer[seg.Start:seg.Start+seg.Length])
	}
	fmt.Println(toRead)
	fmt.Println("Len", ring.Length())

	// read one byte from the tail
	fmt.Println(ringBuffer[ring.RemoveFromTail()])
	// read one byte from the head
	fmt.Println(ringBuffer[ring.RemoveFromHead()])
	// read one more from the head
	fmt.Println(ringBuffer[ring.RemoveFromHead()])

	fmt.Println("Len", ring.Length())

About

Fast and flexible implementation of the ring buffer algorithm in Go but simply portable on any another language.


Languages

Language:Go 100.0%