*optimized LIST indexing; *optimized LIST counting.
This commit is contained in:
parent
598e802ae7
commit
1f56b39a4f
4
HISTORY
4
HISTORY
@ -1,3 +1,7 @@
|
|||||||
|
Oct. 11 2015
|
||||||
|
Optimized LIST indexing
|
||||||
|
Optimized LIST counting
|
||||||
|
|
||||||
Oct. 10 2015
|
Oct. 10 2015
|
||||||
Improved stability for nested IF statement
|
Improved stability for nested IF statement
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ extern "C" {
|
|||||||
/** Macros */
|
/** Macros */
|
||||||
#define _VER_MAJOR 1
|
#define _VER_MAJOR 1
|
||||||
#define _VER_MINOR 1
|
#define _VER_MINOR 1
|
||||||
#define _VER_REVISION 82
|
#define _VER_REVISION 83
|
||||||
#define _VER_SUFFIX
|
#define _VER_SUFFIX
|
||||||
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
|
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
|
||||||
#define _STRINGIZE(A) _MAKE_STRINGIZE(A)
|
#define _STRINGIZE(A) _MAKE_STRINGIZE(A)
|
||||||
@ -302,6 +302,9 @@ typedef struct _list_t {
|
|||||||
_ref_t ref;
|
_ref_t ref;
|
||||||
_ls_node_t* list;
|
_ls_node_t* list;
|
||||||
_lock_t lock;
|
_lock_t lock;
|
||||||
|
_ls_node_t* cached_node;
|
||||||
|
int cached_index;
|
||||||
|
unsigned int count;
|
||||||
} _list_t;
|
} _list_t;
|
||||||
|
|
||||||
typedef struct _list_it_t {
|
typedef struct _list_it_t {
|
||||||
@ -762,7 +765,6 @@ static _ls_node_t* _ls_find(_ls_node_t* list, void* data, _ls_compare cmp);
|
|||||||
static _ls_node_t* _ls_back(_ls_node_t* node);
|
static _ls_node_t* _ls_back(_ls_node_t* node);
|
||||||
static _ls_node_t* _ls_pushback(_ls_node_t* list, void* data);
|
static _ls_node_t* _ls_pushback(_ls_node_t* list, void* data);
|
||||||
static void* _ls_popback(_ls_node_t* list);
|
static void* _ls_popback(_ls_node_t* list);
|
||||||
static _ls_node_t* _ls_at(_ls_node_t* list, int index);
|
|
||||||
static _ls_node_t* _ls_insert_at(_ls_node_t* list, int index, void* data);
|
static _ls_node_t* _ls_insert_at(_ls_node_t* list, int index, void* data);
|
||||||
static unsigned int _ls_remove(_ls_node_t* list, _ls_node_t* node, _ls_operation op);
|
static unsigned int _ls_remove(_ls_node_t* list, _ls_node_t* node, _ls_operation op);
|
||||||
static unsigned int _ls_try_remove(_ls_node_t* list, void* info, _ls_compare cmp, _ls_operation op);
|
static unsigned int _ls_try_remove(_ls_node_t* list, void* info, _ls_compare cmp, _ls_operation op);
|
||||||
@ -956,10 +958,12 @@ static bool_t _pop_list(_list_t* coll, mb_value_t* val, mb_interpreter_t* s);
|
|||||||
static bool_t _insert_list(_list_t* coll, int_t idx, mb_value_t* val, _object_t** oval);
|
static bool_t _insert_list(_list_t* coll, int_t idx, mb_value_t* val, _object_t** oval);
|
||||||
static bool_t _set_list(_list_t* coll, int_t idx, mb_value_t* val, _object_t** oval);
|
static bool_t _set_list(_list_t* coll, int_t idx, mb_value_t* val, _object_t** oval);
|
||||||
static bool_t _remove_at_list(_list_t* coll, int_t idx);
|
static bool_t _remove_at_list(_list_t* coll, int_t idx);
|
||||||
|
static _ls_node_t* _node_at_list(_list_t* coll, int index);
|
||||||
static bool_t _at_list(_list_t* coll, int_t idx, mb_value_t* oval);
|
static bool_t _at_list(_list_t* coll, int_t idx, mb_value_t* oval);
|
||||||
static bool_t _find_list(_list_t* coll, mb_value_t* val);
|
static bool_t _find_list(_list_t* coll, mb_value_t* val);
|
||||||
static void _clear_list(_list_t* coll);
|
static void _clear_list(_list_t* coll);
|
||||||
static void _sort_list(_list_t* coll);
|
static void _sort_list(_list_t* coll);
|
||||||
|
static void _invalidate_list_cache(_list_t* coll);
|
||||||
static void _set_dict(_dict_t* coll, mb_value_t* key, mb_value_t *val);
|
static void _set_dict(_dict_t* coll, mb_value_t* key, mb_value_t *val);
|
||||||
static bool_t _remove_dict(_dict_t* coll, mb_value_t* key);
|
static bool_t _remove_dict(_dict_t* coll, mb_value_t* key);
|
||||||
static bool_t _find_dict(_dict_t* coll, mb_value_t* val, mb_value_t* oval);
|
static bool_t _find_dict(_dict_t* coll, mb_value_t* val, mb_value_t* oval);
|
||||||
@ -1408,23 +1412,6 @@ void* _ls_popback(_ls_node_t* list) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ls_node_t* _ls_at(_ls_node_t* list, int index) {
|
|
||||||
_ls_node_t* result = 0;
|
|
||||||
_ls_node_t* tmp = 0;
|
|
||||||
|
|
||||||
mb_assert(list);
|
|
||||||
|
|
||||||
tmp = list->next;
|
|
||||||
while(tmp && index) {
|
|
||||||
tmp = tmp->next;
|
|
||||||
--index;
|
|
||||||
}
|
|
||||||
if(tmp)
|
|
||||||
result = tmp;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ls_node_t* _ls_insert_at(_ls_node_t* list, int index, void* data) {
|
_ls_node_t* _ls_insert_at(_ls_node_t* list, int index, void* data) {
|
||||||
_ls_node_t* result = 0;
|
_ls_node_t* result = 0;
|
||||||
_ls_node_t* tmp = 0;
|
_ls_node_t* tmp = 0;
|
||||||
@ -4051,8 +4038,10 @@ void _push_list(_list_t* coll, mb_value_t* val) {
|
|||||||
|
|
||||||
_create_internal_object_from_public_value(val, &oarg);
|
_create_internal_object_from_public_value(val, &oarg);
|
||||||
_ls_pushback(coll->list, oarg);
|
_ls_pushback(coll->list, oarg);
|
||||||
|
coll->count++;
|
||||||
|
|
||||||
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
||||||
|
_invalidate_list_cache(coll);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t _pop_list(_list_t* coll, mb_value_t* val, mb_interpreter_t* s) {
|
bool_t _pop_list(_list_t* coll, mb_value_t* val, mb_interpreter_t* s) {
|
||||||
@ -4065,11 +4054,13 @@ bool_t _pop_list(_list_t* coll, mb_value_t* val, mb_interpreter_t* s) {
|
|||||||
if(oval) {
|
if(oval) {
|
||||||
_internal_object_to_public_value(oval, val);
|
_internal_object_to_public_value(oval, val);
|
||||||
_destroy_object_capsule_only(oval, 0);
|
_destroy_object_capsule_only(oval, 0);
|
||||||
|
coll->count--;
|
||||||
|
|
||||||
if(val->type == MB_DT_STRING)
|
if(val->type == MB_DT_STRING)
|
||||||
_mark_lazy_destroy_string(s, val->value.string);
|
_mark_lazy_destroy_string(s, val->value.string);
|
||||||
|
|
||||||
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
||||||
|
_invalidate_list_cache(coll);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@ -4090,7 +4081,9 @@ bool_t _insert_list(_list_t* coll, int_t idx, mb_value_t* val, _object_t** oval)
|
|||||||
*oval = oarg;
|
*oval = oarg;
|
||||||
|
|
||||||
if(_ls_insert_at(coll->list, (int)idx, oarg)) {
|
if(_ls_insert_at(coll->list, (int)idx, oarg)) {
|
||||||
|
coll->count++;
|
||||||
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
||||||
|
_invalidate_list_cache(coll);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4105,7 +4098,7 @@ bool_t _set_list(_list_t* coll, int_t idx, mb_value_t* val, _object_t** oval) {
|
|||||||
|
|
||||||
mb_assert(coll && val);
|
mb_assert(coll && val);
|
||||||
|
|
||||||
result = _ls_at(coll->list, (int)idx);
|
result = _node_at_list(coll, (int)idx);
|
||||||
if(result) {
|
if(result) {
|
||||||
if(result->data)
|
if(result->data)
|
||||||
_destroy_object(result->data, 0);
|
_destroy_object(result->data, 0);
|
||||||
@ -4115,6 +4108,7 @@ bool_t _set_list(_list_t* coll, int_t idx, mb_value_t* val, _object_t** oval) {
|
|||||||
result->data = oarg;
|
result->data = oarg;
|
||||||
|
|
||||||
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
||||||
|
_invalidate_list_cache(coll);
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!(result && result->data);
|
return !!(result && result->data);
|
||||||
@ -4127,12 +4121,14 @@ bool_t _remove_at_list(_list_t* coll, int_t idx) {
|
|||||||
|
|
||||||
mb_assert(coll);
|
mb_assert(coll);
|
||||||
|
|
||||||
node = _ls_at(coll->list, (int)idx);
|
node = _node_at_list(coll, (int)idx);
|
||||||
if(node) {
|
if(node) {
|
||||||
if(node->data) {
|
if(node->data) {
|
||||||
_ls_remove(coll->list, node, _destroy_object);
|
_ls_remove(coll->list, node, _destroy_object);
|
||||||
|
coll->count--;
|
||||||
|
|
||||||
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
||||||
|
_invalidate_list_cache(coll);
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
@ -4141,13 +4137,50 @@ bool_t _remove_at_list(_list_t* coll, int_t idx) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ls_node_t* _node_at_list(_list_t* coll, int index) {
|
||||||
|
/* Get a node at a specific index in a list */
|
||||||
|
_ls_node_t* result = 0;
|
||||||
|
_ls_node_t* tmp = 0;
|
||||||
|
int idx = index;
|
||||||
|
|
||||||
|
mb_assert(coll);
|
||||||
|
|
||||||
|
if(index >= 0 && index < (int)coll->count) {
|
||||||
|
if(coll->cached_node && !(index < coll->cached_index / 2)) {
|
||||||
|
while(index != coll->cached_index) {
|
||||||
|
if(index > coll->cached_index) {
|
||||||
|
coll->cached_node = coll->cached_node->next;
|
||||||
|
coll->cached_index++;
|
||||||
|
} else if(index < coll->cached_index) {
|
||||||
|
coll->cached_node = coll->cached_node->prev;
|
||||||
|
coll->cached_node--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = coll->cached_node;
|
||||||
|
} else {
|
||||||
|
tmp = coll->list->next;
|
||||||
|
while(tmp && idx) {
|
||||||
|
tmp = tmp->next;
|
||||||
|
--idx;
|
||||||
|
}
|
||||||
|
if(tmp) {
|
||||||
|
result = tmp;
|
||||||
|
coll->cached_node = tmp;
|
||||||
|
coll->cached_index = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool_t _at_list(_list_t* coll, int_t idx, mb_value_t* oval) {
|
bool_t _at_list(_list_t* coll, int_t idx, mb_value_t* oval) {
|
||||||
/* Get the value in a list with a specific index */
|
/* Get the value in a list with a specific index */
|
||||||
_ls_node_t* result = 0;
|
_ls_node_t* result = 0;
|
||||||
|
|
||||||
mb_assert(coll && oval);
|
mb_assert(coll && oval);
|
||||||
|
|
||||||
result = _ls_at(coll->list, idx);
|
result = _node_at_list(coll, idx);
|
||||||
if(oval && result && result->data)
|
if(oval && result && result->data)
|
||||||
_internal_object_to_public_value(result->data, oval);
|
_internal_object_to_public_value(result->data, oval);
|
||||||
|
|
||||||
@ -4174,8 +4207,10 @@ void _clear_list(_list_t* coll) {
|
|||||||
|
|
||||||
_ls_foreach(coll->list, _destroy_object);
|
_ls_foreach(coll->list, _destroy_object);
|
||||||
_ls_clear(coll->list);
|
_ls_clear(coll->list);
|
||||||
|
coll->count = 0;
|
||||||
|
|
||||||
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
||||||
|
_invalidate_list_cache(coll);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _sort_list(_list_t* coll) {
|
void _sort_list(_list_t* coll) {
|
||||||
@ -4185,6 +4220,15 @@ void _sort_list(_list_t* coll) {
|
|||||||
_ls_sort(coll->list, (_ls_compare)_ht_cmp_object);
|
_ls_sort(coll->list, (_ls_compare)_ht_cmp_object);
|
||||||
|
|
||||||
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
||||||
|
_invalidate_list_cache(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _invalidate_list_cache(_list_t* coll) {
|
||||||
|
/* Invalidate cached list index */
|
||||||
|
mb_assert(coll);
|
||||||
|
|
||||||
|
coll->cached_node = 0;
|
||||||
|
coll->cached_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _set_dict(_dict_t* coll, mb_value_t* key, mb_value_t *val) {
|
void _set_dict(_dict_t* coll, mb_value_t* key, mb_value_t *val) {
|
||||||
@ -8973,7 +9017,7 @@ int _std_len(mb_interpreter_t* s, void** l) {
|
|||||||
#ifdef MB_ENABLE_COLLECTION_LIB
|
#ifdef MB_ENABLE_COLLECTION_LIB
|
||||||
case MB_DT_LIST:
|
case MB_DT_LIST:
|
||||||
lst = (_list_t*)arg.value.list;
|
lst = (_list_t*)arg.value.list;
|
||||||
mb_check(mb_push_int(s, l, (int_t)_ls_count(lst->list)));
|
mb_check(mb_push_int(s, l, (int_t)lst->count));
|
||||||
_assign_public_value(&arg, 0);
|
_assign_public_value(&arg, 0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user