Skip to content

Commit

Permalink
refactor: use std::vector instead of bespoke Array class
Browse files Browse the repository at this point in the history
  • Loading branch information
ckerr committed Jun 30, 2023
1 parent 9cb9f9c commit d9d3754
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 132 deletions.
2 changes: 2 additions & 0 deletions utp_hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
* THE SOFTWARE.
*/

#include <assert.h>

#include "utp_hash.h"
#include "utp_types.h"

Expand Down
60 changes: 28 additions & 32 deletions utp_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,21 +667,22 @@ struct UTPSocket {
size_t get_packet_size() const;
};

void removeSocketFromAckList(UTPSocket *conn)
static void removeSocketFromAckList(UTPSocket *conn)
{
if (conn->ida >= 0)
{
UTPSocket *last = conn->ctx->ack_sockets[conn->ctx->ack_sockets.GetCount() - 1];
auto const ida = conn->ida;
if (ida < 0)
return;

assert(last->ida < (int)(conn->ctx->ack_sockets.GetCount()));
assert(conn->ctx->ack_sockets[last->ida] == last);
last->ida = conn->ida;
conn->ctx->ack_sockets[conn->ida] = last;
conn->ida = -1;
auto& acks = conn->ctx->ack_sockets;
assert(acks[ida]->ida == ida);

// Decrease the count
conn->ctx->ack_sockets.SetCount(conn->ctx->ack_sockets.GetCount() - 1);
}
// fast-remove `conn` from acks by swapping w/last and resizing.
// update `ida` index for both swapped sockets.
// note the steps need to be safe even when conn == acks.back()
std::swap(acks[ida], acks.back());
acks[ida]->ida = ida;
acks.resize(acks.size() - 1U);
conn->ida = -1;
}

