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
2 changes: 2 additions & 0 deletions 05_hw/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vs
out
22 changes: 19 additions & 3 deletions 05_hw/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.12)
project(stack)

add_library(stack stack.c)
add_library(stack src/stack.c)
add_library(stack::library ALIAS stack)

add_executable(main main.c)
add_executable(main "src/main.c")
target_link_libraries(main stack)

# sanitizer setup
if (NOT CMAKE_BUILD_TYPE STREQUAL "Release")
target_compile_options(main PRIVATE -fsanitize=address -MD)
target_link_options(main PRIVATE)
endif()


# tests setup
add_subdirectory(test)
enable_testing()
add_test(tests test/tests)

# benchmark setup
add_subdirectory(benchmark)
26 changes: 26 additions & 0 deletions 05_hw/CMakeSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"configurations": [
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "clang_cl_x86" ],
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": ""
},
{
"name": "x64-Clang-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "clang_cl_x64" ]
}
]
}
16 changes: 8 additions & 8 deletions 05_hw/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@

Необходимо привести код в порядок.

* Исправить ошибки;
* Покрыть код тестами;
* Проверить покрытие кода тестами (убедиться, что все функции и условия протестированы);
* Выбрать статический анализатор и запустить его (исправить ошибки, если будут);
* Запустить тесты с санитайзерами (исправить ошибки, если будут);
* Для базовых функций (push / pop) написать бенчмарки;
* Изучить возможности Github Actions и настроить CI для тестирования (*).
- Исправить ошибки;
- Покрыть код тестами;
- Проверить покрытие кода тестами (убедиться, что все функции и условия протестированы);
- Выбрать статический анализатор и запустить его (исправить ошибки, если будут);
- Запустить тесты с санитайзерами (исправить ошибки, если будут);
- Для базовых функций (push / pop) написать бенчмарки;
- Изучить возможности Github Actions и настроить CI для тестирования (\*).

Во время рефакторинга разрешается изменять не только код функций, но и их c сигнатуры,
если это будет оправдано с точки зрения использования/тестирования этих функций.

Решение - Pull Request с исправлением. Желательно разбивать изменения на атомарные коммиты
с целью повышения качества ревью и ускорения получения фидбека.

(*) - необязательное задание.
(\*) - необязательное задание.
5 changes: 5 additions & 0 deletions 05_hw/benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.10)
project(benchmark)

add_executable(benchmark benchmark.cpp)
target_link_libraries(benchmark PRIVATE stack::library)
72 changes: 72 additions & 0 deletions 05_hw/benchmark/benchmark.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include <iostream>
#include <chrono>
#include "../src/stack.h"

class StackBenchmark
{
public:
StackBenchmark(size_t limit) : limit(limit)
{
initStack(&stack);
}

~StackBenchmark()
{
destroyStack(&stack);
}

void run()
{
for (int i = 1; i <= 5; ++i)
{
std::cout << "Run " << i << ":" << std::endl;
benchmarkPush();
benchmarkPop();
std::cout << std::endl;
}
}

private:
Stack stack;
size_t limit;

void benchmarkPush()
{
std::cout << " Pushing " << limit << " elements into the stack" << std::endl;

auto start_time = std::chrono::steady_clock::now();
for (size_t i = 0; i < limit; ++i)
{
push(&stack, 1);
}
auto end_time = std::chrono::steady_clock::now();

auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
std::cout << " Push time: " << elapsed.count() << " ms" << std::endl;
}

void benchmarkPop()
{
std::cout << " Popping " << limit << " elements from the stack" << std::endl;

auto start_time = std::chrono::steady_clock::now();
for (size_t i = 0; i < limit; ++i)
{
pop(&stack);
}
auto end_time = std::chrono::steady_clock::now();

auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
std::cout << " Pop time: " << elapsed.count() << " ms" << std::endl;
}
};

int main()
{
const size_t limit = 10000000;

StackBenchmark benchmark(limit);
benchmark.run();

return 0;
}
28 changes: 17 additions & 11 deletions 05_hw/main.c → 05_hw/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

#include <stdio.h>

int main() {
int main()
{
Stack stack;
initStack(&stack);

push(&stack, 10);
push(&stack, 20);
push(&stack, 30);
const int first = 10;
const int second = 20;
const int third = 30;
push(&stack, first);
push(&stack, second);
push(&stack, third);

printf("After pushing elements:\n");
traverseStack(&stack);
Expand All @@ -18,19 +22,21 @@ int main() {
printf("After popping an element:\n");
traverseStack(&stack);

Node* searchResult = searchByValue(&stack, 20);
if (searchResult != NULL) {
Node *searchResult = searchByValue(&stack, second);
if (searchResult != NULL)
{
printf("Element with value 20 found.\n");
} else {
}
else
{
printf("Element with value 20 not found.\n");
}

Node* topElement = getTop(&stack);
if (topElement != NULL) {
Node *topElement = getTop(&stack);
if (topElement != NULL)
{
printf("Top element: %d\n", topElement->data);
}

return 0;
}


94 changes: 94 additions & 0 deletions 05_hw/src/stack.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include <stdio.h>
#include <stdlib.h>

#include "stack.h"

Node *createNode(int data)
{
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}

void initStack(Stack *stack)
{
stack->top = NULL;
}

void destroyStack(Stack *stack)
{
Node *current = stack->top;
while (current != NULL)
{
Node *tmp = current;
current = current->next;
free(tmp);
}
}

void push(Stack *stack, int data)
{
Node *newNode = createNode(data);
newNode->next = stack->top;
stack->top = newNode;
}

void pop(Stack *stack)
{
Node *temp = stack->top;
stack->top = stack->top->next;
free(temp);
}

Node *searchByValue(Stack *stack, int value)
{
Node *current = stack->top;
while (current != NULL)
{
if (current->data == value)
{
return current;
}
current = current->next;
}
return NULL;
}

Node *searchByIndex(Stack *stack, int index)
{
Node *current = stack->top;
int count = 0;
while (current != NULL)
{
if (count == index)
{
return current;
}
count++;
current = current->next;
}
return NULL;
}

Node *getTop(Stack *stack)
{
return stack->top;
}

void traverseStack(Stack *stack)
{
Node *current = stack->top;
printf("Stack elements: ");
while (current != NULL)
{
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}

bool isEmpty(Stack *stack)
{
return stack->top == NULL;
}
43 changes: 43 additions & 0 deletions 05_hw/src/stack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#pragma once

#include <stdbool.h>

typedef struct Node
{
int data;
struct Node *next;
} Node;

typedef struct Stack
{
Node *top;
} Stack;

#ifdef __cplusplus
extern "C"
{
#endif

Node *createNode(int data);

void initStack(Stack *stack);

void destroyStack(Stack *stack);

void push(Stack *stack, int data);

void pop(Stack *stack);

Node *searchByValue(Stack *stack, int value);

Node *searchByIndex(Stack *stack, int index);

Node *getTop(Stack *stack);

void traverseStack(Stack *stack);

bool isEmpty(Stack *stack);

#ifdef __cplusplus
}
#endif
Loading