Skip to content

Commit

Permalink
#341 Performance improvements for resolve and declareChild
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Sep 18, 2015
1 parent 519c5f0 commit 92cd6c9
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 63 deletions.
2 changes: 1 addition & 1 deletion components/json/src/json.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static cx_int16 serializePrimitive(cx_serializer s, cx_value *v, void *userData)
CX_UNUSED(s);
cx_type type = cx_valueType(v);
cx_json_ser_t *data = userData;
cx_int16 result;
cx_int16 result = 0;
cx_string valueString;

switch (cx_primitive(type)->kind) {
Expand Down
2 changes: 1 addition & 1 deletion packages/corto/ast/src/ast_While.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ cx_int16 _ast_While_construct(ast_While this) {
ic_node _ast_While_toIc_v(ast_While this, ic_program program, ic_storage storage, cx_bool stored) {
/* $begin(::corto::ast::While::toIc) */
ic_storage accumulator;
ic_label labelEval, labelNeq;
ic_label labelEval, labelNeq = NULL;
ast_Expression condition = NULL;
cx_bool condResult = FALSE, inverse = FALSE;
ic_node expr = NULL;
Expand Down
2 changes: 2 additions & 0 deletions packages/corto/lang/include/cx_rbtree.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ void cx_rbtreeFree(cx_rbtree tree);
void* cx_rbtreeGet(cx_rbtree tree, void* key);
void* cx_rbtreeGetPtr(cx_rbtree tree, void* key);
void cx_rbtreeSet(cx_rbtree tree, const void* key, void* value);
void* cx_rbtreeFindOrSet(cx_rbtree tree, const void* key, void* value);
void cx_rbtreeRemove(cx_rbtree tree, void* key);
cx_bool cx_rbtreeHasKey(cx_rbtree tree, const void* key, void** value);
cx_bool cx_rbtreeHasKey_w_cmp(cx_rbtree tree, const void* key, void** value, cx_equalsAction cmp);
void* cx_rbtreeMin(cx_rbtree tree, void** key_out);
void* cx_rbtreeMax(cx_rbtree tree, void** key_out);
void* cx_rbtreeNext(cx_rbtree tree, void* key, void** key_out);
Expand Down
2 changes: 1 addition & 1 deletion packages/corto/lang/src/cx_copy_ser.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ static void cx_collection_resizeArray(cx_collection t, void* sequence, cx_uint32
static cx_int16 cx_ser_collection(cx_serializer s, cx_value *info, void* userData) {
cx_type t1, t2;
void *v1, *v2;
cx_uint32 size1;
cx_uint32 size1 = 0;
cx_copy_ser_t *data = userData;
cx_uint32 result = 0;

Expand Down
159 changes: 114 additions & 45 deletions packages/corto/lang/src/cx_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

extern cx_mutex_s cx_adminLock;

static int cx_adopt(cx_object parent, cx_object child);
static cx_object cx_adopt(cx_object parent, cx_object child);
static cx_int32 cx_notify(cx__observable *_o, cx_object observable, cx_uint32 mask);

static void cx_notifyObserverDefault(cx__observer* data, cx_object this, cx_object observable, cx_object source, cx_uint32 mask);
Expand Down Expand Up @@ -247,9 +247,10 @@ static void* cx__objectStartAddr(cx__object* o) {
}

/* Initialze scope-part of object */
static cx_int16 cx__initScope(cx_object o, cx_string name, cx_object parent) {
static cx_object cx__initScope(cx_object o, cx_string name, cx_object parent) {
cx__object* _o;
cx__scope* scope;
cx_object result = NULL;

_o = CX_OFFSET(o, -sizeof(cx__object));
scope = cx__objectScope(_o);
Expand All @@ -260,13 +261,18 @@ static cx_int16 cx__initScope(cx_object o, cx_string name, cx_object parent) {
cx_rwmutexNew(&scope->scopeLock);

/* Add object to the scope of the parent-object */
if (cx_adopt(parent, o)) {
if (!(result = cx_adopt(parent, o))) {
goto error;
}

return 0;
if (result != o) {
cx_dealloc(scope->name);
cx_rwmutexFree(&scope->scopeLock);
}

return result;
error:
return -1;
return NULL;
}

static void cx__deinitScope(cx_object o) {
Expand Down Expand Up @@ -497,7 +503,7 @@ int cx__adoptSSO(cx_object sso) {
/* Reset the parent to NULL, since cx_adopt will otherwise conclude that this object is adopted twice */
scope->parent = NULL;

return cx_adopt(parent, sso);
return !cx_adopt(parent, sso);
}

/* Find the right constructor to call */
Expand Down Expand Up @@ -554,7 +560,6 @@ int cx__destructor(cx_object o) {
return -1;
}

/* Set state on object */
void cx__setState(cx_object o, cx_uint8 state) {
cx__object* _o;

Expand All @@ -568,6 +573,44 @@ static cx_equalityKind cx_objectCompare(cx_type this, const void* o1, const void
return ((r = stricmp(o1, o2)) < 0) ? CX_LT : (r > 0) ? CX_GT : CX_EQ;
}

#include "ctype.h"
static cx_equalityKind cx_objectCompareLookup(cx_type this, const void* o1, const void* o2) {
CX_UNUSED(this);
int r;
const char *ptr1, *ptr2;
ptr1 = o1;
ptr2 = o2;
char ch1, ch2;

ch2 = *ptr2;
while((ch1 = *ptr1) && ch2) {
if (ch1 == ch2) {
if (ch1 == '(') {
r = 0;
goto compare;
}
ptr1++; ptr2++;
ch2 = *ptr2;
continue;
}
if (ch1 < 97) ch1 = tolower(ch1);

/* Query is always made lower case, for efficiency reasons */
/* if (ch2 < 97) ch2 = tolower(ch2); */
if (ch1 != ch2) {
r = ch1 - ch2;
goto compare;
}
ptr1++;
ptr2++;
ch2 = *ptr2;
}

r = ch1 - ch2;
compare:
return (r < 0) ? CX_LT : (r > 0) ? CX_GT : CX_EQ;
}

/* Match a state exclusively:
* CX_DECLARED - CX_DECLARED | CX_DEFINED
* CX_DECLARED X
Expand All @@ -590,7 +633,7 @@ static cx_bool cx__checkStateXOR(cx_object o, cx_uint8 state) {
}

/* Adopt an object */
static int cx_adopt(cx_object parent, cx_object child) {
static cx_object cx_adopt(cx_object parent, cx_object child) {
cx__object *_parent, *_child;
cx__scope *p_scope, *c_scope;
cx_type parentType;
Expand Down Expand Up @@ -644,7 +687,15 @@ static int cx_adopt(cx_object parent, cx_object child) {
if (!p_scope->scope) {
p_scope->scope = cx_rbtreeNew_w_func(cx_objectCompare);
}
cx_rbtreeSet(p_scope->scope, c_scope->name, child);

cx_object existing = cx_rbtreeFindOrSet(p_scope->scope, c_scope->name, child);
if (existing) {
if (cx_typeof(existing) != cx_typeof(child)) {
goto err_type_mismatch;
} else {
child = existing;
}
}

/* Parent must not be deleted before all childs are gone. */
cx_claim(parent);
Expand All @@ -656,31 +707,37 @@ static int cx_adopt(cx_object parent, cx_object child) {
goto err_no_parent_scope;
}

return 0;
return child;

err_child_mutex:
cx_critical("cx_adopt: lock operation on scopeLock of child failed");
return -1;
return NULL;

err_parent_mutex:
cx_critical("cx_adopt: lock operation on scopeLock of parent failed");
return -1;
return NULL;

err_already_adopted:
cx_rwmutexUnlock(&c_scope->scopeLock);
cx_seterr("cx_adopt: child-object is already adopted");
return -1;
return NULL;

err_type_mismatch:
cx_rwmutexUnlock(&p_scope->scopeLock);
cx_critical("'%s' is already declared with a different type",
c_scope->name);
return NULL;

err_no_parent_scope:
cx_critical("cx_adopt: parent-object is not scoped");
return -1;
return NULL;

err_no_child_scope:
cx_critical("cx_adopt: child-object is not scoped");
return -1;
return NULL;

err_invalid_parent:
return -1;
return NULL;
}

void cx_attach(cx_object parent, cx_object child) {
Expand Down Expand Up @@ -911,7 +968,7 @@ cx_object _cx_declare(cx_type type) {
} else {
cx_seterr("%s::init failed", cx_fullname(type, id));
}
goto error;
goto error_init;
}

/* Add object to anonymous cache */
Expand All @@ -925,6 +982,8 @@ cx_object _cx_declare(cx_type type) {
}

return CX_OFFSET(o, sizeof(cx__object));
error_init:
cx_release(type);
error:
if (o) cx_dealloc(cx__objectObservable(o));
return NULL;
Expand All @@ -938,26 +997,19 @@ cx_object _cx_declareChild(cx_object parent, cx_string name, cx_type type) {
parent = root_o;
}

/* Check if object already exists */
if ((o = cx_lookup(parent, name))) {
if (cx_typeof(o) != type) {
cx_seterr("object already declared with different type");
o = NULL;
goto error;
}
cx__scope *scope = cx__objectScope(CX_OFFSET(o, -sizeof(cx__object)));
cx_ainc(&scope->declared);
} else {
/* Create new object */
cx_attr oldAttr = cx_setAttr(cx_getAttr()|CX_ATTR_SCOPED);
o = cx_declare(type);
cx_setAttr(oldAttr);
/* Create new object */
cx_attr oldAttr = cx_setAttr(cx_getAttr()|CX_ATTR_SCOPED);
o = cx_declare(type);
cx_setAttr(oldAttr);

if (o) {
cx_object o_ret = NULL;
cx__object *_o = CX_OFFSET(o, -sizeof(cx__object));
/* Initialize object parameters. */

if (o) {
cx__object *_o = CX_OFFSET(o, -sizeof(cx__object));
/* Initialize object parameters. */
if (!cx__initScope(o, name, parent)) {
if ((o_ret = cx__initScope(o, name, parent))) {

if (o_ret == o) {
/* Observable administration needs to be initialized after the
* scope administration because it needs to setup the correct
* chain of parents to notify on an event. */
Expand All @@ -980,17 +1032,24 @@ cx_object _cx_declareChild(cx_object parent, cx_string name, cx_type type) {
/* Initially, an object is valid and declared */
_o->attrs.state |= CX_VALID;
} else {
cx__deinitScope(o);
cx_release(type);
cx_dealloc(cx__objectStartAddr(CX_OFFSET(o,-sizeof(cx__object))));
o = NULL;
goto error;
o = o_ret;
goto ok;
}

/* Notify parent of new object */
cx_notify(cx__objectObservable(CX_OFFSET(parent,-sizeof(cx__object))), o, CX_ON_DECLARE);
} else {
cx__deinitScope(o);
cx_release(type);
cx_dealloc(cx__objectStartAddr(CX_OFFSET(o,-sizeof(cx__object))));
o = NULL;
goto error;
}

/* Notify parent of new object */
cx_notify(cx__objectObservable(CX_OFFSET(parent,-sizeof(cx__object))), o, CX_ON_DECLARE);
}

ok:
return o;
error:
if (o) {
Expand Down Expand Up @@ -1844,7 +1903,7 @@ void cx_drop(cx_object o) {
}
}

cx_object cx_lookup(cx_object o, cx_string name) {
cx_object cx_lookupLowercase(cx_object o, cx_string name) {
cx_object result;
cx__object *_o, *_result;
cx__scope* scope;
Expand All @@ -1856,7 +1915,7 @@ cx_object cx_lookup(cx_object o, cx_string name) {
if (scope) {
cx_rwmutexRead(&scope->scopeLock);
if ((tree = scope->scope)) {
if ((!cx_rbtreeHasKey(tree, name, (void**)&result))) {
if ((!cx_rbtreeHasKey_w_cmp(tree, name, (void**)&result, cx_objectCompareLookup))) {
result = NULL;
} else {
/* Keep object. If the refcount was zero, this object will be deleted soon, so prevent the object from being referenced again. */
Expand Down Expand Up @@ -1889,6 +1948,15 @@ cx_object cx_lookup(cx_object o, cx_string name) {
return NULL;
}

cx_object cx_lookup(cx_object o, cx_string name) {
cx_id lower;
char *ptr = name, ch;
char *bptr = lower;
for(; (ch = *ptr); ptr++) *(bptr++) = tolower(ch);
*bptr = '\0';
return cx_lookupLowercase(o, lower);
}

/* Event handling. */
static cx__observer* cx_observerFind(cx_ll on, cx_observer observer, cx_object this) {
cx__observer* result;
Expand Down Expand Up @@ -3182,7 +3250,7 @@ cx_int16 cx_overload(cx_object object, cx_string requested, cx_int32* distance)
}

/* Validate if names of request and offered match */
if (strcmp(o_name, r_name)) {
if (stricmp(o_name, r_name)) {
goto nomatch;
}

Expand Down Expand Up @@ -3279,7 +3347,7 @@ int cx_lookupFunctionWalk(cx_object o, void* userData) {
} else {
cx_id name;
cx_signatureName(cx_nameof(o), name); /* Obtain function name */
if (!strcmp(name, data->request)) {
if (!stricmp(name, data->request)) {
d = INT_MAX-1;
}
}
Expand Down Expand Up @@ -3763,3 +3831,4 @@ cx_int16 cx_copya(cx_any *dst, cx_any src) {
dst->type = src.type;
return result;
}

12 changes: 11 additions & 1 deletion packages/corto/lang/src/cx_rbtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ void* cx_rbtreeGetPtr(cx_rbtree tree, void* key) {
}

void cx_rbtreeSet(cx_rbtree tree, const void* key, void* value) {
jsw_rbinsert((jsw_rbtree_t*)tree, (void*)key, value);
jsw_rbinsert((jsw_rbtree_t*)tree, (void*)key, value, NULL, TRUE);
}

void* cx_rbtreeFindOrSet(cx_rbtree tree, const void* key, void* value) {
void *old = NULL;
jsw_rbinsert((jsw_rbtree_t*)tree, (void*)key, value, &old, FALSE);
return old;
}

void cx_rbtreeRemove(cx_rbtree tree, void* key) {
Expand All @@ -50,6 +56,10 @@ cx_bool cx_rbtreeHasKey(cx_rbtree tree, const void* key, void** value) {
return jsw_rbhaskey((jsw_rbtree_t*)tree, key, value);
}

cx_bool cx_rbtreeHasKey_w_cmp(cx_rbtree tree, const void* key, void** value, cx_equalsAction cmp) {
return jsw_rbhaskey_w_cmp((jsw_rbtree_t*)tree, key, value, cmp);
}

cx_uint32 cx_rbtreeSize(cx_rbtree tree) {
return jsw_rbsize((jsw_rbtree_t*)tree);
}
Expand Down
Loading

0 comments on commit 92cd6c9

Please sign in to comment.