static void utp_register_sent_packet(utp_context *ctx, size_t length)
Expand Down Expand Up @@ -715,7 +716,8 @@ void UTPSocket::schedule_ack()
#if UTP_DEBUG_LOGGING
log(UTP_LOG_DEBUG, "schedule_ack");
#endif
ida = ctx->ack_sockets.Append(this);
ida = ctx->ack_sockets.size();
ctx->ack_sockets.push_back(this);
} else {
#if UTP_DEBUG_LOGGING
log(UTP_LOG_DEBUG, "schedule_ack: already in list");
Expand Down Expand Up @@ -2923,12 +2925,9 @@ int utp_process_udp(utp_context *ctx, const byte *buffer, size_t len, const stru
if (flags != ST_SYN) {
ctx->current_ms = utp_call_get_milliseconds(ctx, NULL);

for (size_t i = 0; i < ctx->rst_info.GetCount(); i++) {
if ((ctx->rst_info[i].connid == id) &&
(ctx->rst_info[i].addr == addr) &&
(ctx->rst_info[i].ack_nr == seq_nr))
{
ctx->rst_info[i].timestamp = ctx->current_ms;
for (auto& info : ctx->rst_info) {
if ((info.connid == id) && (info.addr == addr) && (info.ack_nr == seq_nr)) {
info.timestamp = ctx->current_ms;

#if UTP_DEBUG_LOGGING
ctx->log(UTP_LOG_DEBUG, NULL, "recv not sending RST to non-SYN (stored)");
Expand All @@ -2938,7 +2937,7 @@ int utp_process_udp(utp_context *ctx, const byte *buffer, size_t len, const stru
}
}

if (ctx->rst_info.GetCount() > RST_INFO_LIMIT) {
if (ctx->rst_info.size() > RST_INFO_LIMIT) {

#if UTP_DEBUG_LOGGING
ctx->log(UTP_LOG_DEBUG, NULL, "recv not sending RST to non-SYN (limit at %u stored)", (uint)ctx->rst_info.GetCount());
Expand All @@ -2951,11 +2950,7 @@ int utp_process_udp(utp_context *ctx, const byte *buffer, size_t len, const stru
ctx->log(UTP_LOG_DEBUG, NULL, "recv send RST to non-SYN (%u stored)", (uint)ctx->rst_info.GetCount());
#endif

RST_Info &r = ctx->rst_info.Append();
r.addr = addr;
r.connid = id;
r.ack_nr = seq_nr;
r.timestamp = ctx->current_ms;
ctx->rst_info.emplace_back(addr, id, seq_nr, ctx->current_ms);

UTPSocket::send_rst(ctx, addr, id, seq_nr, utp_call_get_random(ctx, NULL));
return 1;
Expand Down Expand Up @@ -3280,7 +3275,7 @@ void utp_issue_deferred_acks(utp_context *ctx)
assert(ctx);
if (!ctx) return;

for (size_t i = 0; i < ctx->ack_sockets.GetCount(); i++) {
for (size_t i = 0; i < ctx->ack_sockets.size(); i++) {
UTPSocket *conn = ctx->ack_sockets[i];
conn->send_ack();
i--;
Expand All @@ -3300,15 +3295,16 @@ void utp_check_timeouts(utp_context *ctx)

ctx->last_check = ctx->current_ms;

for (size_t i = 0; i < ctx->rst_info.GetCount(); i++) {
if ((int)(ctx->current_ms - ctx->rst_info[i].timestamp) >= RST_INFO_TIMEOUT) {
ctx->rst_info.MoveUpLast(i);
auto& infos = ctx->rst_info;
for (size_t i = 0; i < infos.size(); i++) {
if ((int)(ctx->current_ms - infos[i].timestamp) >= RST_INFO_TIMEOUT) {
// fast-remove from `infos` by swapping w/last and resizing
std::swap(infos[i], infos.back());
infos.resize(infos.size() - 1U);
i--;
}
}
if (ctx->rst_info.GetCount() != ctx->rst_info.GetAlloc()) {
ctx->rst_info.Compact();
}
infos.shrink_to_fit();

utp_hash_iterator_t it;
UTPSocketKeyData* keyData;
Expand Down
16 changes: 14 additions & 2 deletions utp_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <assert.h>
#include <stdio.h>

#include <vector>

#include "utp.h"
#include "utp_callbacks.h"
#include "utp_templates.h"
Expand Down Expand Up @@ -59,6 +61,16 @@ enum bandwidth_type_t {
#endif

struct PACKED_ATTRIBUTE RST_Info {
RST_Info() = default;

RST_Info(PackedSockAddr _addr, uint32 _connid, uint16 _ack_nr, uint64 _timestamp)
: addr{ _addr }
, connid{ _connid }
, ack_nr{ _ack_nr }
, timestamp{ _timestamp }
{
}

PackedSockAddr addr;
uint32 connid;
uint16 ack_nr;
Expand Down Expand Up @@ -117,8 +129,8 @@ struct struct_utp_context {
uint64 current_ms;
utp_context_stats context_stats;
UTPSocket *last_utp_socket;
Array<UTPSocket*> ack_sockets;
Array<RST_Info> rst_info;
std::vector<UTPSocket*> ack_sockets;
std::vector<RST_Info> rst_info;
UTPSocketHT *utp_sockets;
size_t target_delay;
size_t opt_sndbuf;
Expand Down
98 changes: 0 additions & 98 deletions utp_templates.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#define __TEMPLATES_H__

#include "utp_types.h"
#include <assert.h>

#if defined(POSIX)
/* Allow over-writing FORCEINLINE from makefile because gcc 3.4.4 for buffalo
Expand Down Expand Up @@ -95,101 +94,4 @@ typedef big_endian<uint16> uint16_big;

template<typename T> static inline void zeromem(T *a, size_t count = 1) { memset(a, 0, count * sizeof(T)); }

typedef int SortCompareProc(const void *, const void *);

template<typename T> static FORCEINLINE void QuickSortT(T *base, size_t num, int (*comp)(const T *, const T *)) { qsort(base, num, sizeof(T), (SortCompareProc*)comp); }


// WARNING: The template parameter MUST be a POD type!
template <typename T, size_t minsize = 16> class Array {
protected:
T *mem;
size_t alloc,count;

public:
Array(size_t init) { Init(init); }
Array() { Init(); }
~Array() { Free(); }

void inline Init() { mem = NULL; alloc = count = 0; }
void inline Init(size_t init) { Init(); if (init) Resize(init); }
size_t inline GetCount() const { return count; }
size_t inline GetAlloc() const { return alloc; }
void inline SetCount(size_t c) { count = c; }

inline T& operator[](size_t offset) { assert(offset ==0 || offset<alloc); return mem[offset]; }
inline const T& operator[](size_t offset) const { assert(offset ==0 || offset<alloc); return mem[offset]; }

void inline Resize(size_t a) {
if (a == 0) { free(mem); Init(); }
else { mem = (T*)realloc(mem, (alloc=a) * sizeof(T)); }
}

void Grow() { Resize(::max<size_t>(minsize, alloc * 2)); }

inline size_t Append(const T &t) {
if (count >= alloc) Grow();
size_t r=count++;
mem[r] = t;
return r;
}

T inline &Append() {
if (count >= alloc) Grow();
return mem[count++];
}

void inline Compact() {
Resize(count);
}

void inline Free() {
free(mem);
Init();
}

void inline Clear() {
count = 0;
}

bool inline MoveUpLast(size_t index) {
assert(index < count);
size_t c = --count;
if (index != c) {
mem[index] = mem[c];
return true;
}
return false;
}

bool inline MoveUpLastExist(const T &v) {
return MoveUpLast(LookupElementExist(v));
}

size_t inline LookupElement(const T &v) const {
for(size_t i = 0; i != count; i++)
if (mem[i] == v)
return i;
return (size_t) -1;
}

bool inline HasElement(const T &v) const {
return LookupElement(v) != -1;
}

typedef int SortCompareProc(const T *a, const T *b);

void Sort(SortCompareProc* proc, size_t start, size_t end) {
QuickSortT(&mem[start], end - start, proc);
}

void Sort(SortCompareProc* proc, size_t start) {
Sort(proc, start, count);
}

void Sort(SortCompareProc* proc) {
Sort(proc, 0, count);
}
};

#endif //__TEMPLATES_H__

0 comments on commit d9d3754

Please sign in to comment.