Commit 2a3604ad authored by Andreas Schmidt's avatar Andreas Schmidt

Merge branch 'develop' into feature/congestionControl

parents 6c85c247 03ae07ab
Pipeline #3132 passed with stages
in 2 minutes and 11 seconds
......@@ -90,3 +90,19 @@ deploy:pypi:
- echo "password=$PYPI_PASSWORD" >> ~/.pypirc
- python3 setup.py check sdist bdist upload -r on
- rm -vf ~/.pypirc
deploy:profile:
stage: deploy
tags:
- gprof
script:
- ls -lahv
- rm CMakeCache.txt
- CC=gcc-5 CXX=g++-5 cmake . -DGPROF=1
- make
- bash profiling/profile.sh
artifacts:
paths:
- gprof-send.txt
- gprof-recv.txt
expire_in: 30 days
\ No newline at end of file
......@@ -2,16 +2,22 @@ cmake_minimum_required (VERSION 2.8.11)
project (PRRT)
option(PRRT_TESTS "Build tests" OFF)
option(GPROF "Compile with profiler" OFF)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_C_FLAGS "-O2 -Wall -std=gnu11 -D_GNU_SOURCE -fPIC" )
set(CMAKE_C_FLAGS_DEBUG "-O0 -fsanitize=undefined -fsanitize=address -g3" )
set(CMAKE_CXX_FLAGS "-fstack-protector -fstack-protector-all -Wall -std=gnu++11 -D_GNU_SOURCE" )
set(CMAKE_CXX_FLAGS_DEBUG "-O2 -Wall -ggdb" )
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -Wall -ggdb -fsanitize=undefined -fsanitize=address -g3" )
set(CMAKE_CXX_FLAGS_RELEASE "-Os -Wall" )
if(GPROF)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
endif()
find_package (Threads)
find_library(M_LIB m)
......
......@@ -81,6 +81,20 @@ Packet 9
* [PRRT Wiki](https://git.nt.uni-saarland.de/LARN/PRRT/wikis)
* [LARN Project Website](http://larn.systems)
## Citing Us
If you find PRRT useful and incorporate it in your works, we are very happy to hear about it. Please also consider to cite us like this:
```bibtex
@misc{sic2018prrt,
author = {Schmidt, Andreas},
title = {PRRT: Predictably Reliable Real-time Transport},
howpublished={Web page},
url = {http://prrt.larn.systems},
year = {2018}
}
```
## License
[MIT Licence](LICENSE)
#!/usr/bin/env bash
which gprof
run_in() {
(cd $1; ${@:2})
}
to="timeout -s INT 30 "
mkdir -p gprof_send gprof_recv
run_in gprof_recv $to ../receiver -p 5000 -r 4095 -o receiver.csv &
run_in gprof_send $to ../sender -t 127.0.0.1 -p 5000 -r 4095 -o sender.csv
wait
gprof ./receiver gprof_recv/gmon.out > gprof-recv.txt
gprof ./sender gprof_send/gmon.out > gprof-send.txt
rm -r gprof_send gprof_recv
\ No newline at end of file
......@@ -27,5 +27,9 @@ add_executable(time-receiver time-receiver.c)
target_link_libraries(sender LINK_PUBLIC PRRT UTIL ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(receiver LINK_PUBLIC PRRT UTIL ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(time-sender LINK_PUBLIC PRRT UTIL ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(time-receiver LINK_PUBLIC PRRT UTIL ${CMAKE_THREAD_LIBS_INIT})
add_executable(refcount refcount.c)
target_link_libraries(refcount LINK_PUBLIC PRRT UTIL ${CMAKE_THREAD_LIBS_INIT})
......@@ -162,6 +162,10 @@ static void handle_data_packet(PrrtSocket *sock_ptr, PrrtPacket *packet) {
PrrtPacketDeliveryStore_insert(sock_ptr->packetDeliveryStore, packet);
PrrtPacket *reference = PrrtPacket_copy(packet);
// forward to application layer
debug(DEBUG_DATARECEIVER, "Forward: %u", seqno);
PrrtPacketDeliveryStore_insert(sock_ptr->packetDeliveryStore, packet);
PrrtBlock *block = PrrtRepairBlockStore_get_block(sock_ptr->repairBlockStore, baseSequenceNumber);
if (block != NULL) {
......@@ -206,8 +210,9 @@ static void handle_redundancy_packet(PrrtSocket *socket, PrrtPacket *packet) {
PrrtBlock *block = PrrtRepairBlockStore_get_block(socket->repairBlockStore,
redundancyPayload->baseSequenceNumber);
if (block == NULL) {
uint8_t n_cycle[1] = {redundancyPayload->n - redundancyPayload->k};
PrrtCodingConfiguration *codingParams = PrrtCodingConfiguration_create(redundancyPayload->k,
redundancyPayload->n, 0, NULL);
redundancyPayload->n, 1, n_cycle);
block = PrrtBlock_create(codingParams, PrrtSocket_get_matching_coder(socket, codingParams),
redundancyPayload->baseSequenceNumber);
......
......@@ -9,6 +9,7 @@
#include <linux/net_tstamp.h>
#include <assert.h>
#include <sys/ioctl.h>
#include <netdb.h>
#include "../defines.h"
#include "../util/common.h"
#include "../util/dbg.h"
......@@ -141,10 +142,15 @@ bool PrrtSocket_bind(PrrtSocket *s, const char *ipAddress, const uint16_t port)
struct sockaddr_in *address = calloc(1, size);
check_mem(address);
// TODO: Allow DNS names to be passed as ipAddress.
struct hostent *host = gethostbyname(ipAddress);
check(host, "gethostbyname(%s): %s", ipAddress, hstrerror(h_errno));
char buf[16];
unsigned char* addr = (unsigned char*) host->h_addr;
snprintf(buf, 16, "%u.%u.%u.%u", addr[0], addr[1], addr[2], addr[3]);
address->sin_family = AF_INET;
address->sin_addr.s_addr = inet_addr(ipAddress);
address->sin_addr.s_addr = inet_addr(buf);
address->sin_port = htons((uint16_t) (port));
s->address = address;
......
......@@ -6,11 +6,32 @@
PrrtCodingConfiguration *PrrtCodingConfiguration_create(uint8_t k, uint8_t n, uint8_t c, uint8_t *n_cycle)
{
if (n < k) {
PERROR("Invalid parameters: n must be greater or equal k.%s","");
return NULL;
}
uint8_t r = n - k;
if ((r > 0) && (n_cycle == NULL)) {
PERROR("Invalid parameters: n_cycle cannot be NULL if (n-k) != 0.%s","");
return NULL;
}
uint8_t sum = 0;
for (int i = 0; i < c; ++i) {
sum += n_cycle[i];
}
if (sum != r) {
PERROR("Invalid parameters: The elements in n_cycle must sum up to n-k.%s","");
return NULL;
}
PrrtCodingConfiguration *cc = calloc(1, sizeof(PrrtCodingConfiguration));
check_mem(cc);
cc->k = k;
cc->n = n;
cc->r = cc->n - cc->k;
cc->r = r;
cc->c = c;
if(n_cycle != NULL) {
cc->n_cycle = (uint8_t*) realloc(cc->n_cycle, cc->c * sizeof(int8_t));
......
......@@ -22,14 +22,6 @@ static void *decode_redundancy_header(void *dstBuffer, const void *srcBuffer);
static void *decode_feedback_header(void *dstBuffer, const void *srcBuffer);
prrtPacketType_t PrrtPacket_type(PrrtPacket *packet_ptr) {
return (prrtPacketType_t) ((packet_ptr->type_priority >> 4) & 0x0F);
}
uint8_t PrrtPacket_priority(PrrtPacket *packet_ptr) {
return (uint8_t) (packet_ptr->type_priority & 0x0F);
}
prrtPacketLength_t PrrtPacket_size(PrrtPacket *packet_ptr) {
return (prrtPacketLength_t) (packet_ptr->payloadLength + PRRT_PACKET_ENCODED_GENERAL_HEADER_LENGTH);
}
......@@ -92,6 +84,11 @@ int PrrtPacket_print(PrrtPacket *packet_ptr) {
}
PrrtPacket *PrrtPacket_copy(PrrtPacket *original) {
__sync_fetch_and_add(&original->refcount, 1);
return original;
}
PrrtPacket *PrrtPacket_deepcopy(PrrtPacket *original) {
PrrtPacket *newPacket = calloc(1, sizeof(PrrtPacket));
check_mem(newPacket);
void *payload = calloc(1, original->payloadLength);
......@@ -105,6 +102,8 @@ PrrtPacket *PrrtPacket_copy(PrrtPacket *original) {
newPacket->sequenceNumber = original->sequenceNumber;
newPacket->type_priority = original->type_priority;
newPacket->refcount = 1;
return newPacket;
error:
......@@ -122,6 +121,7 @@ create_header(uint8_t priority, prrtSequenceNumber_t seqno, prrtPacketLength_t s
packet->index = index;
packet->sequenceNumber = seqno;
packet->payloadLength = size;
packet->refcount = 1;
return packet;
......@@ -160,8 +160,10 @@ bool PrrtPacket_encode(void *buf_ptr, uint16_t buf_size, PrrtPacket *packet_ptr)
#define PrrtPacketField_encode(payload, buf_ptr, field_t, field, conversion) \
do { \
field_t *ptr = (field_t *) (buf_ptr); \
*ptr = conversion((payload)->field); \
field_t PrrtPacketField_encode_value = conversion((payload)->field); \
/* memcpy to avoid misaligned access.
* The compiler will optimize this into appropriate mov instructions */ \
memcpy(buf_ptr, &PrrtPacketField_encode_value, sizeof(field_t)); \
(buf_ptr) += sizeof(field_t); \
} while (false)
......@@ -215,6 +217,10 @@ void *encode_general_header(void *buf_ptr, const PrrtPacket *packet) {
}
bool PrrtPacket_decode(void *srcBuffer, uint16_t srcBufferSize, PrrtPacket *targetPacket) {
// targetPacket is uninitialized, so we need to set the reference count
targetPacket->refcount = 1;
prrtPacketLength_t payload_len = (prrtPacketLength_t) (srcBufferSize - PRRT_PACKET_ENCODED_GENERAL_HEADER_LENGTH);
targetPacket->type_priority = *(uint8_t *) srcBuffer;
srcBuffer += 1;
......@@ -251,8 +257,11 @@ bool PrrtPacket_decode(void *srcBuffer, uint16_t srcBufferSize, PrrtPacket *targ
#define PrrtPacketField_decode(payload, buf_ptr, field_t, field, conversion) \
do { \
field_t *PrrtPacketField_decode_ptr = (field_t *) (buf_ptr); \
(payload)->field = conversion(*PrrtPacketField_decode_ptr); \
field_t PrrtPacketField_decode_value; \
/* memcpy to avoid misaligned access.
* The compiler will optimize this into appropriate mov instructions */ \
memcpy(&PrrtPacketField_decode_value, buf_ptr, sizeof(field_t)); \
(payload)->field = conversion(PrrtPacketField_decode_value); \
(buf_ptr) += sizeof(field_t); \
} while (false)
......@@ -297,11 +306,17 @@ void *decode_data_header(void *dstBuffer, const void *srcBuffer) {
}
int PrrtPacket_destroy(PrrtPacket *packet) {
if (packet->payload != NULL) {
free(packet->payload);
prrtRefcount_t refcount = __sync_fetch_and_sub(&packet->refcount, 1);
if (refcount > 1) {
return 0;
} else {
if (packet->payload != NULL) {
free(packet->payload);
}
free(packet);
return 0;
}
free(packet);
return 0;
}
PrrtPacket *PrrtPacket_create_data_packet(uint8_t priority, const void *payloadPointer,
......
......@@ -36,6 +36,8 @@ typedef atomic_uint_fast32_t prrtAtomicDeliveryRate_t;
typedef uint32_t prrtByteCount_t;
typedef uint8_t prrtPacketType_t;
typedef uint16_t prrtRefcount_t;
typedef struct prrtIncompleteBlock {
prrtSequenceNumber_t sequenceNumberBase;
uint16_t repairCycleIndex;
......@@ -59,6 +61,8 @@ typedef struct prrtPacket {
prrtTimedelta_t rtt;
struct sockaddr_in sender_addr;
prrtRefcount_t refcount;
} PrrtPacket;
#define PRRT_PACKET_GENERAL_HEADER_SIZE 8
#define PRRT_PACKET_ENCODED_GENERAL_HEADER_LENGTH 4
......@@ -117,9 +121,10 @@ typedef struct prrtPacketFeedbackPayload {
sizeof(prrtSequenceNumber_t) + \
sizeof(prrtPacketType_t) )
prrtPacketType_t PrrtPacket_type(PrrtPacket *packet_ptr);
uint8_t PrrtPacket_priority(PrrtPacket *packet_ptr);
#define PrrtPacket_type(packet_ptr) ((prrtPacketType_t) (((packet_ptr)->type_priority >> 4) & 0x0F))
#define PrrtPacket_priority(packet_ptr) ((uint8_t) (packet_ptr->type_priority & 0x0F))
prrtPacketLength_t PrrtPacket_size(PrrtPacket *packet_ptr);
......@@ -127,6 +132,8 @@ int PrrtPacket_print(PrrtPacket *packet_ptr);
PrrtPacket *PrrtPacket_copy(PrrtPacket *original);
PrrtPacket *PrrtPacket_deepcopy(PrrtPacket *original);
PrrtPacket *PrrtPacket_create_data_packet(uint8_t priority, const void *payloadPointer,
prrtPacketLength_t dataLength, prrtSequenceNumber_t sequenceNumber,
prrtTimedelta_t targetDelay);
......
......@@ -150,7 +150,12 @@ cdef class PrrtSocket:
self._c_socket = cprrt.PrrtSocket_create(maximum_payload_size, target_delay_us)
if thread_pinning:
cprrt.PrrtSocket_enable_thread_pinning(self._c_socket)
cprrt.PrrtSocket_bind(self._c_socket, host.encode("utf8"), port)
if not cprrt.PrrtSocket_bind(self._c_socket, host.encode("utf8"), port):
# PrrtSocket_bind calls PrrtSocket_close on error
# so we need to set _c_socket to NULL because otherwise __dealloc__
# will attempt to call PrrtSocket_close again on the closed socket
self._c_socket = NULL
raise ValueError("PrrtSocket_bind failed")
# Channel Properties
property data_rate_btl_fwd:
......
#include "proto/types/packet.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int prio = 0;
const int seqnum = 1337;
const int timedelta = 0;
int main() {
const char* payload = "just some example payload";
struct prrtPacket *a = PrrtPacket_create_data_packet(prio, payload, strlen(payload), seqnum, timedelta);
printf("refcount(a): %u\n\n", a->refcount);
struct prrtPacket *b = PrrtPacket_copy(a);
printf("refcount(a): %u\nrefcount(b): %u\n\n", a->refcount, b->refcount);
PrrtPacket_destroy(a);
printf("refcount(b): %u\n", b->refcount);
PrrtPacket_destroy(b);
}
......@@ -28,31 +28,70 @@ Bitmap *Bitmap_create(bool initialValue, uint32_t elementCount)
void Bitmap_set_range_0(Bitmap *bitmap, uint32_t start, uint32_t length)
{
uint32_t i = 0;
// TODO: highly inefficient - optimize
for(i = 0; i < length; i++) {
Bitmap_set_0(bitmap, start + i);
}
uint32_t start_byte = start / 32;
uint32_t start_bit = start % 32;
uint32_t end_byte = (start + length) / 32;
uint32_t end_bit = (start + length) % 32;
uint32_t full_mask = ~0u;
if (start_byte == end_byte) {
uint32_t mask = (full_mask << end_bit) ^ (full_mask << start_bit);
bitmap->data[start_byte] ^= (bitmap->data[start_byte] & mask);
} else {
uint32_t start_mask = full_mask << start_bit;
bitmap->data[start_byte] ^= (bitmap->data[start_byte] & start_mask);
for (uint32_t current_byte = start_byte + 1; current_byte < end_byte; ++current_byte) {
bitmap->data[current_byte] = 0;
}
uint32_t end_mask = ~(full_mask << end_bit);
bitmap->data[end_byte] ^= (bitmap->data[end_byte] & end_mask);
}
}
void Bitmap_set_range_1(Bitmap *bitmap, uint32_t start, uint32_t length)
{
uint32_t i = 0;
// TODO: highly inefficient - optimize
for(i = 0; i < length; i++) {
Bitmap_set_1(bitmap, start + i);
}
uint32_t start_byte = start / 32;
uint32_t start_bit = start % 32;
uint32_t end_byte = (start + length) / 32;
uint32_t end_bit = (start + length) % 32;
uint32_t full_mask = ~0u;
if (start_byte == end_byte) {
uint32_t mask = (full_mask << end_bit) ^ (full_mask << start_bit);
bitmap->data[start_byte] |= mask;
} else {
uint32_t start_mask = full_mask << start_bit;
bitmap->data[start_byte] |= start_mask;
for (uint32_t current_byte = start_byte + 1; current_byte < end_byte; ++current_byte) {
bitmap->data[current_byte] = full_mask;
}
uint32_t end_mask = ~(full_mask << end_bit);
bitmap->data[end_byte] |= end_mask;
}
}
uint32_t Bitmap_sum_ones(Bitmap *bitmap, uint32_t start, uint32_t length)
{
uint32_t sum = 0;
uint32_t i = 0;
// TODO: highly inefficient - optimize
for(i = 0; i < length; i++) {
sum += (Bitmap_get(bitmap, start + i) == true);
uint32_t start_byte = start / 32;
uint32_t start_bit = start % 32;
uint32_t end_byte = (start + length) / 32;
uint32_t end_bit = (start + length) % 32;
uint32_t full_mask = ~0u;
if (start_byte == end_byte) {
uint32_t mask = (full_mask << end_bit) ^ (full_mask << start_bit);
return __builtin_popcount(bitmap->data[start_byte] & mask);
} else {
uint32_t start_mask = full_mask << start_bit;
uint32_t sum = __builtin_popcount(bitmap->data[start_byte] & start_mask);
for (uint32_t current_byte = start_byte + 1; current_byte < end_byte; ++current_byte) {
sum += __builtin_popcount(bitmap->data[current_byte]);
}
uint32_t end_mask = ~(full_mask << end_bit);
sum += __builtin_popcount(bitmap->data[end_byte] & end_mask);
return sum;
}
return sum;
}
uint32_t Bitmap_sum_zeros(Bitmap *bitmap, uint32_t start, uint32_t length)
......
......@@ -26,14 +26,14 @@ BITMAP_EXPOSED_FUNCTION bool Bitmap_get(Bitmap *bitmap, uint32_t position)
{
uint32_t byte_offset = position / 32;
uint32_t bit_offset = position % 32;
return (bool) ((bitmap->data[byte_offset] & (1 << bit_offset)) != 0);
return (bool) ((bitmap->data[byte_offset] & (1u << bit_offset)) != 0);
}
BITMAP_EXPOSED_FUNCTION bool Bitmap_set_0(Bitmap *bitmap, uint32_t position)
{
uint32_t byte_offset = position / 32;
uint32_t bit_offset = position % 32;
bitmap->data[byte_offset] &= ~(1 << bit_offset);
bitmap->data[byte_offset] &= ~(1u << bit_offset);
return true;
}
......@@ -41,7 +41,7 @@ BITMAP_EXPOSED_FUNCTION bool Bitmap_set_1(Bitmap *bitmap, uint32_t position)
{
uint32_t byte_offset = position / 32;
uint32_t bit_offset = position % 32;
bitmap->data[byte_offset] |= (1 << bit_offset);
bitmap->data[byte_offset] |= (1u << bit_offset);
return true;
}
......
......@@ -11,7 +11,7 @@ void print_gf(const gf *start, const int len);
void pin_thread_to_core(pthread_attr_t *ap, int core);
#define PERROR(fmt, args...) \
printf("PRRT ERROR: \n" fmt, ## args);
printf("PRRT ERROR (" __FILE__ ":%d)\n" fmt, __LINE__, ## args);
#define PNOTIMPLEMENTED(args) \
printf("NOT IMPLEMENTED: %s\n", args); \
......
......@@ -30,7 +30,7 @@ TEST_F(PrrtBlockTest, VDMCode)
uint8_t length = 3;
PrrtCodingConfiguration* params = PrrtCodingConfiguration_create(k, n, 1, NULL);
PrrtCodingConfiguration* params = PrrtCodingConfiguration_create(k, n, 1, &r);
PrrtCoder *coder = PrrtCoder_create(params);
for(q = 0; q < 4; q++) {
......@@ -86,14 +86,35 @@ TEST_F(PrrtBlockTest, VDMCode)
ASSERT_EQ(4, decFec[3][0]);
ASSERT_EQ(9, decFec[3][1]);
ASSERT_EQ(5, decFec[3][2]);
// free allocated memory
for (i = 0; i < k; ++i) {
free(decFec[i]);
}
free(idx_p);
free(decFec);
for (j = 0; j < r; ++j) {
free(encFec[j]);
}
free(encFec);
free(src[3]);
free(src[2]);
free(src[1]);
free(src[0]);
free(src);
}
PrrtCoder_destroy(coder);
PrrtCodingConfiguration_destroy(params);
}
TEST_F(PrrtBlockTest, EncodeDecode)
{
PrrtCodingConfiguration *cpar = PrrtCodingConfiguration_create(4, 7, 1, NULL);
uint8_t r = 3;
PrrtCodingConfiguration *cpar = PrrtCodingConfiguration_create(4, 7, 1, &r);
PrrtCoder *coder = PrrtCoder_create(cpar);
PrrtBlock *encBlock = PrrtBlock_create(PrrtCodingConfiguration_copy(cpar), PrrtCoder_copy(coder), 1);
......@@ -141,7 +162,7 @@ TEST_F(PrrtBlockTest, EncodeDecode)
PrrtBlock_insert_redundancy_packet(decBlock, redPackets[0]);
PrrtBlock_insert_redundancy_packet(decBlock, redPackets[1]);
PrrtBlock_insert_redundancy_packet(decBlock, redPackets[2]);
PrrtBlock_insert_data_packet(decBlock, packets[3]);
PrrtBlock_insert_data_packet(decBlock, PrrtPacket_copy(packets[3]));
ASSERT_TRUE(PrrtBlock_decode_ready(decBlock));
......@@ -159,17 +180,27 @@ TEST_F(PrrtBlockTest, EncodeDecode)
ASSERT_STREQ(s1, s2);
ASSERT_EQ(refLength, ptrLength);
PrrtPacket_destroy(ptr);
}
PrrtBlock_destroy(encBlock);
PrrtBlock_destroy(decBlock);
PrrtCoder_destroy(coder);
PrrtCodingConfiguration_destroy(cpar);
for (auto packet: packets) {
PrrtPacket_destroy(packet);
}
for (auto packet: refPackets) {
PrrtPacket_destroy(packet);
}
}
TEST_F(PrrtBlockTest, NoCodingConfigured)
{
PrrtCodingConfiguration *cpar = PrrtCodingConfiguration_create(1, 1, 1, NULL);
PrrtCodingConfiguration *cpar = PrrtCodingConfiguration_create(1, 1, 0, NULL);
PrrtCoder* coder = PrrtCoder_create(cpar);
PrrtBlock *encBlock = PrrtBlock_create(PrrtCodingConfiguration_copy(cpar), PrrtCoder_copy(coder), 1);
......@@ -181,9 +212,9 @@ TEST_F(PrrtBlockTest, NoCodingConfigured)
for(uint32_t i = 0; i < 1; i++) {
char data[3];
sprintf(data, "%d", i);
packets[i] = PrrtPacket_create_data_packet(0, data, (prrtPacketLength_t) strlen(data), i + 1, 0);
packets[i] = PrrtPacket_create_data_packet(0, data, (prrtPacketLength_t) strlen(data) + 1, i + 1, 0);
packets[i]->index = (uint8_t) i;
refPackets[i] = PrrtPacket_create_data_packet(0, data, (prrtPacketLength_t) strlen(data), i + 1, 0);
refPackets[i] = PrrtPacket_create_data_packet(0, data, (prrtPacketLength_t) strlen(data) + 1, i + 1, 0);
ASSERT_TRUE(PrrtBlock_insert_data_packet(encBlock, packets[i]));
}
......@@ -200,6 +231,11 @@ TEST_F(PrrtBlockTest, NoCodingConfigured)
uint32_t red_count = List_count(encBlock->redundancyPackets);
ASSERT_EQ(red_count, 0);
for (int i = 0; i < 1; ++i) {
PrrtPacket_destroy(packets[i]);
PrrtPacket_destroy(refPackets[i]);
}
PrrtBlock_destroy(encBlock);
PrrtCoder_destroy(coder);
PrrtCodingConfiguration_destroy(cpar);
......
......@@ -54,12 +54,22 @@ TEST_F(BitmapTest, GetRange)
TEST_F(BitmapTest, SetRange)
{
ASSERT_EQ(5, Bitmap_sum_ones(bitmap, 1, 5));
ASSERT_EQ(0, Bitmap_sum_zeros(bitmap, 1, 5));
Bitmap_set_range(bitmap, 2, 2, false);
ASSERT_FALSE(Bitmap_get(bitmap, 2));
ASSERT_FALSE(Bitmap_get(bitmap, 3));
ASSERT_TRUE(Bitmap_get(bitmap, 4));
ASSERT_EQ(3, Bitmap_sum_ones(bitmap, 1, 5));
ASSERT_EQ(2, Bitmap_sum_zeros(bitmap, 1, 5));
ASSERT_EQ(500, Bitmap_sum_ones(bitmap, 17, 500));
ASSERT_EQ(0, Bitmap_sum_zeros(bitmap, 17, 500));
Bitmap_set_range(bitmap, 2, 300, false);
ASSERT_TRUE(Bitmap_get(bitmap, 1));
for (int i = 2; i < 302; ++i) {
ASSERT_FALSE(Bitmap_get(bitmap, i));
}
ASSERT_TRUE(Bitmap_get(bitmap, 302));
Bitmap_set_range(bitmap, 150, 100, true);
ASSERT_FALSE(Bitmap_get(bitmap, 149));
for (int i = 150; i < 250; ++i) {
ASSERT_TRUE(Bitmap_get(bitmap, i));
}
ASSERT_FALSE(Bitmap_get(bitmap, 250));
ASSERT_EQ(300, Bitmap_sum_ones(bitmap, 1, 500));
ASSERT_EQ(200, Bitmap_sum_zeros(bitmap, 1, 500));
}
......@@ -6,13 +6,20 @@ extern "C" {
class BPlusTreeTest : public ::testing::Test {
protected:
virtual void SetUp() {
void SetUp() override {
root = NULL;
void* p = malloc(sizeof(int));
root = BPTree_insert(root, 1, p);
}
virtual void TearDown() {
void TearDown() override {
List *list = List_create();
BPTree_get_range(root, list, std::numeric_limits<BPTreeKey_t>::min(), std::numeric_limits<BPTreeKey_t>::max());
while (List_count(list) > 0) {
void *p = List_shift(list);
free(p);
}
List_destroy(list);
root = BPTree_destroy(root);
}
......@@ -21,7 +28,10 @@ protected:
};
TEST_F(BPlusTreeTest, InsertDelete) {
void* p = malloc(sizeof(int));
void* p = malloc(sizeof(int)),
*p2 = malloc(sizeof(int)),
*p3 = malloc(sizeof(int));
ASSERT_EQ(BPTree_height(root), 0);
ASSERT_EQ(BPTree_size(root), 1);
......@@ -29,15 +39,17 @@ TEST_F(BPlusTreeTest, InsertDelete) {
ASSERT_EQ(BPTree_height(root), 0);
ASSERT_EQ(BPTree_size(root), 2);
root = BPTree_insert(root, 3, p);
root = BPTree_insert(root, 3, p2);
ASSERT_EQ(BPTree_height(root), 0);
ASSERT_EQ(BPTree_size(root), 3);
root = BPTree_insert(root, 4, p);
root = BPTree_insert(root, 4, p3);
ASSERT_EQ(BPTree_height(root), 1);
ASSERT_EQ(BPTree_size(root), 4);
free(BPTree_get(root, 3));
root = BPTree_delete(root, 3);
ASSERT_EQ(BPTree_height(root), 0);
ASSERT_EQ(BPTree_size(root), 3);
}
......@@ -45,11 +57,13 @@ TEST_F(BPlusTreeTest, InsertDelete) {
TEST_F(BPlusTreeTest, InsertAndFind) {
void* p = malloc(sizeof(int));
void* p2 = malloc(sizeof(int));
void* p3 = malloc(sizeof(int));
root = BPTree_insert(root, 2, p);
root = BPTree_insert(root, 3, p2);
root = BPTree_insert(root, 4, p);