Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
xphoenix committed Sep 12, 2018
0 parents commit c92e50b
Show file tree
Hide file tree
Showing 578 changed files with 200,272 additions and 0 deletions.
95 changes: 95 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(afina LANGUAGES C CXX)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Werror -fPIC")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
set(CMAKE_THREAD_PREFER_PTHREAD)

set(CMAKE_THREAD_LIBS_INIT "-lpthread")
set(CMAKE_HAVE_THREADS_LIBRARY 1)
set(CMAKE_USE_WIN32_THREADS_INIT 0)
set(CMAKE_USE_PTHREADS_INIT 1)

# If system has ccache - use it
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND)

# Use native optimizations, for example fast crc32
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_OPT_ARCH_NATIVE_SUPPORTED)
if (COMPILER_OPT_ARCH_NATIVE_SUPPORTED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native")
endif()

##############################################################################
# Dependencies
##############################################################################
## GTest
set(BUILD_GTEST ON CACHE BOOL "Builds the googletest subproject")
set(BUILD_GMOCK ON CACHE BOOL "Builds the googlemock subproject")
set(gtest_disable_pthreads ON CACHE BOOL "Disable uses of pthreads in gtest.")
add_subdirectory(third-party/googletest-release-1.8.0)

## Logging
add_subdirectory(third-party/spdlog-0.13.0)

## Stack traces
add_subdirectory(third-party/backward-cpp)

## Command line arguments parsing
set(CXXOPTS_BUILD_TESTS OFF CACHE BOOL "Set to ON to build examples")
set(CXXOPTS_BUILD_EXAMPLES OFF CACHE BOOL "Set to ON to build examples")
add_subdirectory(third-party/cxxopts-1.4.3)

##############################################################################
# Setup build system
##############################################################################
# Generate version information
IF (NOT AFINA_VERSION)
include(GetGitRevisionDescription)
git_local_changes(AFINA_VERSION_DIRTY)
git_describe(AFINA_VERSION --long --tags --match "v[0-9]*" --abbrev=4)
ENDIF()

# major.minor.patch part of version
MESSAGE(STATUS "Version: " ${AFINA_VERSION} )
if ("${AFINA_VERSION}" MATCHES "^v[0-9]+\\.[0-9]+\\.[0-9]+")
string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${AFINA_VERSION}")
string(REGEX REPLACE "^v[0-9]+\\.([0-9]+)\\..*" "\\1" VERSION_MINOR "${AFINA_VERSION}")
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${AFINA_VERSION}")
else()
message(FATAL_ERROR "Version has wrong format, check major/minor/patch parts of version")
endif()

# additional git part of version
if ("${AFINA_VERSION}" MATCHES "^v[0-9]+\\.[0-9]+\\.[0-9]+-[0-9]+-[a-zA-Z0-9]+")
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+-([0-9]+).*" "\\1" VERSION_COMMITS "${AFINA_VERSION}")
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+-[0-9]+-(.*)" "\\1" VERSION_SHA1 "${AFINA_VERSION}")
else()
message(WARNING "Version has no full git info")
set(VERSION_COMMITS "")
set(VERSION_SHA1 "")
endif()

MESSAGE( STATUS "VERSION_MAJOR: " ${VERSION_MAJOR} )
MESSAGE( STATUS "VERSION_MINOR: " ${VERSION_MINOR} )
MESSAGE( STATUS "VERSION_PATCH: " ${VERSION_PATCH} )
MESSAGE( STATUS "VERSION_COMMITS: " ${VERSION_COMMITS} )
MESSAGE( STATUS "VERSION_SHA1: " ${VERSION_SHA1} )
MESSAGE( STATUS "VERSION_DIRTY: " ${AFINA_VERSION_DIRTY} )


##############################################################################
# Sources
##############################################################################
## Build services
add_subdirectory(src)

## Build tests
enable_testing()
add_subdirectory(test)
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# afina
Simple caching server

Проект создан для курса по многопоточному программированию в Техносфере

# Telegram
https://t.me/spheremt

# Components
Сервер состоит из компонент, каждый в виде отдельной статической библиотеки:
- Allocator (include/afina/allocator/, src/allocator): менеджер памяти
- Storage (include/afina/Storage.h, src/storage): хранилище данных
- Execute (include/afina/execute/, src/execute/): комманды, сервер создает экземпляры комманд на основе сообщений из сети и применяет их над заданным хранилищем
- Network (src/network/): сетевой слой, реализует подмножество memcached текстового протокола

# How to build
Для сборки нужен cmake >= 3.0.1 и gcc, так же система сборки использует ccache если последний найден в системе.
```
[user@domain afina] mkdir build
[user@domain afina] cd build
[user@domain build] cmake -DCMAKE_BUILD_TYPE=Debug ..
[user@domain build] make
```

# Сервер:
```
[user@domain build] ./src/afina
```

Поддерживает следующий опции:
- --network <uv, block> какую использовать реализацию сети
- *uv*: демонстрационную на libuv
- *block*: блокирующая (домашка)
- --storage <map_global> какую реализацию хранилища использовать
- *map_global*: на основе std::map с глобальным локом (домашка)

Вот так можно отправить комманды:
```
echo -n -e "set foo 0 0 6\r\nfooval\r\n" | nc localhost 8080
```
обратите внимание на -e и -n

# Tests
```
make runAllocatorTests && ./test/allocator/runAllocatorTests - собрать и запустить тесты аллокатора
make runExecuteTests && ./test/execute/runExecuteTests - собрать и запустить тесты комманд
make runProtocolTests && ./test/protocol/runProtocolTests - собрать и запустить тесты парсера memcached протокола
make runNetworkTests && ./test/network/runNetworkTests - собрать и запустить тесты сетевой подсистемы
make runStorageTests && ./test/storage/runStorageTests - собрать и запустить тесты хранилиза данных
```
47 changes: 47 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# На следующий год
Тут что нужно поменять к следующему году, по зметкам студентов и личным наблюдениям

## Лекция 1
- Все таки написать текст лекции, а то получилось слишком сумбурно :(
- Вставить слайдов про архетектуру процессора, кэши, и.т.д. Рассказать про
про Hyper Threading, подробнее про потоки исполнения

*Домашка*:
- Добавить слайдов про аллокаторы:
-- Оценки по по колличеству аллокаций памяти (помнится NASA report был какой-то)
-- Типы аллокаторов (general, slab, e.t.c)
- Интерфейс привести к стандартному для C++, вместо C'ого
-- Вот про это конкретно подумать, а то там шаблоны и магия местами...С другой стороны, нигде ВООБЩЕ нет внятного описания про то, как
-- в С++ делать свои аллокаторы - полезно рассказать
- Выбрать 2 конкретные схемы для аллокатора (с учетом многопоточности. G1 & slab?)
-- Сделать слайды для пояснения алгоритмов
-- Для каждого написать полуготовую реализацию (народ жалуется на множество частных случаев, которые долго кодить)
-- Отдать студентам на реализацию


## Лекция 2
Пока нет feedback'а

*Домашка*:
Студенты говорят слишком простая, особенно по сравнению с аллокатором.
- Написать шаблон LRU, реализовать основной алгоритм и структуры данных
- Дать реализовать интерйес map и итераторы на основе написанного алгоритма
- Не забыть про лекцию по lock free

## Лекция 3
Пока нет feedback'а

*Домашка*:
Видимо выбрали слишком простую. Нужно еще что-то, кроме демонизации
- Как насчет graceful restart? Тогда нужно чтобы уже IPC и сеть были
- Сигналы между тредами - вот хорошая идея, например epoll будить и делать балансировку сокетов между epoll потоками через локальные очереди

## Лекция 4
Пока нет feedback'а

*Домашка*:
- AHTUNG: так как про mutex не рассказывали еще, то тяжело сделать отслеживания потоков, соответственно тяжело дожидаться, когда все потоки
отработают (читай соединения закроются)
-- Перести лекцию по примитивам синхронизации В САМОЕ НАЧАЛО, вообще 1ой сделать!
-- Аллокатор можно вообще в самый конец вынести, и сделать только slab, все равно другой в этой задаче не нужен
-- Slab, кстати, можно хорошо сделать на LockFree (как у tarantool arena->slab_cache->mempool)
173 changes: 173 additions & 0 deletions cmake/Modules/ECMEnableSanitizers.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
#.rst:
# ECMEnableSanitizers
# -------------------
#
# Enable compiler sanitizer flags.
#
# The following sanitizers are supported:
#
# - Address Sanitizer
# - Memory Sanitizer
# - Thread Sanitizer
# - Leak Sanitizer
# - Undefined Behaviour Sanitizer
#
# All of them are implemented in Clang, depending on your version, and
# there is an work in progress in GCC, where some of them are currently
# implemented.
#
# This module will check your current compiler version to see if it
# supports the sanitizers that you want to enable
#
# Usage
# =====
#
# Simply add::
#
# include(ECMEnableSanitizers)
#
# to your ``CMakeLists.txt``. Note that this module is included in
# KDECompilerSettings, so projects using that module do not need to also
# include this one.
#
# The sanitizers are not enabled by default. Instead, you must set
# ``ECM_ENABLE_SANITIZERS`` (either in your ``CMakeLists.txt`` or on the
# command line) to a semicolon-separated list of sanitizers you wish to enable.
# The options are:
#
# - address
# - memory
# - thread
# - leak
# - undefined
#
# The sanitizers "address", "memory" and "thread" are mutually exclusive. You
# cannot enable two of them in the same build.
#
# "leak" requires the "address" sanitizer.
#
# .. note::
#
# To reduce the overhead induced by the instrumentation of the sanitizers, it
# is advised to enable compiler optimizations (``-O1`` or higher).
#
# Example
# =======
#
# This is an example of usage::
#
# mkdir build
# cd build
# cmake -DECM_ENABLE_SANITIZERS='address;leak;undefined' ..
#
# .. note::
#
# Most of the sanitizers will require Clang. To enable it, use::
#
# -DCMAKE_CXX_COMPILER=clang++
#
# Since 1.3.0.

#=============================================================================
# Copyright 2014 Mathieu Tarral <[email protected]>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# MACRO check_compiler_version
#-----------------------------
macro (check_compiler_version gcc_required_version clang_required_version)
if (
(
CMAKE_CXX_COMPILER_ID MATCHES "GNU"
AND
CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${gcc_required_version}
)
OR
(
CMAKE_CXX_COMPILER_ID MATCHES "Clang"
AND
CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${clang_required_version}
)
)
# error !
message(FATAL_ERROR "You ask to enable the sanitizer ${CUR_SANITIZER},
but your compiler ${CMAKE_CXX_COMPILER_ID} version ${CMAKE_CXX_COMPILER_VERSION}
does not support it !
You should use at least GCC ${gcc_required_version} or Clang ${clang_required_version}
(99.99 means not implemented yet)")
endif ()
endmacro ()

# MACRO check_compiler_support
#------------------------------
macro (enable_sanitizer_flags sanitize_option)
if (${sanitize_option} MATCHES "address")
check_compiler_version("4.8" "3.1")
set(XSAN_COMPILE_FLAGS "-fsanitize=address -D__SANITIZE_ADDRESS__ -fno-omit-frame-pointer -fno-optimize-sibling-calls")
set(XSAN_LINKER_FLAGS "asan")
elseif (${sanitize_option} MATCHES "thread")
check_compiler_version("4.8" "3.1")
set(XSAN_COMPILE_FLAGS "-fsanitize=thread")
set(XSAN_LINKER_FLAGS "tsan")
elseif (${sanitize_option} MATCHES "memory")
check_compiler_version("99.99" "3.1")
set(XSAN_COMPILE_FLAGS "-fsanitize=memory")
elseif (${sanitize_option} MATCHES "leak")
check_compiler_version("4.9" "3.4")
set(XSAN_COMPILE_FLAGS "-fsanitize=leak")
set(XSAN_LINKER_FLAGS "lsan")
elseif (${sanitize_option} MATCHES "undefined")
check_compiler_version("4.9" "3.1")
set(XSAN_COMPILE_FLAGS "-fsanitize=undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls")
else ()
message(FATAL_ERROR "Compiler sanitizer option \"${sanitize_option}\" not supported.")
endif ()
endmacro ()

if (ECM_ENABLE_SANITIZERS)
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# for each element of the ECM_ENABLE_SANITIZERS list
foreach ( CUR_SANITIZER ${ECM_ENABLE_SANITIZERS} )
# lowercase filter
string(TOLOWER ${CUR_SANITIZER} CUR_SANITIZER)
# check option and enable appropriate flags
enable_sanitizer_flags ( ${CUR_SANITIZER} )
# TODO: GCC will not link pthread library if enabled ASan
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${XSAN_COMPILE_FLAGS}" )
endif()
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${XSAN_COMPILE_FLAGS}" )
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
link_libraries(${XSAN_LINKER_FLAGS})
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
string(REPLACE "-Wl,--no-undefined" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
string(REPLACE "-Wl,--no-undefined" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}")
endif ()
endforeach()
else()
message(STATUS "Tried to enable sanitizers (-DECM_ENABLE_SANITIZERS=${ECM_ENABLE_SANITIZERS}), \
but compiler (${CMAKE_CXX_COMPILER_ID}) does not have sanitizer support")
endif()
endif()
Loading

0 comments on commit c92e50b

Please sign in to comment.