Skip to content

Commit

Permalink
Merge pull request #16836 from bfredl/mark2
Browse files Browse the repository at this point in the history
refactor(marks): use a more efficient representation with less pointer indirection
  • Loading branch information
bfredl committed Jan 15, 2022
2 parents b455e01 + 95ab979 commit 561df30
Show file tree
Hide file tree
Showing 15 changed files with 462 additions and 460 deletions.
11 changes: 6 additions & 5 deletions src/nvim/api/deprecated.c
Expand Up @@ -130,7 +130,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A
return 0;
}

uint64_t ns_id = src2ns(&src_id);
uint32_t ns_id = src2ns(&src_id);
int width;

VirtText virt_text = parse_virt_text(chunks, err, &width);
Expand All @@ -148,11 +148,12 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A
return src_id;
}

Decoration *decor = xcalloc(1, sizeof(*decor));
decor->virt_text = virt_text;
decor->virt_text_width = width;
Decoration decor = DECORATION_INIT;
decor.virt_text = virt_text;
decor.virt_text_width = width;
decor.priority = 0;

extmark_set(buf, ns_id, NULL, (int)line, 0, -1, -1, decor, true,
extmark_set(buf, ns_id, NULL, (int)line, 0, -1, -1, &decor, true,
false, kExtmarkNoUndo);
return src_id;
}
Expand Down
95 changes: 40 additions & 55 deletions src/nvim/api/extmark.c
Expand Up @@ -85,12 +85,12 @@ const char *describe_ns(NS ns_id)
}

// Is the Namespace in use?
static bool ns_initialized(uint64_t ns)
static bool ns_initialized(uint32_t ns)
{
if (ns < 1) {
return false;
}
return ns < (uint64_t)next_namespace_id;
return ns < (uint32_t)next_namespace_id;
}


Expand All @@ -111,27 +111,27 @@ static Array extmark_to_array(ExtmarkInfo extmark, bool id, bool add_dict)
PUT(dict, "end_col", INTEGER_OBJ(extmark.end_col));
}

