Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 55 additions & 25 deletions Lesson_2/homework_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,48 +9,79 @@ import (

// go test -v homework_test.go

type CircularQueue struct {
values []int
// need to implement
type QueueType interface {
int | int8 | int16 | int32 | int64
}

func NewCircularQueue(size int) CircularQueue {
return CircularQueue{} // need to implement
type CircularQueue[T QueueType] struct {
values []T
front int
rear int
size int
}

func (q *CircularQueue) Push(value int) bool {
return false // need to implement
func NewCircularQueue[T QueueType](size int) CircularQueue[T] {
if size <= 0 {
return CircularQueue[T]{}
}
return CircularQueue[T]{
values: make([]T, size),
}
}

func (q *CircularQueue) Pop() bool {
return false // need to implement
func (q *CircularQueue[T]) Push(value T) bool {
if q.Full() {
return false
}

q.values[q.rear] = value
q.rear = (q.rear + 1) % len(q.values)
q.size++
return true
}

func (q *CircularQueue[T]) Pop() bool {
if q.Empty() {
return false
}

q.front = (q.front + 1) % len(q.values)
q.size--
return true
}

func (q *CircularQueue) Front() int {
return -1 // need to implement
func (q *CircularQueue[T]) Front() T {
if q.Empty() {
return -1
}
return q.values[q.front]
}

func (q *CircularQueue) Back() int {
return -1 // need to implement
func (q *CircularQueue[T]) Back() T {
if q.Empty() {
return -1
}
return q.values[(q.rear-1+len(q.values))%len(q.values)]
}

func (q *CircularQueue) Empty() bool {
return false // need to implement
func (q *CircularQueue[T]) Empty() bool {
return q.size == 0
}

func (q *CircularQueue) Full() bool {
return false // need to implement
func (q *CircularQueue[T]) Full() bool {
return q.size == len(q.values)
}

func TestCircularQueue(t *testing.T) {
const queueSize = 3
queue := NewCircularQueue(queueSize)

queue := NewCircularQueue[int](queueSize)

assert.True(t, queue.Empty())
assert.False(t, queue.Full())

assert.Equal(t, -1, queue.Front())
assert.Equal(t, -1, queue.Back())
assert.Equal(t, int(-1), queue.Front())
assert.Equal(t, int(-1), queue.Back())
assert.False(t, queue.Pop())

assert.True(t, queue.Push(1))
Expand All @@ -63,18 +94,17 @@ func TestCircularQueue(t *testing.T) {
assert.False(t, queue.Empty())
assert.True(t, queue.Full())

assert.Equal(t, 1, queue.Front())
assert.Equal(t, 3, queue.Back())
assert.Equal(t, int(1), queue.Front())
assert.Equal(t, int(3), queue.Back())

assert.True(t, queue.Pop())
assert.False(t, queue.Empty())
assert.False(t, queue.Full())
assert.True(t, queue.Push(4))

assert.True(t, reflect.DeepEqual([]int{4, 2, 3}, queue.values))

assert.Equal(t, 2, queue.Front())
assert.Equal(t, 4, queue.Back())
assert.Equal(t, int(2), queue.Front())
assert.Equal(t, int(4), queue.Back())

assert.True(t, queue.Pop())
assert.True(t, queue.Pop())
Expand Down
74 changes: 74 additions & 0 deletions Lesson_3/homework_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package main

import (
"reflect"
"testing"
"unsafe"

"github.com/stretchr/testify/assert"
)

type COWBuffer struct {
data []byte
refs *int
// need to implement
}

func NewCOWBuffer(data []byte) COWBuffer {
return COWBuffer{} // need to implement
}

func (b *COWBuffer) Clone() COWBuffer {
return COWBuffer{} // need to implement
}

func (b *COWBuffer) Close() {
// need to implement
}

func (b *COWBuffer) Update(index int, value byte) bool {
return false // need to implement
}

func (b *COWBuffer) String() string {
return "" // need to implement
}

func TestCOWBuffer(t *testing.T) {
data := []byte{'a', 'b', 'c', 'd'}
buffer := NewCOWBuffer(data)
defer buffer.Close()

copy1 := buffer.Clone()
copy2 := buffer.Clone()

assert.Equal(t, unsafe.SliceData(data), unsafe.SliceData(buffer.data))
assert.Equal(t, unsafe.SliceData(buffer.data), unsafe.SliceData(copy1.data))
assert.Equal(t, unsafe.SliceData(copy1.data), unsafe.SliceData(copy2.data))

assert.True(t, (*byte)(unsafe.SliceData(data)) == unsafe.StringData(buffer.String()))
assert.True(t, (*byte)(unsafe.StringData(buffer.String())) == unsafe.StringData(copy1.String()))
assert.True(t, (*byte)(unsafe.StringData(copy1.String())) == unsafe.StringData(copy2.String()))

assert.True(t, buffer.Update(0, 'g'))
assert.False(t, buffer.Update(-1, 'g'))
assert.False(t, buffer.Update(4, 'g'))

assert.True(t, reflect.DeepEqual([]byte{'g', 'b', 'c', 'd'}, buffer.data))
assert.True(t, reflect.DeepEqual([]byte{'a', 'b', 'c', 'd'}, copy1.data))
assert.True(t, reflect.DeepEqual([]byte{'a', 'b', 'c', 'd'}, copy2.data))

assert.NotEqual(t, unsafe.SliceData(buffer.data), unsafe.SliceData(copy1.data))
assert.Equal(t, unsafe.SliceData(copy1.data), unsafe.SliceData(copy2.data))

copy1.Close()

previous := copy2.data
copy2.Update(0, 'f')
current := copy2.data

// 1 reference - don't need to copy buffer during update
assert.Equal(t, unsafe.SliceData(previous), unsafe.SliceData(current))

copy2.Close()
}