iodine 0.7.2 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/exe/iodine +1 -0
- data/ext/iodine/extconf.rb +1 -1
- data/ext/iodine/fio.c +51 -49
- data/ext/iodine/fio.h +84 -141
- data/ext/iodine/fio_cli.c +11 -16
- data/ext/iodine/fiobj_hash.c +14 -17
- data/ext/iodine/http.c +4 -8
- data/ext/iodine/iodine.c +52 -7
- data/ext/iodine/iodine_caller.c +11 -9
- data/ext/iodine/iodine_connection.c +10 -15
- data/ext/iodine/iodine_http.c +7 -9
- data/ext/iodine/iodine_json.c +7 -11
- data/ext/iodine/iodine_pubsub.c +2 -3
- data/ext/iodine/iodine_store.c +15 -15
- data/ext/iodine/iodine_tcp.c +1 -1
- data/ext/iodine/redis_engine.c +1 -2
- data/ext/iodine/websockets.c +7 -9
- data/lib/iodine.rb +4 -0
- data/lib/iodine/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf89fce9c0e4b457fb88d8871bc61e81517fdb9bfe227627394f8c06753829c1
|
4
|
+
data.tar.gz: 20f66f4a8fe102b9c9e59ee2eda6ed27e0f65e880a42c953554df8b3ead6ca11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4967888c32c01259d933576876d07d66612ac71689dfb93ae8dad8e08675a4908e654d76ebb9e44cf4f9fb87b657a068fb97520648b89df6daae2bfe4a191f55
|
7
|
+
data.tar.gz: 11170c43eece7c6a6627408e40c5f5751abde9b5e330ba97c8f19c6643e0cf842d70c7a3dfaaf2b18b6fb30894cf48563d2d56ffc9cc70fa58809eb5e30c2983
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,12 @@ Please notice that this change log contains changes for upcoming releases as wel
|
|
6
6
|
|
7
7
|
## Changes:
|
8
8
|
|
9
|
+
#### Change log v.0.7.3
|
10
|
+
|
11
|
+
**Fix**: (facil.io) updating facil.io fixes a channel name memory leak fixed in facil.io's edge version.
|
12
|
+
|
13
|
+
**Updated**: Improved logging for server data, allowing for log silencing.
|
14
|
+
|
9
15
|
#### Change log v.0.7.2
|
10
16
|
|
11
17
|
**Updated**: updated the logging for HTTP services startup, to minimize log clutter.
|
data/exe/iodine
CHANGED
@@ -32,6 +32,7 @@ Available options:
|
|
32
32
|
-maxbd Maximum Mb per HTTP message (max body size). Default: 50Mb.
|
33
33
|
-maxms Maximum Bytes per Websocket message. Default: 250Kb.
|
34
34
|
-ping WebSocket / SSE ping interval in seconds. Default: 40 seconds.
|
35
|
+
-logging Server level logging (not HTTP), values between 0..5. Defaults to 4.
|
35
36
|
<filename> Defaults to: config.ru
|
36
37
|
|
37
38
|
Example:
|
data/ext/iodine/extconf.rb
CHANGED
@@ -29,7 +29,7 @@ else
|
|
29
29
|
puts 'using an unknown (old?) compiler... who knows if this will work out... we hope.'
|
30
30
|
end
|
31
31
|
|
32
|
-
$CFLAGS = "-std=c11 -O2 -Wall #{ENV['CFLAGS']}"
|
32
|
+
$CFLAGS = "-std=c11 -O2 -Wall -DFIO_PRINT_STATE=0 #{ENV['CFLAGS']}"
|
33
33
|
RbConfig::MAKEFILE_CONFIG['CC'] = $CC = ENV['CC'] if ENV['CC']
|
34
34
|
RbConfig::MAKEFILE_CONFIG['CPP'] = $CPP = ENV['CPP'] if ENV['CPP']
|
35
35
|
|
data/ext/iodine/fio.c
CHANGED
@@ -467,7 +467,8 @@ void fio_uuid_link(intptr_t uuid, void *obj, void (*on_close)(void *obj)) {
|
|
467
467
|
fio_lock(&uuid_data(uuid).sock_lock);
|
468
468
|
if (!uuid_is_valid(uuid))
|
469
469
|
goto locked_invalid;
|
470
|
-
fio_uuid_links_overwrite(&uuid_data(uuid).links, (uintptr_t)obj, on_close
|
470
|
+
fio_uuid_links_overwrite(&uuid_data(uuid).links, (uintptr_t)obj, on_close,
|
471
|
+
NULL);
|
471
472
|
fio_unlock(&uuid_data(uuid).sock_lock);
|
472
473
|
return;
|
473
474
|
locked_invalid:
|
@@ -485,7 +486,8 @@ int fio_uuid_unlink(intptr_t uuid, void *obj) {
|
|
485
486
|
if (!uuid_is_valid(uuid))
|
486
487
|
goto locked_invalid;
|
487
488
|
/* default object comparison is always true */
|
488
|
-
int ret =
|
489
|
+
int ret =
|
490
|
+
fio_uuid_links_remove(&uuid_data(uuid).links, (uintptr_t)obj, NULL, NULL);
|
489
491
|
if (ret)
|
490
492
|
errno = ENOTCONN;
|
491
493
|
fio_unlock(&uuid_data(uuid).sock_lock);
|
@@ -3071,6 +3073,7 @@ static void fio_pubsub_on_fork(void);
|
|
3071
3073
|
|
3072
3074
|
static void fio_mem_destroy(void);
|
3073
3075
|
static void __attribute__((destructor)) fio_lib_destroy(void) {
|
3076
|
+
uint8_t add_eol = fio_is_master();
|
3074
3077
|
fio_data->active = 0;
|
3075
3078
|
fio_state_callback_force(FIO_CALL_AT_EXIT);
|
3076
3079
|
fio_state_callback_clear_all();
|
@@ -3081,7 +3084,8 @@ static void __attribute__((destructor)) fio_lib_destroy(void) {
|
|
3081
3084
|
/* memory library destruction must be last */
|
3082
3085
|
fio_mem_destroy();
|
3083
3086
|
FIO_LOG_DEBUG("(%d) facil.io resources released, exit complete.", getpid());
|
3084
|
-
|
3087
|
+
if (add_eol)
|
3088
|
+
fprintf(stderr, "\n"); /* add EOL to logs (logging adds EOL before text */
|
3085
3089
|
}
|
3086
3090
|
|
3087
3091
|
/* Called within a child process after it starts. */
|
@@ -3477,6 +3481,7 @@ void fio_start FIO_IGNORE_MACRO(struct fio_start_args args) {
|
|
3477
3481
|
fio_data->workers = (uint16_t)args.workers;
|
3478
3482
|
fio_data->threads = (uint16_t)args.threads;
|
3479
3483
|
fio_data->active = 1;
|
3484
|
+
fio_data->is_worker = 0;
|
3480
3485
|
|
3481
3486
|
fio_state_callback_force(FIO_CALL_PRE_START);
|
3482
3487
|
|
@@ -3899,10 +3904,10 @@ static void fio_listen_on_startup(void *pr_) {
|
|
3899
3904
|
fio_listen_protocol_s *pr = pr_;
|
3900
3905
|
fio_attach(pr->uuid, &pr->pr);
|
3901
3906
|
if (pr->port_len)
|
3902
|
-
|
3907
|
+
FIO_LOG_DEBUG("(%d) started listening on port %s", getpid(), pr->port);
|
3903
3908
|
else
|
3904
|
-
|
3905
|
-
|
3909
|
+
FIO_LOG_DEBUG("(%d) started listening on Unix Socket at %s", getpid(),
|
3910
|
+
pr->addr);
|
3906
3911
|
}
|
3907
3912
|
|
3908
3913
|
static void fio_listen_on_close(intptr_t uuid, fio_protocol_s *pr_) {
|
@@ -4303,7 +4308,7 @@ static inline channel_s *fio_filter_dup_lock_internal(channel_s *ch,
|
|
4303
4308
|
uint64_t hashed,
|
4304
4309
|
fio_collection_s *c) {
|
4305
4310
|
fio_lock(&c->lock);
|
4306
|
-
ch =
|
4311
|
+
ch = fio_ch_set_insert(&c->channels, hashed, ch);
|
4307
4312
|
fio_str_dup(&ch->id);
|
4308
4313
|
fio_lock(&ch->lock);
|
4309
4314
|
fio_unlock(&c->lock);
|
@@ -4440,7 +4445,7 @@ void fio_unsubscribe(subscription_s *s) {
|
|
4440
4445
|
fio_lock(&c->lock);
|
4441
4446
|
/* test again within lock */
|
4442
4447
|
if (fio_ls_embd_is_empty(&ch->subscriptions)) {
|
4443
|
-
fio_ch_set_remove(&c->channels, hashed, ch);
|
4448
|
+
fio_ch_set_remove(&c->channels, hashed, ch, NULL);
|
4444
4449
|
removed = 1;
|
4445
4450
|
}
|
4446
4451
|
fio_unlock(&c->lock);
|
@@ -4520,13 +4525,14 @@ void fio_pubsub_attach(fio_pubsub_engine_s *engine) {
|
|
4520
4525
|
/** Detaches an engine, so it could be safely destroyed. */
|
4521
4526
|
void fio_pubsub_detach(fio_pubsub_engine_s *engine) {
|
4522
4527
|
fio_lock(&fio_postoffice.engines.lock);
|
4523
|
-
fio_engine_set_remove(&fio_postoffice.engines.set, (uintptr_t)engine, engine
|
4528
|
+
fio_engine_set_remove(&fio_postoffice.engines.set, (uintptr_t)engine, engine,
|
4529
|
+
NULL);
|
4524
4530
|
fio_unlock(&fio_postoffice.engines.lock);
|
4525
4531
|
}
|
4526
4532
|
|
4527
4533
|
/** Returns true (1) if the engine is attached to the system. */
|
4528
4534
|
int fio_pubsub_is_attached(fio_pubsub_engine_s *engine) {
|
4529
|
-
fio_pubsub_engine_s
|
4535
|
+
fio_pubsub_engine_s *addr;
|
4530
4536
|
fio_lock(&fio_postoffice.engines.lock);
|
4531
4537
|
addr = fio_engine_set_find(&fio_postoffice.engines.set, (uintptr_t)engine,
|
4532
4538
|
engine);
|
@@ -4612,8 +4618,8 @@ void fio_message_metadata_callback_set(fio_msg_metadata_fn callback,
|
|
4612
4618
|
fio_meta_set_insert(&fio_postoffice.meta.set, (uintptr_t)callback,
|
4613
4619
|
callback);
|
4614
4620
|
else
|
4615
|
-
fio_meta_set_remove(&fio_postoffice.meta.set, (uintptr_t)callback,
|
4616
|
-
|
4621
|
+
fio_meta_set_remove(&fio_postoffice.meta.set, (uintptr_t)callback, callback,
|
4622
|
+
NULL);
|
4617
4623
|
fio_unlock(&fio_postoffice.meta.lock);
|
4618
4624
|
}
|
4619
4625
|
|
@@ -4637,12 +4643,11 @@ void *fio_message_metadata(fio_msg_s *msg, intptr_t type_id) {
|
|
4637
4643
|
static channel_s *fio_channel_find_dup_internal(fio_str_s *s, uint64_t hashed,
|
4638
4644
|
fio_collection_s *c) {
|
4639
4645
|
fio_lock(&c->lock);
|
4640
|
-
channel_s
|
4641
|
-
if (!
|
4646
|
+
channel_s *ch = fio_ch_set_find(&c->channels, hashed, (channel_s *)s);
|
4647
|
+
if (!ch) {
|
4642
4648
|
fio_unlock(&c->lock);
|
4643
4649
|
return NULL;
|
4644
4650
|
}
|
4645
|
-
channel_s *ch = *pch;
|
4646
4651
|
fio_str_dup((fio_str_s *)ch);
|
4647
4652
|
fio_unlock(&c->lock);
|
4648
4653
|
return ch;
|
@@ -4778,8 +4783,7 @@ static void fio_publish2process(fio_msg_internal_s *m) {
|
|
4778
4783
|
}
|
4779
4784
|
/* exact match */
|
4780
4785
|
if (ch) {
|
4781
|
-
fio_defer(fio_publish2channel_task,
|
4782
|
-
fio_msg_internal_dup(m));
|
4786
|
+
fio_defer(fio_publish2channel_task, &ch->id, fio_msg_internal_dup(m));
|
4783
4787
|
}
|
4784
4788
|
if (m->filter == 0) {
|
4785
4789
|
/* pattern matching match */
|
@@ -5128,7 +5132,7 @@ static void fio_cluster_server_handler(struct cluster_pr_s *pr) {
|
|
5128
5132
|
fio_str_s tmp = FIO_STR_INIT_EXISTING(
|
5129
5133
|
pr->msg->channel.data, pr->msg->channel.len, 0); // don't free
|
5130
5134
|
fio_lock(&pr->lock);
|
5131
|
-
fio_sub_hash_insert(&pr->pubsub, fio_str_hash(&tmp), tmp, s);
|
5135
|
+
fio_sub_hash_insert(&pr->pubsub, fio_str_hash(&tmp), tmp, s, NULL);
|
5132
5136
|
fio_unlock(&pr->lock);
|
5133
5137
|
break;
|
5134
5138
|
}
|
@@ -5136,7 +5140,7 @@ static void fio_cluster_server_handler(struct cluster_pr_s *pr) {
|
|
5136
5140
|
fio_str_s tmp = FIO_STR_INIT_EXISTING(
|
5137
5141
|
pr->msg->channel.data, pr->msg->channel.len, 0); // don't free
|
5138
5142
|
fio_lock(&pr->lock);
|
5139
|
-
fio_sub_hash_remove(&pr->pubsub, fio_str_hash(&tmp), tmp);
|
5143
|
+
fio_sub_hash_remove(&pr->pubsub, fio_str_hash(&tmp), tmp, NULL);
|
5140
5144
|
fio_unlock(&pr->lock);
|
5141
5145
|
break;
|
5142
5146
|
}
|
@@ -5149,7 +5153,7 @@ static void fio_cluster_server_handler(struct cluster_pr_s *pr) {
|
|
5149
5153
|
fio_str_s tmp = FIO_STR_INIT_EXISTING(
|
5150
5154
|
pr->msg->channel.data, pr->msg->channel.len, 0); // don't free
|
5151
5155
|
fio_lock(&pr->lock);
|
5152
|
-
fio_sub_hash_insert(&pr->patterns, fio_str_hash(&tmp), tmp, s);
|
5156
|
+
fio_sub_hash_insert(&pr->patterns, fio_str_hash(&tmp), tmp, s, NULL);
|
5153
5157
|
fio_unlock(&pr->lock);
|
5154
5158
|
break;
|
5155
5159
|
}
|
@@ -5158,7 +5162,7 @@ static void fio_cluster_server_handler(struct cluster_pr_s *pr) {
|
|
5158
5162
|
fio_str_s tmp = FIO_STR_INIT_EXISTING(
|
5159
5163
|
pr->msg->channel.data, pr->msg->channel.len, 0); // don't free
|
5160
5164
|
fio_lock(&pr->lock);
|
5161
|
-
fio_sub_hash_remove(&pr->patterns, fio_str_hash(&tmp), tmp);
|
5165
|
+
fio_sub_hash_remove(&pr->patterns, fio_str_hash(&tmp), tmp, NULL);
|
5162
5166
|
fio_unlock(&pr->lock);
|
5163
5167
|
break;
|
5164
5168
|
}
|
@@ -5412,7 +5416,7 @@ static void fio_cluster_at_exit(void *ignore) {
|
|
5412
5416
|
fio_pubsub_on_fork();
|
5413
5417
|
/* clear subscriptions of all types */
|
5414
5418
|
while (fio_ch_set_count(&fio_postoffice.patterns.channels)) {
|
5415
|
-
channel_s *ch =
|
5419
|
+
channel_s *ch = fio_ch_set_last(&fio_postoffice.patterns.channels);
|
5416
5420
|
while (fio_ls_embd_any(&ch->subscriptions)) {
|
5417
5421
|
subscription_s *sub =
|
5418
5422
|
FIO_LS_EMBD_OBJ(subscription_s, node, ch->subscriptions.next);
|
@@ -5422,7 +5426,7 @@ static void fio_cluster_at_exit(void *ignore) {
|
|
5422
5426
|
}
|
5423
5427
|
|
5424
5428
|
while (fio_ch_set_count(&fio_postoffice.pubsub.channels)) {
|
5425
|
-
channel_s *ch =
|
5429
|
+
channel_s *ch = fio_ch_set_last(&fio_postoffice.pubsub.channels);
|
5426
5430
|
while (fio_ls_embd_any(&ch->subscriptions)) {
|
5427
5431
|
subscription_s *sub =
|
5428
5432
|
FIO_LS_EMBD_OBJ(subscription_s, node, ch->subscriptions.next);
|
@@ -5432,7 +5436,7 @@ static void fio_cluster_at_exit(void *ignore) {
|
|
5432
5436
|
}
|
5433
5437
|
|
5434
5438
|
while (fio_ch_set_count(&fio_postoffice.filters.channels)) {
|
5435
|
-
channel_s *ch =
|
5439
|
+
channel_s *ch = fio_ch_set_last(&fio_postoffice.filters.channels);
|
5436
5440
|
while (fio_ls_embd_any(&ch->subscriptions)) {
|
5437
5441
|
subscription_s *sub =
|
5438
5442
|
FIO_LS_EMBD_OBJ(subscription_s, node, ch->subscriptions.next);
|
@@ -5447,7 +5451,7 @@ static void fio_cluster_at_exit(void *ignore) {
|
|
5447
5451
|
/* clear engines */
|
5448
5452
|
FIO_PUBSUB_DEFAULT = FIO_PUBSUB_CLUSTER;
|
5449
5453
|
while (fio_engine_set_count(&fio_postoffice.engines.set)) {
|
5450
|
-
fio_pubsub_detach(
|
5454
|
+
fio_pubsub_detach(fio_engine_set_last(&fio_postoffice.engines.set));
|
5451
5455
|
fio_engine_set_last(&fio_postoffice.engines.set);
|
5452
5456
|
}
|
5453
5457
|
fio_engine_set_free(&fio_postoffice.engines.set);
|
@@ -8434,23 +8438,22 @@ FIO_FUNC void fio_set_test(void) {
|
|
8434
8438
|
FIO_ASSERT(!fio_hash_test_is_fragmented(&h),
|
8435
8439
|
"empty hash shouldn't be considered fragmented");
|
8436
8440
|
FIO_ASSERT(!fio_set_test_last(&s), "empty set shouldn't have a last object");
|
8437
|
-
FIO_ASSERT(!fio_hash_test_last(&h),
|
8441
|
+
FIO_ASSERT(!fio_hash_test_last(&h).key && !fio_hash_test_last(&h).obj,
|
8438
8442
|
"empty hash shouldn't have a last object");
|
8439
8443
|
|
8440
8444
|
for (uintptr_t i = 1; i < FIO_SET_TEXT_COUNT; ++i) {
|
8441
8445
|
fio_set_test_insert(&s, i, i);
|
8442
|
-
fio_hash_test_insert(&h, i, i, i + 1);
|
8446
|
+
fio_hash_test_insert(&h, i, i, i + 1, NULL);
|
8443
8447
|
FIO_ASSERT(fio_set_test_find(&s, i, i), "set find failed after insert");
|
8444
8448
|
FIO_ASSERT(fio_hash_test_find(&h, i, i), "hash find failed after insert");
|
8445
|
-
FIO_ASSERT(i ==
|
8446
|
-
FIO_ASSERT(i + 1 ==
|
8447
|
-
"hash insertion != find");
|
8449
|
+
FIO_ASSERT(i == fio_set_test_find(&s, i, i), "set insertion != find");
|
8450
|
+
FIO_ASSERT(i + 1 == fio_hash_test_find(&h, i, i), "hash insertion != find");
|
8448
8451
|
}
|
8449
8452
|
fprintf(stderr, "* Seeking %lu items\n", FIO_SET_TEXT_COUNT);
|
8450
8453
|
for (unsigned long i = 1; i < FIO_SET_TEXT_COUNT; ++i) {
|
8451
|
-
FIO_ASSERT((i ==
|
8454
|
+
FIO_ASSERT((i == fio_set_test_find(&s, i, i)),
|
8452
8455
|
"set insertion != find (seek)");
|
8453
|
-
FIO_ASSERT((i + 1 ==
|
8456
|
+
FIO_ASSERT((i + 1 == fio_hash_test_find(&h, i, i)),
|
8454
8457
|
"hash insertion != find (seek)");
|
8455
8458
|
}
|
8456
8459
|
{
|
@@ -8477,8 +8480,8 @@ FIO_FUNC void fio_set_test(void) {
|
|
8477
8480
|
|
8478
8481
|
fprintf(stderr, "* Removing odd items from %lu items\n", FIO_SET_TEXT_COUNT);
|
8479
8482
|
for (unsigned long i = 1; i < FIO_SET_TEXT_COUNT; i += 2) {
|
8480
|
-
fio_set_test_remove(&s, i, i);
|
8481
|
-
fio_hash_test_remove(&h, i, i);
|
8483
|
+
fio_set_test_remove(&s, i, i, NULL);
|
8484
|
+
fio_hash_test_remove(&h, i, i, NULL);
|
8482
8485
|
FIO_ASSERT(!(fio_set_test_find(&s, i, i)),
|
8483
8486
|
"Removal failed in set (still exists).");
|
8484
8487
|
FIO_ASSERT(!(fio_hash_test_find(&h, i, i)),
|
@@ -8510,49 +8513,49 @@ FIO_FUNC void fio_set_test(void) {
|
|
8510
8513
|
{
|
8511
8514
|
fprintf(stderr, "* Poping two elements (testing pop through holes)\n");
|
8512
8515
|
FIO_ASSERT(fio_set_test_last(&s), "Pop `last` 1 failed - no last object");
|
8513
|
-
uintptr_t tmp =
|
8516
|
+
uintptr_t tmp = fio_set_test_last(&s);
|
8514
8517
|
FIO_ASSERT(tmp, "Pop set `last` 1 failed to collect object");
|
8515
8518
|
fio_set_test_pop(&s);
|
8516
8519
|
FIO_ASSERT(
|
8517
|
-
|
8520
|
+
fio_set_test_last(&s) != tmp,
|
8518
8521
|
"Pop `last` 2 in set same as `last` 1 - failed to collect object");
|
8519
|
-
tmp = fio_hash_test_last(&h)
|
8522
|
+
tmp = fio_hash_test_last(&h).key;
|
8520
8523
|
FIO_ASSERT(tmp, "Pop hash `last` 1 failed to collect object");
|
8521
8524
|
fio_hash_test_pop(&h);
|
8522
8525
|
FIO_ASSERT(
|
8523
|
-
fio_hash_test_last(&h)
|
8526
|
+
fio_hash_test_last(&h).key != tmp,
|
8524
8527
|
"Pop `last` 2 in hash same as `last` 1 - failed to collect object");
|
8525
8528
|
FIO_ASSERT(fio_set_test_last(&s), "Pop `last` 2 failed - no last object");
|
8526
|
-
FIO_ASSERT(fio_hash_test_last(&h),
|
8529
|
+
FIO_ASSERT(fio_hash_test_last(&h).obj,
|
8527
8530
|
"Pop `last` 2 failed in hash - no last object");
|
8528
8531
|
fio_set_test_pop(&s);
|
8529
8532
|
fio_hash_test_pop(&h);
|
8530
8533
|
}
|
8531
8534
|
if (1) {
|
8532
8535
|
uintptr_t tmp = 1;
|
8533
|
-
fio_set_test_remove(&s, tmp, tmp);
|
8534
|
-
fio_hash_test_remove(&h, tmp, tmp);
|
8536
|
+
fio_set_test_remove(&s, tmp, tmp, NULL);
|
8537
|
+
fio_hash_test_remove(&h, tmp, tmp, NULL);
|
8535
8538
|
size_t count = s.count;
|
8536
|
-
fio_set_test_overwrite(&s, tmp, tmp);
|
8539
|
+
fio_set_test_overwrite(&s, tmp, tmp, NULL);
|
8537
8540
|
FIO_ASSERT(
|
8538
8541
|
count + 1 == s.count,
|
8539
8542
|
"Re-adding a removed item in set should increase count by 1 (%zu + "
|
8540
8543
|
"1 != %zu).",
|
8541
8544
|
count, (size_t)s.count);
|
8542
8545
|
count = h.count;
|
8543
|
-
fio_hash_test_insert(&h, tmp, tmp, tmp);
|
8546
|
+
fio_hash_test_insert(&h, tmp, tmp, tmp, NULL);
|
8544
8547
|
FIO_ASSERT(
|
8545
8548
|
count + 1 == h.count,
|
8546
8549
|
"Re-adding a removed item in hash should increase count by 1 (%zu + "
|
8547
8550
|
"1 != %zu).",
|
8548
8551
|
count, (size_t)s.count);
|
8549
|
-
tmp =
|
8552
|
+
tmp = fio_set_test_find(&s, tmp, tmp);
|
8550
8553
|
FIO_ASSERT(tmp == 1,
|
8551
8554
|
"Re-adding a removed item should update the item in the set "
|
8552
8555
|
"(%lu != 1)!",
|
8553
|
-
(unsigned long)
|
8554
|
-
fio_set_test_remove(&s, tmp, tmp);
|
8555
|
-
fio_hash_test_remove(&h, tmp, tmp);
|
8556
|
+
(unsigned long)fio_set_test_find(&s, tmp, tmp));
|
8557
|
+
fio_set_test_remove(&s, tmp, tmp, NULL);
|
8558
|
+
fio_hash_test_remove(&h, tmp, tmp, NULL);
|
8556
8559
|
FIO_ASSERT(count == h.count,
|
8557
8560
|
"Re-removing an item should decrease count (%zu != %zu).",
|
8558
8561
|
count, (size_t)s.count);
|
@@ -8589,14 +8592,13 @@ FIO_FUNC void fio_set_test(void) {
|
|
8589
8592
|
fio_set_test_insert(&s, i, i);
|
8590
8593
|
FIO_ASSERT(fio_set_test_find(&s, i, i),
|
8591
8594
|
"find failed after insert (2nd round)");
|
8592
|
-
FIO_ASSERT(i ==
|
8595
|
+
FIO_ASSERT(i == fio_set_test_find(&s, i, i),
|
8593
8596
|
"insertion (2nd round) != find");
|
8594
8597
|
FIO_ASSERT(i == s.count, "count error (%lu != %lu) post insertion.", i,
|
8595
8598
|
s.count);
|
8596
8599
|
}
|
8597
8600
|
fio_set_test_free(&s);
|
8598
8601
|
}
|
8599
|
-
#undef FIO_SET_NAME
|
8600
8602
|
|
8601
8603
|
/* *****************************************************************************
|
8602
8604
|
SipHash tests
|
data/ext/iodine/fio.h
CHANGED
@@ -402,10 +402,8 @@ extern size_t FIO_LOG_LEVEL;
|
|
402
402
|
/** Tests for an allocation failure. The behavior can be overridden. */
|
403
403
|
#define FIO_ASSERT_ALLOC(ptr) \
|
404
404
|
if (!(ptr)) { \
|
405
|
-
fprintf(stderr,
|
406
|
-
|
407
|
-
":%d\n", \
|
408
|
-
__LINE__); \
|
405
|
+
fprintf(stderr, "\nFATAL ERROR: memory allocation error "__FILE__ \
|
406
|
+
":" FIO_MACRO2STR(__LINE__) "\n"); \
|
409
407
|
perror(" Error details (errno)"); \
|
410
408
|
kill(0, SIGINT); \
|
411
409
|
exit(errno); \
|
@@ -2738,11 +2736,11 @@ FIO_FUNC inline int fio_ls_embd_any(fio_ls_embd_s *list);
|
|
2738
2736
|
Independent Linked List API
|
2739
2737
|
***************************************************************************** */
|
2740
2738
|
|
2741
|
-
/** Adds an object to the list's head. */
|
2742
|
-
FIO_FUNC inline
|
2739
|
+
/** Adds an object to the list's head, returnin's the object's location. */
|
2740
|
+
FIO_FUNC inline fio_ls_s *fio_ls_push(fio_ls_s *pos, const void *obj);
|
2743
2741
|
|
2744
|
-
/** Adds an object to the list's tail. */
|
2745
|
-
FIO_FUNC inline
|
2742
|
+
/** Adds an object to the list's tail, returnin's the object's location. */
|
2743
|
+
FIO_FUNC inline fio_ls_s *fio_ls_unshift(fio_ls_s *pos, const void *obj);
|
2746
2744
|
|
2747
2745
|
/** Removes an object from the list's head. */
|
2748
2746
|
FIO_FUNC inline void *fio_ls_pop(fio_ls_s *list);
|
@@ -2848,7 +2846,7 @@ FIO_FUNC inline void *fio_ls_remove(fio_ls_s *node) {
|
|
2848
2846
|
}
|
2849
2847
|
|
2850
2848
|
/** Adds an object to the list's head. */
|
2851
|
-
FIO_FUNC inline
|
2849
|
+
FIO_FUNC inline fio_ls_s *fio_ls_push(fio_ls_s *pos, const void *obj) {
|
2852
2850
|
/* prepare item */
|
2853
2851
|
fio_ls_s *item = (fio_ls_s *)malloc(sizeof(*item));
|
2854
2852
|
if (!item) {
|
@@ -2859,11 +2857,12 @@ FIO_FUNC inline void fio_ls_push(fio_ls_s *pos, const void *obj) {
|
|
2859
2857
|
/* inject item */
|
2860
2858
|
pos->prev->next = item;
|
2861
2859
|
pos->prev = item;
|
2860
|
+
return item;
|
2862
2861
|
}
|
2863
2862
|
|
2864
2863
|
/** Adds an object to the list's tail. */
|
2865
|
-
FIO_FUNC inline
|
2866
|
-
fio_ls_push(pos->next, obj);
|
2864
|
+
FIO_FUNC inline fio_ls_s *fio_ls_unshift(fio_ls_s *pos, const void *obj) {
|
2865
|
+
return fio_ls_push(pos->next, obj);
|
2867
2866
|
}
|
2868
2867
|
|
2869
2868
|
/** Removes an object from the list's head. */
|
@@ -4207,9 +4206,9 @@ inline FIO_FUNC ssize_t fio_str_send_free2(const intptr_t uuid,
|
|
4207
4206
|
typedef struct {
|
4208
4207
|
FIO_SET_KEY_TYPE key;
|
4209
4208
|
FIO_SET_OBJ_TYPE obj;
|
4210
|
-
} FIO_NAME(
|
4209
|
+
} FIO_NAME(couplet_s);
|
4211
4210
|
|
4212
|
-
#define FIO_SET_TYPE FIO_NAME(
|
4211
|
+
#define FIO_SET_TYPE FIO_NAME(couplet_s)
|
4213
4212
|
|
4214
4213
|
/** key copy required? */
|
4215
4214
|
#ifndef FIO_SET_KEY_COPY
|
@@ -4270,26 +4269,10 @@ FIO_FUNC void FIO_NAME(free)(FIO_NAME(s) * set);
|
|
4270
4269
|
*
|
4271
4270
|
* NOTE: This is the function's Hash Map variant. See FIO_SET_KEY_TYPE.
|
4272
4271
|
*/
|
4273
|
-
FIO_FUNC inline FIO_SET_OBJ_TYPE
|
4272
|
+
FIO_FUNC inline FIO_SET_OBJ_TYPE
|
4274
4273
|
FIO_NAME(find)(FIO_NAME(s) * set, const FIO_SET_HASH_TYPE hash_value,
|
4275
4274
|
FIO_SET_KEY_TYPE key);
|
4276
4275
|
|
4277
|
-
/**
|
4278
|
-
* Inserts an object to the Hash Map, rehashing if required, returning the new
|
4279
|
-
* object's location using a pointer.
|
4280
|
-
*
|
4281
|
-
* If an object already exists in the Hash Map with the same key, it will be
|
4282
|
-
* destroyed.
|
4283
|
-
*
|
4284
|
-
* NOTE 1: This is the function's Hash Map variant. See FIO_SET_KEY_TYPE.
|
4285
|
-
*
|
4286
|
-
* NOTE 2: This is equivelant to calling the `insert2` with `old` set to NULL.
|
4287
|
-
*/
|
4288
|
-
FIO_FUNC inline void FIO_NAME(insert)(FIO_NAME(s) * set,
|
4289
|
-
const FIO_SET_HASH_TYPE hash_value,
|
4290
|
-
FIO_SET_KEY_TYPE key,
|
4291
|
-
FIO_SET_OBJ_TYPE obj);
|
4292
|
-
|
4293
4276
|
/**
|
4294
4277
|
* Inserts an object to the Hash Map, rehashing if required, returning the new
|
4295
4278
|
* object's location using a pointer.
|
@@ -4301,22 +4284,11 @@ FIO_FUNC inline void FIO_NAME(insert)(FIO_NAME(s) * set,
|
|
4301
4284
|
*
|
4302
4285
|
* NOTE: This is the function's Hash Map variant. See FIO_SET_KEY_TYPE.
|
4303
4286
|
*/
|
4304
|
-
FIO_FUNC inline void FIO_NAME(
|
4305
|
-
|
4306
|
-
|
4307
|
-
|
4308
|
-
|
4309
|
-
|
4310
|
-
/**
|
4311
|
-
* Removes an object from the Hash Map, rehashing if required.
|
4312
|
-
*
|
4313
|
-
* Returns 0 on success and -1 if the object wasn't found.
|
4314
|
-
*
|
4315
|
-
* NOTE: This is the function's Hash Map variant. See FIO_SET_KEY_TYPE.
|
4316
|
-
*/
|
4317
|
-
FIO_FUNC inline int FIO_NAME(remove)(FIO_NAME(s) * set,
|
4318
|
-
const FIO_SET_HASH_TYPE hash_value,
|
4319
|
-
FIO_SET_KEY_TYPE key);
|
4287
|
+
FIO_FUNC inline void FIO_NAME(insert)(FIO_NAME(s) * set,
|
4288
|
+
const FIO_SET_HASH_TYPE hash_value,
|
4289
|
+
FIO_SET_KEY_TYPE key,
|
4290
|
+
FIO_SET_OBJ_TYPE obj,
|
4291
|
+
FIO_SET_OBJ_TYPE *old);
|
4320
4292
|
|
4321
4293
|
/**
|
4322
4294
|
* Removes an object from the Hash Map, rehashing if required.
|
@@ -4328,10 +4300,10 @@ FIO_FUNC inline int FIO_NAME(remove)(FIO_NAME(s) * set,
|
|
4328
4300
|
*
|
4329
4301
|
* NOTE: This is the function's Hash Map variant. See FIO_SET_KEY_TYPE.
|
4330
4302
|
*/
|
4331
|
-
FIO_FUNC inline int FIO_NAME(
|
4332
|
-
|
4333
|
-
|
4334
|
-
|
4303
|
+
FIO_FUNC inline int FIO_NAME(remove)(FIO_NAME(s) * set,
|
4304
|
+
const FIO_SET_HASH_TYPE hash_value,
|
4305
|
+
FIO_SET_KEY_TYPE key,
|
4306
|
+
FIO_SET_OBJ_TYPE *old);
|
4335
4307
|
|
4336
4308
|
#else
|
4337
4309
|
|
@@ -4340,47 +4312,35 @@ FIO_FUNC inline int FIO_NAME(remove2)(FIO_NAME(s) * set,
|
|
4340
4312
|
*
|
4341
4313
|
* NOTE: This is the function's pure Set variant (no FIO_SET_KEY_TYPE).
|
4342
4314
|
*/
|
4343
|
-
FIO_FUNC inline FIO_SET_OBJ_TYPE
|
4315
|
+
FIO_FUNC inline FIO_SET_OBJ_TYPE
|
4344
4316
|
FIO_NAME(find)(FIO_NAME(s) * set, const FIO_SET_HASH_TYPE hash_value,
|
4345
4317
|
FIO_SET_OBJ_TYPE obj);
|
4346
4318
|
|
4347
4319
|
/**
|
4348
4320
|
* Inserts an object to the Set only if it's missing, rehashing if required,
|
4349
|
-
* returning the new (or old) object
|
4350
|
-
*
|
4321
|
+
* returning the new (or old) object.
|
4351
4322
|
*
|
4352
4323
|
* If the object already exists in the set, than the new object will be
|
4353
|
-
* destroyed and the old object
|
4324
|
+
* destroyed and the old object will be returned.
|
4354
4325
|
*
|
4355
4326
|
* NOTE: This is the function's pure Set variant (no FIO_SET_KEY_TYPE).
|
4356
4327
|
*/
|
4357
|
-
FIO_FUNC inline FIO_SET_OBJ_TYPE
|
4328
|
+
FIO_FUNC inline FIO_SET_OBJ_TYPE
|
4358
4329
|
FIO_NAME(insert)(FIO_NAME(s) * set, const FIO_SET_HASH_TYPE hash_value,
|
4359
4330
|
FIO_SET_OBJ_TYPE obj);
|
4360
4331
|
|
4361
4332
|
/**
|
4362
4333
|
* Inserts an object to the Set, rehashing if required, returning the new
|
4363
|
-
* object
|
4334
|
+
* object.
|
4364
4335
|
*
|
4365
4336
|
* If the object already exists in the set, it will be destroyed and
|
4366
4337
|
* overwritten.
|
4367
4338
|
*
|
4368
|
-
* NOTE: This function doesn't exist when FIO_SET_KEY_TYPE is defined.
|
4369
|
-
*/
|
4370
|
-
FIO_FUNC inline FIO_SET_OBJ_TYPE *
|
4371
|
-
FIO_NAME(overwrite)(FIO_NAME(s) * set, const FIO_SET_HASH_TYPE hash_value,
|
4372
|
-
FIO_SET_OBJ_TYPE obj);
|
4373
|
-
|
4374
|
-
/**
|
4375
|
-
* The same as `overwrite`, only it copies the old object (if any) to the
|
4376
|
-
* location pointed to by `old`.
|
4377
|
-
*
|
4378
4339
|
* When setting `old` to NULL, the function behaves the same as `overwrite`.
|
4379
4340
|
*/
|
4380
|
-
FIO_FUNC FIO_SET_OBJ_TYPE
|
4381
|
-
|
4382
|
-
|
4383
|
-
FIO_SET_OBJ_TYPE *old);
|
4341
|
+
FIO_FUNC FIO_SET_OBJ_TYPE
|
4342
|
+
FIO_NAME(overwrite)(FIO_NAME(s) * set, const FIO_SET_HASH_TYPE hash_value,
|
4343
|
+
FIO_SET_OBJ_TYPE obj, FIO_SET_OBJ_TYPE *old);
|
4384
4344
|
|
4385
4345
|
/**
|
4386
4346
|
* Removes an object from the Set, rehashing if required.
|
@@ -4391,7 +4351,8 @@ FIO_FUNC FIO_SET_OBJ_TYPE *FIO_NAME(replace)(FIO_NAME(s) * set,
|
|
4391
4351
|
*/
|
4392
4352
|
FIO_FUNC inline int FIO_NAME(remove)(FIO_NAME(s) * set,
|
4393
4353
|
const FIO_SET_HASH_TYPE hash_value,
|
4394
|
-
FIO_SET_OBJ_TYPE obj
|
4354
|
+
FIO_SET_OBJ_TYPE obj,
|
4355
|
+
FIO_SET_OBJ_TYPE *old);
|
4395
4356
|
|
4396
4357
|
#endif
|
4397
4358
|
/**
|
@@ -4400,7 +4361,7 @@ FIO_FUNC inline int FIO_NAME(remove)(FIO_NAME(s) * set,
|
|
4400
4361
|
* Remember that objects might be destroyed if the Set is altered
|
4401
4362
|
* (`FIO_SET_OBJ_DESTROY` / `FIO_SET_KEY_DESTROY`).
|
4402
4363
|
*/
|
4403
|
-
FIO_FUNC inline FIO_SET_TYPE
|
4364
|
+
FIO_FUNC inline FIO_SET_TYPE FIO_NAME(last)(FIO_NAME(s) * set);
|
4404
4365
|
|
4405
4366
|
/**
|
4406
4367
|
* Allows the Hash to be momentarily used as a stack, destroying the last
|
@@ -4579,11 +4540,14 @@ FIO_FUNC inline void FIO_NAME(_reallocate_set_mem_)(FIO_NAME(s) * set) {
|
|
4579
4540
|
* If the object already exists in the set, it will be destroyed and
|
4580
4541
|
* overwritten.
|
4581
4542
|
*/
|
4582
|
-
FIO_FUNC inline FIO_SET_TYPE
|
4543
|
+
FIO_FUNC inline FIO_SET_TYPE FIO_NAME(_insert_or_overwrite_)(
|
4583
4544
|
FIO_NAME(s) * set, const FIO_SET_HASH_TYPE hash_value, FIO_SET_TYPE obj,
|
4584
4545
|
int overwrite, FIO_SET_OBJ_TYPE *old) {
|
4585
|
-
if (FIO_SET_HASH_COMPARE(hash_value, FIO_SET_HASH_INVALID))
|
4586
|
-
|
4546
|
+
if (FIO_SET_HASH_COMPARE(hash_value, FIO_SET_HASH_INVALID)) {
|
4547
|
+
FIO_SET_TYPE empty;
|
4548
|
+
memset(&empty, 0, sizeof(empty));
|
4549
|
+
return empty;
|
4550
|
+
}
|
4587
4551
|
|
4588
4552
|
/* automatic fragmentation protection */
|
4589
4553
|
if (FIO_NAME(is_fragmented)(set))
|
@@ -4603,7 +4567,7 @@ FIO_FUNC inline FIO_SET_TYPE *FIO_NAME(_insert_or_overwrite_)(
|
|
4603
4567
|
/* overwrite existing object */
|
4604
4568
|
if (!overwrite) {
|
4605
4569
|
FIO_SET_DESTROY(obj);
|
4606
|
-
return
|
4570
|
+
return pos->pos->obj;
|
4607
4571
|
}
|
4608
4572
|
#ifdef FIO_SET_KEY_TYPE
|
4609
4573
|
if (old) {
|
@@ -4612,7 +4576,7 @@ FIO_FUNC inline FIO_SET_TYPE *FIO_NAME(_insert_or_overwrite_)(
|
|
4612
4576
|
/* no need to recreate the key object, just the value object */
|
4613
4577
|
FIO_SET_OBJ_DESTROY(pos->pos->obj.obj);
|
4614
4578
|
FIO_SET_OBJ_COPY(pos->pos->obj.obj, obj.obj);
|
4615
|
-
return
|
4579
|
+
return pos->pos->obj;
|
4616
4580
|
#else
|
4617
4581
|
if (old) {
|
4618
4582
|
FIO_SET_COPY((*old), pos->pos->obj);
|
@@ -4630,7 +4594,7 @@ FIO_FUNC inline FIO_SET_TYPE *FIO_NAME(_insert_or_overwrite_)(
|
|
4630
4594
|
pos->pos->hash = hash_value;
|
4631
4595
|
FIO_SET_COPY(pos->pos->obj, obj);
|
4632
4596
|
|
4633
|
-
return
|
4597
|
+
return pos->pos->obj;
|
4634
4598
|
}
|
4635
4599
|
|
4636
4600
|
/* *****************************************************************************
|
@@ -4661,29 +4625,17 @@ FIO_FUNC void FIO_NAME(free)(FIO_NAME(s) * s) {
|
|
4661
4625
|
*
|
4662
4626
|
* NOTE: This is the function's Hash Map variant. See FIO_SET_KEY_TYPE.
|
4663
4627
|
*/
|
4664
|
-
FIO_FUNC FIO_SET_OBJ_TYPE
|
4665
|
-
|
4666
|
-
|
4628
|
+
FIO_FUNC FIO_SET_OBJ_TYPE FIO_NAME(find)(FIO_NAME(s) * set,
|
4629
|
+
const FIO_SET_HASH_TYPE hash_value,
|
4630
|
+
FIO_SET_KEY_TYPE key) {
|
4667
4631
|
FIO_NAME(_map_s_) *pos =
|
4668
4632
|
FIO_NAME(_find_map_pos_)(set, hash_value, (FIO_SET_TYPE){.key = key});
|
4669
|
-
if (!pos || !pos->pos)
|
4670
|
-
|
4671
|
-
|
4672
|
-
|
4673
|
-
|
4674
|
-
|
4675
|
-
* Inserts an object to the Hash Map, rehashing if required, returning the new
|
4676
|
-
* object's location using a pointer.
|
4677
|
-
*
|
4678
|
-
* If the object already exists in the set, it will be destroyed.
|
4679
|
-
*
|
4680
|
-
* NOTE: This is the function's Hash Map variant. See FIO_SET_KEY_TYPE.
|
4681
|
-
*/
|
4682
|
-
FIO_FUNC void FIO_NAME(insert)(FIO_NAME(s) * set,
|
4683
|
-
const FIO_SET_HASH_TYPE hash_value,
|
4684
|
-
FIO_SET_KEY_TYPE key, FIO_SET_OBJ_TYPE obj) {
|
4685
|
-
FIO_NAME(_insert_or_overwrite_)
|
4686
|
-
(set, hash_value, (FIO_SET_TYPE){.key = key, .obj = obj}, 1, NULL);
|
4633
|
+
if (!pos || !pos->pos) {
|
4634
|
+
FIO_SET_OBJ_TYPE empty;
|
4635
|
+
memset(&empty, 0, sizeof(empty));
|
4636
|
+
return empty;
|
4637
|
+
}
|
4638
|
+
return pos->pos->obj.obj;
|
4687
4639
|
}
|
4688
4640
|
|
4689
4641
|
/**
|
@@ -4697,10 +4649,10 @@ FIO_FUNC void FIO_NAME(insert)(FIO_NAME(s) * set,
|
|
4697
4649
|
*
|
4698
4650
|
* NOTE: This is the function's Hash Map variant. See FIO_SET_KEY_TYPE.
|
4699
4651
|
*/
|
4700
|
-
FIO_FUNC void FIO_NAME(
|
4701
|
-
|
4702
|
-
|
4703
|
-
|
4652
|
+
FIO_FUNC void FIO_NAME(insert)(FIO_NAME(s) * set,
|
4653
|
+
const FIO_SET_HASH_TYPE hash_value,
|
4654
|
+
FIO_SET_KEY_TYPE key, FIO_SET_OBJ_TYPE obj,
|
4655
|
+
FIO_SET_OBJ_TYPE *old) {
|
4704
4656
|
FIO_NAME(_insert_or_overwrite_)
|
4705
4657
|
(set, hash_value, (FIO_SET_TYPE){.key = key, .obj = obj}, 1, old);
|
4706
4658
|
}
|
@@ -4715,10 +4667,10 @@ FIO_FUNC void FIO_NAME(insert2)(FIO_NAME(s) * set,
|
|
4715
4667
|
*
|
4716
4668
|
* NOTE: This is the function's Hash Map variant. See FIO_SET_KEY_TYPE.
|
4717
4669
|
*/
|
4718
|
-
FIO_FUNC inline int FIO_NAME(
|
4719
|
-
|
4720
|
-
|
4721
|
-
|
4670
|
+
FIO_FUNC inline int FIO_NAME(remove)(FIO_NAME(s) * set,
|
4671
|
+
const FIO_SET_HASH_TYPE hash_value,
|
4672
|
+
FIO_SET_KEY_TYPE key,
|
4673
|
+
FIO_SET_OBJ_TYPE *old) {
|
4722
4674
|
if (FIO_SET_HASH_COMPARE(hash_value, FIO_SET_HASH_INVALID))
|
4723
4675
|
return -1;
|
4724
4676
|
FIO_NAME(_map_s_) *pos =
|
@@ -4740,22 +4692,19 @@ FIO_FUNC inline int FIO_NAME(remove2)(FIO_NAME(s) * set,
|
|
4740
4692
|
return 0;
|
4741
4693
|
}
|
4742
4694
|
|
4743
|
-
FIO_FUNC inline int FIO_NAME(remove)(FIO_NAME(s) * set,
|
4744
|
-
const FIO_SET_HASH_TYPE hash_value,
|
4745
|
-
FIO_SET_KEY_TYPE key) {
|
4746
|
-
return FIO_NAME(remove2)(set, hash_value, key, NULL);
|
4747
|
-
}
|
4748
|
-
|
4749
4695
|
#else
|
4750
4696
|
|
4751
4697
|
/** Locates an object in the Set, if it exists. */
|
4752
|
-
FIO_FUNC FIO_SET_OBJ_TYPE
|
4753
|
-
|
4754
|
-
|
4698
|
+
FIO_FUNC FIO_SET_OBJ_TYPE FIO_NAME(find)(FIO_NAME(s) * set,
|
4699
|
+
const FIO_SET_HASH_TYPE hash_value,
|
4700
|
+
FIO_SET_OBJ_TYPE obj) {
|
4755
4701
|
FIO_NAME(_map_s_) *pos = FIO_NAME(_find_map_pos_)(set, hash_value, obj);
|
4756
|
-
if (!pos || !pos->pos)
|
4757
|
-
|
4758
|
-
|
4702
|
+
if (!pos || !pos->pos) {
|
4703
|
+
FIO_SET_OBJ_TYPE empty;
|
4704
|
+
memset(&empty, 0, sizeof(empty));
|
4705
|
+
return empty;
|
4706
|
+
}
|
4707
|
+
return pos->pos->obj;
|
4759
4708
|
}
|
4760
4709
|
|
4761
4710
|
/**
|
@@ -4765,9 +4714,9 @@ FIO_FUNC FIO_SET_OBJ_TYPE *FIO_NAME(find)(FIO_NAME(s) * set,
|
|
4765
4714
|
* If the object already exists in the set, than the new object will be
|
4766
4715
|
* destroyed and the old object's address will be returned.
|
4767
4716
|
*/
|
4768
|
-
FIO_FUNC FIO_SET_OBJ_TYPE
|
4769
|
-
|
4770
|
-
|
4717
|
+
FIO_FUNC FIO_SET_OBJ_TYPE FIO_NAME(insert)(FIO_NAME(s) * set,
|
4718
|
+
const FIO_SET_HASH_TYPE hash_value,
|
4719
|
+
FIO_SET_OBJ_TYPE obj) {
|
4771
4720
|
return FIO_NAME(_insert_or_overwrite_)(set, hash_value, obj, 0, NULL);
|
4772
4721
|
}
|
4773
4722
|
|
@@ -4777,23 +4726,12 @@ FIO_FUNC FIO_SET_OBJ_TYPE *FIO_NAME(insert)(FIO_NAME(s) * set,
|
|
4777
4726
|
*
|
4778
4727
|
* If the object already exists in the set, it will be destroyed and
|
4779
4728
|
* overwritten.
|
4780
|
-
*/
|
4781
|
-
FIO_FUNC FIO_SET_OBJ_TYPE *
|
4782
|
-
FIO_NAME(overwrite)(FIO_NAME(s) * set, const FIO_SET_HASH_TYPE hash_value,
|
4783
|
-
FIO_SET_OBJ_TYPE obj) {
|
4784
|
-
return FIO_NAME(_insert_or_overwrite_)(set, hash_value, obj, 1, NULL);
|
4785
|
-
}
|
4786
|
-
|
4787
|
-
/**
|
4788
|
-
* The same as `overwrite`, only it copies the old object (if any) to the
|
4789
|
-
* location pointed to by `old`.
|
4790
4729
|
*
|
4791
4730
|
* When setting `old` to NULL, the function behaves the same as `overwrite`.
|
4792
4731
|
*/
|
4793
|
-
FIO_FUNC FIO_SET_OBJ_TYPE
|
4794
|
-
|
4795
|
-
|
4796
|
-
FIO_SET_OBJ_TYPE *old) {
|
4732
|
+
FIO_FUNC FIO_SET_OBJ_TYPE
|
4733
|
+
FIO_NAME(overwrite)(FIO_NAME(s) * set, const FIO_SET_HASH_TYPE hash_value,
|
4734
|
+
FIO_SET_OBJ_TYPE obj, FIO_SET_OBJ_TYPE *old) {
|
4797
4735
|
return FIO_NAME(_insert_or_overwrite_)(set, hash_value, obj, 1, old);
|
4798
4736
|
}
|
4799
4737
|
|
@@ -4802,12 +4740,14 @@ FIO_FUNC FIO_SET_OBJ_TYPE *FIO_NAME(replace)(FIO_NAME(s) * set,
|
|
4802
4740
|
*/
|
4803
4741
|
FIO_FUNC int FIO_NAME(remove)(FIO_NAME(s) * set,
|
4804
4742
|
const FIO_SET_HASH_TYPE hash_value,
|
4805
|
-
FIO_SET_OBJ_TYPE obj) {
|
4743
|
+
FIO_SET_OBJ_TYPE obj, FIO_SET_OBJ_TYPE *old) {
|
4806
4744
|
if (FIO_SET_HASH_COMPARE(hash_value, FIO_SET_HASH_INVALID))
|
4807
4745
|
return -1;
|
4808
4746
|
FIO_NAME(_map_s_) *pos = FIO_NAME(_find_map_pos_)(set, hash_value, obj);
|
4809
4747
|
if (!pos || !pos->pos)
|
4810
4748
|
return -1;
|
4749
|
+
if (old)
|
4750
|
+
FIO_SET_COPY((*old), pos->pos->obj);
|
4811
4751
|
FIO_SET_DESTROY(pos->pos->obj);
|
4812
4752
|
--set->count;
|
4813
4753
|
pos->pos->hash = FIO_SET_HASH_INVALID;
|
@@ -4829,10 +4769,13 @@ FIO_FUNC int FIO_NAME(remove)(FIO_NAME(s) * set,
|
|
4829
4769
|
* Remember that objects might be destroyed if the Set is altered
|
4830
4770
|
* (`FIO_SET_OBJ_DESTROY` / `FIO_SET_KEY_DESTROY`).
|
4831
4771
|
*/
|
4832
|
-
FIO_FUNC inline FIO_SET_TYPE
|
4833
|
-
if (!set->ordered || !set->pos)
|
4834
|
-
|
4835
|
-
|
4772
|
+
FIO_FUNC inline FIO_SET_TYPE FIO_NAME(last)(FIO_NAME(s) * set) {
|
4773
|
+
if (!set->ordered || !set->pos) {
|
4774
|
+
FIO_SET_TYPE empty;
|
4775
|
+
memset(&empty, 0, sizeof(empty));
|
4776
|
+
return empty;
|
4777
|
+
}
|
4778
|
+
return set->ordered[set->pos - 1].obj;
|
4836
4779
|
}
|
4837
4780
|
|
4838
4781
|
/**
|