Dudum ante eramus ad problema purgationis tuples in spatiis
Exemplum bonum nobis fuit moduli tarantool vocati
Description
Documenta pro tarantool valde bona est
Ex longinquo incipiamus et vide quid moduli capped exspirationis ab exterioribus similes sint:
fiber = require('fiber')
net_box = require('net.box')
box.cfg{listen = 3300}
box.schema.func.create('libcapped-expirationd.start', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.start')
box.schema.func.create('libcapped-expirationd.kill', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.kill')
box.schema.space.create('tester')
box.space.tester:create_index('primary', {unique = true, parts = {1, 'unsigned'}})
capped_connection = net_box:new(3300)
Pro simplicitate tarantool in indicem deducimus ubi bibliotheca nostra libcapped-expirationd.so sita est. Duae functiones e bibliotheca exportantur: incipite et occidunt. Primus gradus est haec munera praesto facere ex Luae box.schema.func.create et box.schema.user.grant. Tum spatium crea cuius tuples tantum tres agros continebit: prima est unica identificatio, secunda inscriptio est, tertia vita tupla est. Lignum indicem super primi campi construimus et primarium vocamus. Deinde nexum obiecto bibliothecae nostrae patriae consequimur.
Post opus praeparatorium, munus initium currite;
capped_connection:call('libcapped-expirationd.start', {'non-indexed', box.space.tester.id, box.space.tester.index.primary, box.space.tester.index.primary, 3, 1024, 3600})
Hoc exemplum in intuendo prorsus idem faciet ac moduli respirandi, qui in Lua scriptus est. Prima ratio ad initium functionis est singulare nomen muneris. Secundum est spatium identis. Tertius index singularis est quo tuples delebitur. Quartus index qua tuples percurretur. Quintus est numerus campi tupli cum vita sua (numbering incipit ab 1, not 0!). Sextus et septimus occasus scandunt. 1024 numerus maximus est tuples qui in una transactione spectari potest. MMMDC - plena scan tempus in secundis.
Nota quod exemplum eodem indice utitur ad reptando et delendo. Si index arboris hoc est, tunc traversalis exercetur a minore clave ad maiorem. Si est alius, exempli gratia, index Nullam, tunc peragitur traversalis fere in ordine temere. Totum spatium tuples in uno scan lustratur.
Plures tuples inseramus in spatium cum vita 60 secundis:
box.space.tester:insert{0, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{1, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{2, '[email protected]', math.floor(fiber.time()) + 60}
Sit scriptor reprehendo insertionem valuitque;
tarantool> box.space.tester.index.primary:select()
---
- - [0, '[email protected]', 1576418976]
- [1, '[email protected]', 1576418976]
- [2, '[email protected]', 1576418976]
...
Repeamus electa post 60+ secundis (ab initio insertionis primae tuplae computatis) et videamus moduli cappedum expiratione iam discursum esse:
tarantool> box.space.tester.index.primary:select()
---
- []
...
Sit scriptor inhibere negotium:
capped_connection:call('libcapped-expirationd.kill', {'non-indexed'})
Intueamur alterum exemplum ubi index separatus ponitur pro repere:
fiber = require('fiber')
net_box = require('net.box')
box.cfg{listen = 3300}
box.schema.func.create('libcapped-expirationd.start', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.start')
box.schema.func.create('libcapped-expirationd.kill', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.kill')
box.schema.space.create('tester')
box.space.tester:create_index('primary', {unique = true, parts = {1, 'unsigned'}})
box.space.tester:create_index('exp', {unique = false, parts = {3, 'unsigned'}})
capped_connection = net_box:new(3300)
Omnia hic eadem, quae in primo exemplo, paucis exceptis. Arborem indicem super tertii campi construimus et eam appellamus exp. Hic index non habet esse unicum, dissimilis index qui vocatur primarius. Traversal peragetur index exp, et deletio primaria. Antea utrumque factum meminimus tantum indice primo utente.
Post opus praeparatorium, munus committitur novis argumentis;
capped_connection:call('libcapped-expirationd.start', {'indexed', box.space.tester.id, box.space.tester.index.primary, box.space.tester.index.exp, 3, 1024, 3600})
Plures tuples inseramus in spatium iterum cum vita 60 secundis:
box.space.tester:insert{0, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{1, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{2, '[email protected]', math.floor(fiber.time()) + 60}
Post 30 seconds, per analogiam, plura tuples addemus;
box.space.tester:insert{3, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{4, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{5, '[email protected]', math.floor(fiber.time()) + 60}
Sit scriptor reprehendo insertionem valuitque;
tarantool> box.space.tester.index.primary:select()
---
- - [0, '[email protected]', 1576421257]
- [1, '[email protected]', 1576421257]
- [2, '[email protected]', 1576421257]
- [3, '[email protected]', 1576421287]
- [4, '[email protected]', 1576421287]
- [5, '[email protected]', 1576421287]
...
Repeamus electa post 60+ secundis (ab initio insertionis primae tuplae computatis) et videamus moduli cappedum expiratione iam discursum esse:
tarantool> box.space.tester.index.primary:select()
---
- - [3, '[email protected]', 1576421287]
- [4, '[email protected]', 1576421287]
- [5, '[email protected]', 1576421287]
...
Sunt adhuc quidam tuples relicti in spatio quod circiter 30 plus secundis ad vivendum habebit. Praeterea, scan cessatum est a tupla cum ID of 2 et vita 1576421257 ad tuplum cum ID 3 et vita 1576421287 cessatum est. Tuples cum vita 1576421287 vel plura non lustrata sunt propter ordinationem. in indice clavium exp. Haec est compendia quam in ipso initio consequi voluimus.
Sit scriptor inhibere negotium:
capped_connection:call('libcapped-expirationd.kill', {'indexed'})
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ
Optime narrandum est de omnibus formis consilii fontem suum esse.
Argumenta ad methodum satus transeamus in structura quae vocatur expirationd_task:
struct expirationd_task
{
char name[256];
uint32_t space_id;
uint32_t rm_index_id;
uint32_t it_index_id;
uint32_t it_index_type;
uint32_t field_no;
uint32_t scan_size;
uint32_t scan_time;
};
Nomen attributum est nomen negotii. The space_id attributum est spatium identifier. Proprium rm_index_id est identifier index singularis quo tuples delebitur. Id attributum est identifier index quo tuples percurretur. Proprium illud_index_type est genus indices quo tuples percurretur. Filed_no attributum est numerus campi tuple cum vita. The scan_size attributum est numerus maximus tuples qui in una re lustrantur. Scan_time attributum est plenum scan tempus in secundis.
Nolumus parsing rationes. Hoc est officium accuratum sed simplex, quo bibliotheca te adiuvabit
Prototypa omnium functionum quae ad parsing adhibentur enumeramus:
bool expirationd_parse_name(struct expirationd_task *task, const char **pos);
bool expirationd_parse_space_id(struct expirationd_task *task, const char **pos);
bool expirationd_parse_rm_index_id(struct expirationd_task *task, const char **pos);
bool expirationd_parse_rm_index_unique(struct expirationd_task *task, const char **pos);
bool expirationd_parse_rm_index(struct expirationd_task *task, const char **pos);
bool expirationd_parse_it_index_id(struct expirationd_task *task, const char **pos);
bool expirationd_parse_it_index_type(struct expirationd_task *task, const char **pos);
bool expirationd_parse_it_index(struct expirationd_task *task, const char **pos);
bool expirationd_parse_field_no(struct expirationd_task *task, const char **pos);
bool expirationd_parse_scan_size(struct expirationd_task *task, const char **pos);
bool expirationd_parse_scan_time(struct expirationd_task *task, const char **pos);
Nunc ad rem maximi momenti transeamus β logicam spatium praetermittens et tuples delendo. Uterque truncus tuples non maior quam scan_size lustratur ac modificatur sub una transactione. Si bene, hoc negotium committitur: si erratum est, revolvitur. Postrema ratio ad functionem expirationem_iterate monstrator est ad iteratorem a quo intuens incipit vel pergit. Hic iterator interius augetur donec error incidat, spatium decurrit vel processum in antecessum sistere non potest. Munus expirationd_exspirationis vitam tuplae supprimit, expirationd_deletum tuple delet, expirationd_breakable compescit an progrediendum opus est.
Expirationd_iterate munus codice:
static bool
expirationd_iterate(struct expirationd_task *task, box_iterator_t **iterp)
{
box_iterator_t *iter = *iterp;
box_txn_begin();
for (uint32_t i = 0; i < task->scan_size; ++i) {
box_tuple_t *tuple = NULL;
if (box_iterator_next(iter, &tuple) < 0) {
box_iterator_free(iter);
*iterp = NULL;
box_txn_rollback();
return false;
}
if (!tuple) {
box_iterator_free(iter);
*iterp = NULL;
box_txn_commit();
return true;
}
if (expirationd_expired(task, tuple))
expirationd_delete(task, tuple);
else if (expirationd_breakable(task))
break;
}
box_txn_commit();
return true;
}
Munus codice expirationd_expired:
static bool
expirationd_expired(struct expirationd_task *task, box_tuple_t *tuple)
{
const char *buf = box_tuple_field(tuple, task->field_no - 1);
if (!buf || mp_typeof(*buf) != MP_UINT)
return false;
uint64_t val = mp_decode_uint(&buf);
if (val > fiber_time64() / 1000000)
return false;
return true;
}
Expirationd_delete munus codice:
static void
expirationd_delete(struct expirationd_task *task, box_tuple_t *tuple)
{
uint32_t len;
const char *str = box_tuple_extract_key(tuple, task->space_id, task->rm_index_id, &len);
box_delete(task->space_id, task->rm_index_id, str, str + len, NULL);
}
Munus codicem expiration_breakable:
static bool
expirationd_breakable(struct expirationd_task *task)
{
return task->it_index_id != task->rm_index_id && task->it_index_type == ITER_GT;
}
application
Potes videre source code at
Source: www.habr.com