diff --git a/homeworks/10_allocator/README.md b/homeworks/10_allocator/README.md new file mode 100644 index 0000000..0e778c1 --- /dev/null +++ b/homeworks/10_allocator/README.md @@ -0,0 +1,10 @@ +Домашнее задание №10 + +В домашнем задании нужно реализовать функцию дефрагментации памяти. + +Дефрагментацию нужно будет проводить `in-place` (без копирования в новое место), а также вместе с обновлением указателей, которые уже ссылаются на фрагментированные участки памяти. Указатели будут указывать только на однобайтовые значения в памяти, а различать свободные и занятые участки памяти нужно будет при помощи указателей, но не при помощи значений в памяти. Поподробнее о дефрагментации можно прочитать [здесь](https://ru.wikipedia.org/wiki/Дефрагментация). + +Для выполнения домашнего задания подготовлен шаблон кода и основные тесты, которую помогут проверить корректность реализации конвертации. Шаблона доступен по [ссылке](https://github.com/Balun-courses/deep_go/blob/master/homework/allocator/homework_test.go). + +Задание со звездочкой +Выполнять необязательно, но можно попробовать реализовать функцию дефрагментации, которая будет уметь работать не только с однобайтовыми значениями в памяти, но еще и с 2-4-8 байтовыми значениями. \ No newline at end of file diff --git a/homeworks/10_allocator/homework_test.go b/homeworks/10_allocator/homework_test.go new file mode 100644 index 0000000..eed791b --- /dev/null +++ b/homeworks/10_allocator/homework_test.go @@ -0,0 +1,108 @@ +package main + +import ( + "reflect" + "testing" + "unsafe" + + "github.com/stretchr/testify/assert" +) + +// go test -v homework_test.go + +func Defragment(memory []byte, pointers []unsafe.Pointer) { + if len(memory) == 0 || len(pointers) == 0 { + return + } + + base := uintptr(unsafe.Pointer(&memory[0])) + + ptrmap := make(map[int]int) + for i, v := range pointers { + ptrmap[int(uintptr(v)-base)] = i + } + + write := 0 + for read := range memory { + if i, ok := ptrmap[read]; ok { + if write != read { + memory[write] = memory[read] + } + pointers[i] = unsafe.Pointer(&memory[write]) + write++ + } + } + + // Clear tail data + for i := write; i < len(memory); i++ { + memory[i] = 0 + } +} + +func TestDefragmentation(t *testing.T) { + var fragmentedMemory = []byte{ + 0xF3, 0x00, 0x00, 0x00, + 0x00, 0xF2, 0x00, 0x00, + 0x00, 0x00, 0xF1, 0x00, + 0x00, 0x00, 0x00, 0xF4, + } + + var fragmentedPointers = []unsafe.Pointer{ + unsafe.Pointer(&fragmentedMemory[10]), + unsafe.Pointer(&fragmentedMemory[5]), + unsafe.Pointer(&fragmentedMemory[0]), + unsafe.Pointer(&fragmentedMemory[15]), + } + + var defragmentedPointers = []unsafe.Pointer{ + unsafe.Pointer(&fragmentedMemory[2]), + unsafe.Pointer(&fragmentedMemory[1]), + unsafe.Pointer(&fragmentedMemory[0]), + unsafe.Pointer(&fragmentedMemory[3]), + } + + var defragmentedMemory = []byte{ + 0xF3, 0xF2, 0xF1, 0xF4, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + } + + Defragment(fragmentedMemory, fragmentedPointers) + assert.True(t, reflect.DeepEqual(defragmentedMemory, fragmentedMemory)) + assert.True(t, reflect.DeepEqual(defragmentedPointers, fragmentedPointers)) +} + +func TestDefragmentationBasic(t *testing.T) { + var fragmentedMemory = []byte{ + 0xFF, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0xFF, + } + + var fragmentedPointers = []unsafe.Pointer{ + unsafe.Pointer(&fragmentedMemory[0]), + unsafe.Pointer(&fragmentedMemory[5]), + unsafe.Pointer(&fragmentedMemory[10]), + unsafe.Pointer(&fragmentedMemory[15]), + } + + var defragmentedPointers = []unsafe.Pointer{ + unsafe.Pointer(&fragmentedMemory[0]), + unsafe.Pointer(&fragmentedMemory[1]), + unsafe.Pointer(&fragmentedMemory[2]), + unsafe.Pointer(&fragmentedMemory[3]), + } + + var defragmentedMemory = []byte{ + 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + } + + Defragment(fragmentedMemory, fragmentedPointers) + assert.True(t, reflect.DeepEqual(defragmentedMemory, fragmentedMemory)) + assert.True(t, reflect.DeepEqual(defragmentedPointers, fragmentedPointers)) +}