if (extmark.decor) {
Decoration *decor = extmark.decor;
if (decor->hl_id) {
String name = cstr_to_string((const char *)syn_id2name(decor->hl_id));
PUT(dict, "hl_group", STRING_OBJ(name));
}
if (kv_size(decor->virt_text)) {
Array chunks = ARRAY_DICT_INIT;
for (size_t i = 0; i < decor->virt_text.size; i++) {
Array chunk = ARRAY_DICT_INIT;
VirtTextChunk *vtc = &decor->virt_text.items[i];
ADD(chunk, STRING_OBJ(cstr_to_string(vtc->text)));
if (vtc->hl_id > 0) {
ADD(chunk,
STRING_OBJ(cstr_to_string((const char *)syn_id2name(vtc->hl_id))));
}
ADD(chunks, ARRAY_OBJ(chunk));
Decoration *decor = &extmark.decor;
if (decor->hl_id) {
String name = cstr_to_string((const char *)syn_id2name(decor->hl_id));
PUT(dict, "hl_group", STRING_OBJ(name));
}
if (kv_size(decor->virt_text)) {
Array chunks = ARRAY_DICT_INIT;
for (size_t i = 0; i < decor->virt_text.size; i++) {
Array chunk = ARRAY_DICT_INIT;
VirtTextChunk *vtc = &decor->virt_text.items[i];
ADD(chunk, STRING_OBJ(cstr_to_string(vtc->text)));
if (vtc->hl_id > 0) {
ADD(chunk,
STRING_OBJ(cstr_to_string((const char *)syn_id2name(vtc->hl_id))));
}
PUT(dict, "virt_text", ARRAY_OBJ(chunks));
ADD(chunks, ARRAY_OBJ(chunk));
}
PUT(dict, "virt_text", ARRAY_OBJ(chunks));
}

if (decor->hl_id || kv_size(decor->virt_text)) {
PUT(dict, "priority", INTEGER_OBJ(decor->priority));
}

Expand Down Expand Up @@ -166,7 +166,7 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id,
return rv;
}

if (!ns_initialized((uint64_t)ns_id)) {
if (!ns_initialized((uint32_t)ns_id)) {
api_set_error(err, kErrorTypeValidation, "Invalid ns_id");
return rv;
}
Expand All @@ -191,7 +191,7 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id,
}


ExtmarkInfo extmark = extmark_from_id(buf, (uint64_t)ns_id, (uint64_t)id);
ExtmarkInfo extmark = extmark_from_id(buf, (uint32_t)ns_id, (uint32_t)id);
if (extmark.row < 0) {
return rv;
}
Expand Down Expand Up @@ -252,7 +252,7 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
return rv;
}

if (!ns_initialized((uint64_t)ns_id)) {
if (!ns_initialized((uint32_t)ns_id)) {
api_set_error(err, kErrorTypeValidation, "Invalid ns_id");
return rv;
}
Expand Down Expand Up @@ -310,7 +310,7 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
}


ExtmarkInfoArray marks = extmark_get(buf, (uint64_t)ns_id, l_row, l_col,
ExtmarkInfoArray marks = extmark_get(buf, (uint32_t)ns_id, l_row, l_col,
u_row, u_col, (int64_t)limit, reverse);

for (size_t i = 0; i < kv_size(marks); i++) {
Expand Down Expand Up @@ -421,14 +421,14 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
goto error;
}

if (!ns_initialized((uint64_t)ns_id)) {
if (!ns_initialized((uint32_t)ns_id)) {
api_set_error(err, kErrorTypeValidation, "Invalid ns_id");
goto error;
}

uint64_t id = 0;
uint32_t id = 0;
if (opts->id.type == kObjectTypeInteger && opts->id.data.integer > 0) {
id = (uint64_t)opts->id.data.integer;
id = (uint32_t)opts->id.data.integer;
} else if (HAS_KEY(opts->id)) {
api_set_error(err, kErrorTypeValidation, "id is not a positive integer");
goto error;
Expand Down Expand Up @@ -653,20 +653,6 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
col2 = 0;
}

Decoration *d = NULL;

if (ephemeral) {
d = &decor;
} else if (kv_size(decor.virt_text) || kv_size(decor.virt_lines)
|| decor.priority != DECOR_PRIORITY_BASE
|| decor.hl_eol) {
// TODO(bfredl): this is a bit sketchy. eventually we should
// have predefined decorations for both marks/ephemerals
d = xcalloc(1, sizeof(*d));
*d = decor;
} else if (decor.hl_id) {
d = decor_hl(decor.hl_id);
}

// TODO(bfredl): synergize these two branches even more
if (ephemeral && decor_state.buf == buf) {
Expand All @@ -677,12 +663,8 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
goto error;
}

extmark_set(buf, (uint64_t)ns_id, &id, (int)line, (colnr_T)col, line2, col2,
d, right_gravity, end_right_gravity, kExtmarkNoUndo);

if (kv_size(decor.virt_lines)) {
redraw_buf_line_later(buf, MIN(buf->b_ml.ml_line_count, line+1+(decor.virt_lines_above?0:1)));
}
extmark_set(buf, (uint32_t)ns_id, &id, (int)line, (colnr_T)col, line2, col2,
&decor, right_gravity, end_right_gravity, kExtmarkNoUndo);
}

return (Integer)id;
Expand All @@ -707,23 +689,23 @@ Boolean nvim_buf_del_extmark(Buffer buffer, Integer ns_id, Integer id, Error *er
if (!buf) {
return false;
}
if (!ns_initialized((uint64_t)ns_id)) {
if (!ns_initialized((uint32_t)ns_id)) {
api_set_error(err, kErrorTypeValidation, "Invalid ns_id");
return false;
}

return extmark_del(buf, (uint64_t)ns_id, (uint64_t)id);
return extmark_del(buf, (uint32_t)ns_id, (uint32_t)id);
}

uint64_t src2ns(Integer *src_id)
uint32_t src2ns(Integer *src_id)
{
if (*src_id == 0) {
*src_id = nvim_create_namespace((String)STRING_INIT);
}
if (*src_id < 0) {
return UINT64_MAX;
return (((uint32_t)1) << 31) - 1;
} else {
return (uint64_t)(*src_id);
return (uint32_t)(*src_id);
}
}

Expand Down Expand Up @@ -778,7 +760,7 @@ Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, In
col_end = MAXCOL;
}

uint64_t ns = src2ns(&ns_id);
uint32_t ns = src2ns(&ns_id);

if (!(line < buf->b_ml.ml_line_count)) {
// safety check, we can't add marks outside the range
Expand All @@ -798,10 +780,13 @@ Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, In
end_line++;
}

Decoration decor = DECORATION_INIT;
decor.hl_id = hl_id;

extmark_set(buf, ns, NULL,
(int)line, (colnr_T)col_start,
end_line, (colnr_T)col_end,
decor_hl(hl_id), true, false, kExtmarkNoUndo);
&decor, true, false, kExtmarkNoUndo);
return ns_id;
}

Expand Down Expand Up @@ -833,7 +818,7 @@ void nvim_buf_clear_namespace(Buffer buffer, Integer ns_id, Integer line_start,
if (line_end < 0 || line_end > MAXLNUM) {
line_end = MAXLNUM;
}
extmark_clear(buf, (ns_id < 0 ? 0 : (uint64_t)ns_id),
extmark_clear(buf, (ns_id < 0 ? 0 : (uint32_t)ns_id),
(int)line_start, 0,
(int)line_end-1, MAXCOL);
}
Expand Down
2 changes: 1 addition & 1 deletion src/nvim/api/private/helpers.c
Expand Up @@ -1141,7 +1141,7 @@ bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, int
return false;
}

ExtmarkInfo extmark = extmark_from_id(buf, (uint64_t)ns_id, (uint64_t)id);
ExtmarkInfo extmark = extmark_from_id(buf, (uint32_t)ns_id, (uint32_t)id);
if (extmark.row >= 0) {
*row = extmark.row;
*col = extmark.col;
Expand Down
3 changes: 1 addition & 2 deletions src/nvim/buffer_defs.h
Expand Up @@ -866,8 +866,7 @@ struct file_buffer {
int b_mapped_ctrl_c; // modes where CTRL-C is mapped

MarkTree b_marktree[1];
Map(uint64_t, ExtmarkItem) b_extmark_index[1];
Map(uint64_t, ExtmarkNs) b_extmark_ns[1]; // extmark namespaces
Map(uint32_t, uint32_t) b_extmark_ns[1]; // extmark namespaces
size_t b_virt_line_blocks; // number of virt_line blocks

// array of channel_id:s which have asked to receive updates for this
Expand Down

0 comments on commit 561df30

Please sign in to comment.