Skip to content

Commit

Permalink
Improve table (#3620)
Browse files Browse the repository at this point in the history
* Optimize table initialization performance

* Optimize code

* rename
  • Loading branch information
matyhtf authored Sep 3, 2020
1 parent 678e4b8 commit 7eb7bd4
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 65 deletions.
2 changes: 1 addition & 1 deletion core-tests/src/memory/table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class table_t {

bool set(const std::string &key, const row_t &value) {
swTableRow *_rowlock = nullptr;
swTableRow *row = swTableRow_set(table, key.c_str(), key.length(), &_rowlock);
swTableRow *row = swTableRow_set(table, key.c_str(), key.length(), &_rowlock, nullptr);
if (!row) {
swTableRow_unlock(_rowlock);
return false;
Expand Down
24 changes: 22 additions & 2 deletions include/swoole_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include <vector>
#include <unordered_map>

#define SW_TABLE_DEBUG 1

typedef uint32_t swTable_string_length_t;

struct swTableRow {
Expand Down Expand Up @@ -62,6 +64,11 @@ enum swTableColumn_type {
SW_TABLE_STRING,
};

enum swTable_flag {
SW_TABLE_FLAG_NEW_ROW = 1,
SW_TABLE_FLAG_CONFLICT = 1u << 1,
};

struct swTableColumn {
enum swTableColumn_type type;
uint32_t size;
Expand All @@ -87,6 +94,8 @@ struct swTableColumn {
break;
}
}

void clear(swTableRow *row);
};

struct swTable {
Expand All @@ -112,14 +121,20 @@ struct swTable {
pid_t create_pid;

void *memory;

#ifdef SW_TABLE_DEBUG
int conflict_count;
int insert_count;
int conflict_max_level;
#endif
};

swTable *swTable_new(uint32_t rows_size, float conflict_proportion);
size_t swTable_get_memory_size(swTable *table);
int swTable_create(swTable *table);
void swTable_free(swTable *table);
bool swTableColumn_add(swTable *table, const std::string &name, enum swTableColumn_type type, size_t size);
swTableRow *swTableRow_set(swTable *table, const char *key, uint16_t keylen, swTableRow **rowlock);
swTableRow *swTableRow_set(swTable *table, const char *key, uint16_t keylen, swTableRow **rowlock, int *out_flags);
swTableRow *swTableRow_get(swTable *table, const char *key, uint16_t keylen, swTableRow **rowlock);

void swTable_iterator_rewind(swTable *table);
Expand Down Expand Up @@ -204,8 +219,13 @@ static sw_inline void swTableRow_set_value(swTableRow *row, swTableColumn *col,
swWarn("[key=%s,field=%s]string value is too long", row->key, col->name.c_str());
vlen = col->size - sizeof(swTable_string_length_t);
}
if (value == nullptr) {
vlen = 0;
}
memcpy(row->data + col->index, &vlen, sizeof(swTable_string_length_t));
memcpy(row->data + col->index + sizeof(swTable_string_length_t), value, vlen);
if (vlen > 0) {
memcpy(row->data + col->index + sizeof(swTable_string_length_t), value, vlen);
}
break;
}
}
53 changes: 32 additions & 21 deletions src/memory/table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,8 @@

#include "swoole_table.h"

//#define SW_TABLE_DEBUG 1
#define SW_TABLE_USE_PHP_HASH

#ifdef SW_TABLE_DEBUG
static int conflict_count = 0;
static int insert_count = 0;
static int conflict_max_level = 0;
#endif

static inline void swTable_check_key_length(uint16_t *keylen) {
if (*keylen >= SW_TABLE_KEY_SIZE) {
*keylen = SW_TABLE_KEY_SIZE - 1;
Expand Down Expand Up @@ -149,11 +142,11 @@ int swTable_create(swTable *table) {

void swTable_free(swTable *table) {
#ifdef SW_TABLE_DEBUG
printf("swoole_table: size=%d, conflict_count=%d, conflict_max_level=%d, insert_count=%d\n",
printf("swoole_table: size=%ld, conflict_count=%d, conflict_max_level=%d, insert_count=%d\n",
table->size,
conflict_count,
conflict_max_level,
insert_count);
table->conflict_count,
table->conflict_max_level,
table->insert_count);
#endif

auto i = table->column_map->begin();
Expand Down Expand Up @@ -248,20 +241,24 @@ swTableRow *swTableRow_get(swTable *table, const char *key, uint16_t keylen, swT
}

static inline void swTableRow_init(swTable *table, swTableRow *new_row, const char *key, int keylen) {
sw_memset_zero(new_row, sizeof(swTableRow) + table->item_size);
sw_memset_zero(new_row, sizeof(swTableRow));
memcpy(new_row->key, key, keylen);
new_row->key[keylen] = '\0';
new_row->key_len = keylen;
new_row->active = 1;
sw_atomic_fetch_add(&(table->row_num), 1);
#ifdef SW_TABLE_DEBUG
table->insert_count++;
#endif
}

swTableRow *swTableRow_set(swTable *table, const char *key, uint16_t keylen, swTableRow **rowlock) {
swTableRow *swTableRow_set(swTable *table, const char *key, uint16_t keylen, swTableRow **rowlock, int *out_flags) {
swTable_check_key_length(&keylen);

swTableRow *row = swTable_hash(table, key, keylen);
*rowlock = row;
swTableRow_lock(row);
int _out_flags = 0;

#ifdef SW_TABLE_DEBUG
int _conflict_level = 0;
Expand All @@ -274,34 +271,36 @@ swTableRow *swTableRow_set(swTable *table, const char *key, uint16_t keylen, swT
} else if (row->next == nullptr) {
table->lock.lock(&table->lock);
swTableRow *new_row = (swTableRow *) table->pool->alloc(table->pool, 0);

#ifdef SW_TABLE_DEBUG
conflict_count++;
if (_conflict_level > conflict_max_level) {
conflict_max_level = _conflict_level;
table->conflict_count++;
if (_conflict_level > table->conflict_max_level) {
table->conflict_max_level = _conflict_level;
}

#endif
table->lock.unlock(&table->lock);
if (!new_row) {
return nullptr;
}
swTableRow_init(table, new_row, key, keylen);
_out_flags |= SW_TABLE_FLAG_NEW_ROW;
row->next = new_row;
row = new_row;
break;
} else {
row = row->next;
_out_flags |= SW_TABLE_FLAG_CONFLICT;
#ifdef SW_TABLE_DEBUG
_conflict_level++;
#endif
}
}
} else {
#ifdef SW_TABLE_DEBUG
insert_count++;
#endif
swTableRow_init(table, row, key, keylen);
_out_flags |= SW_TABLE_FLAG_NEW_ROW;
}

if (out_flags) {
*out_flags = _out_flags;
}

return row;
Expand Down Expand Up @@ -367,3 +366,15 @@ int swTableRow_del(swTable *table, const char *key, uint16_t keylen) {

return SW_OK;
}

void swTableColumn::clear(swTableRow *row) {
if (type == SW_TABLE_STRING) {
swTableRow_set_value(row, this, nullptr, 0);
} else if (type == SW_TABLE_FLOAT) {
double _value = 0;
swTableRow_set_value(row, this, &_value, 0);
} else {
long _value = 0;
swTableRow_set_value(row, this, &_value, 0);
}
}
Loading

0 comments on commit 7eb7bd4

Please sign in to comment.