Skip to content

Commit

Permalink
#416 Added iteration over replicators to select
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Dec 2, 2015
1 parent 40e8dbf commit 58f64d3
Show file tree
Hide file tree
Showing 15 changed files with 151 additions and 107 deletions.
2 changes: 1 addition & 1 deletion packages/corto/lang/include/corto__api.h
Original file line number Diff line number Diff line change
Expand Up @@ -1759,7 +1759,7 @@ CORTO_LANG_EXPORT corto_int16 _corto_requestActionInit(corto_requestAction* valu
CORTO_LANG_EXPORT corto_int16 _corto_requestActionDeinit(corto_requestAction* value);
#define corto_requestActionDeinit(value) _corto_requestActionDeinit(value)

corto_int16 corto_requestActionCall(corto_requestAction *_delegate, corto_resultIter* _result, corto_string scope, corto_string expr);
corto_int16 corto_requestActionCall(corto_requestAction *_delegate, corto_resultIter* _result, corto_object scope, corto_string expr);
/* /corto/lang/result */
CORTO_LANG_EXPORT corto_result* _corto_resultCreate(corto_string name, corto_string parent, corto_string type);
#define corto_resultCreate(name, parent, type) _corto_resultCreate(name, parent, type)
Expand Down
33 changes: 18 additions & 15 deletions packages/corto/lang/include/corto_iter.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,23 @@ extern "C" {

#define CORTO_ITER_STACK_LIMIT (64)

#define CORTO_ITERATOR(_name)\
typedef struct _name _name;\
struct _name {\
void *udata;\
void (*moveFirst)(_name*);\
void* (*move)(_name*, unsigned int);\
int (*hasNext)(_name*);\
void* (*next)(_name*);\
void* (*nextPtr)(_name*);\
void* (*remove)(_name*);\
void (*insert)(_name*, void*);\
void (*set)(_name*, void*);\
}\

CORTO_ITERATOR(corto_iter);
/* Create a typedef, so generic iterator functions can be used with user
* defined iterator types */
#define CORTO_ITERATOR(_name) typedef corto_iter _name

typedef struct corto_iter corto_iter;
struct corto_iter {
void *udata;
void (*moveFirst)(corto_iter*);
void* (*move)(corto_iter*, unsigned int);
int (*hasNext)(corto_iter*);
void* (*next)(corto_iter*);
void* (*nextPtr)(corto_iter*);
void* (*remove)(corto_iter*);
void (*insert)(corto_iter*, void*);
void (*set)(corto_iter*, void*);
void (*release)(corto_iter*);
};

/* Generic iterator implementation */
void corto_iterMoveFirst(corto_iter* iter);
Expand All @@ -37,6 +39,7 @@ void* corto_iterNextPtr(corto_iter* iter);
void* corto_iterRemove(corto_iter* iter);
void corto_iterInsert(corto_iter* iter, void* o);
void corto_iterSet(corto_iter* iter, void* o);
void corto_iterRelease(corto_iter* iter);

#ifdef __cplusplus
}
Expand Down
9 changes: 2 additions & 7 deletions packages/corto/lang/include/corto_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,8 @@ corto_object corto_ownerof(corto_object o);
corto_object corto_lookup(corto_object scope, corto_string name);
corto_object corto_resolve(corto_object scope, corto_string expr);

typedef struct corto_selectItem {
corto_string parent;
corto_string name;
corto_string type;
} corto_selectItem;

corto_int16 corto_select(corto_object scope, corto_string expr, corto_iter *iter_out);
/* Iterate over object metadata matching a expression */
corto_int16 corto_select(corto_object scope, corto_string expr, corto_resultIter *iter_out);

/* Notifications */
corto_object corto_setOwner(corto_object owner);
Expand Down
2 changes: 1 addition & 1 deletion packages/corto/lang/include/corto_replicator.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ CORTO_LANG_EXPORT corto_void _corto_replicator_on_update(corto_replicator _this,
CORTO_LANG_EXPORT corto_void _corto_replicator_post(corto_replicator _this, corto_event e);
#define corto_replicator_post(_this, e) _corto_replicator_post(corto_replicator(_this), corto_event(e))

CORTO_LANG_EXPORT corto_resultIter _corto_replicator_request(corto_replicator _this, corto_string parent, corto_string expr);
CORTO_LANG_EXPORT corto_resultIter _corto_replicator_request(corto_replicator _this, corto_object parent, corto_string expr);
#define corto_replicator_request(_this, parent, expr) _corto_replicator_request(corto_replicator(_this), parent, expr)

#ifdef __cplusplus
Expand Down
2 changes: 1 addition & 1 deletion packages/corto/lang/src/corto.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ static void corto_patchSequences(void) {
corto_requestAction_o->parameters.length = 2;
corto_requestAction_o->parameters.buffer = corto_alloc(2 * sizeof(corto_parameter));
corto_requestAction_o->parameters.buffer[0].name = "scope";
corto_requestAction_o->parameters.buffer[0].type = corto_type(corto_string_o);
corto_requestAction_o->parameters.buffer[0].type = corto_type(corto_object_o);
corto_requestAction_o->parameters.buffer[0].passByReference = 0;

corto_requestAction_o->parameters.buffer[1].name = "expr";
Expand Down
2 changes: 1 addition & 1 deletion packages/corto/lang/src/corto__api.c
Original file line number Diff line number Diff line change
Expand Up @@ -6677,7 +6677,7 @@ corto_int16 _corto_requestActionDeinit(corto_requestAction* value) {
return result;
}

corto_int16 corto_requestActionCall(corto_requestAction *_delegate, corto_resultIter* _result, corto_string scope, corto_string expr) {
corto_int16 corto_requestActionCall(corto_requestAction *_delegate, corto_resultIter* _result, corto_object scope, corto_string expr) {
if (_delegate->_parent.procedure) {
if (_delegate->_parent.instance) {
corto_call(_delegate->_parent.procedure, _result, _delegate->_parent.instance, scope, expr);
Expand Down
2 changes: 1 addition & 1 deletion packages/corto/lang/src/corto__bootstrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,7 @@ CORTO_CLASS_NOBASE_O(replicator, NULL, CORTO_DECLARED | CORTO_DEFINED, NULL, NUL
CORTO_METHOD_O(replicator, destruct, "()", void, FALSE, corto_replicator_destruct);
CORTO_METHOD_O(replicator, post, "(event e)", void, FALSE, corto_replicator_post);
CORTO_METHOD_O(replicator, invoke, "(object instance,function proc,octetseq args)", void, FALSE, corto_replicator_invoke);
CORTO_METHOD_O(replicator, request, "(string parent,string expr)", resultIter, FALSE, corto_replicator_request);
CORTO_METHOD_O(replicator, request, "(object parent,string expr)", resultIter, FALSE, corto_replicator_request);
CORTO_MEMBER_O(replicator, onDeclare, notifyAction, CORTO_GLOBAL);
CORTO_MEMBER_O(replicator, onUpdate, notifyAction, CORTO_GLOBAL);
CORTO_MEMBER_O(replicator, onDelete, notifyAction, CORTO_GLOBAL);
Expand Down
4 changes: 2 additions & 2 deletions packages/corto/lang/src/corto__wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1078,8 +1078,8 @@ void __corto_replicator_request(corto_function f, void *result, void *args) {
CORTO_UNUSED(f);
*(corto_resultIter*)result = _corto_replicator_request(
corto_replicator(*(void**)args),
*(corto_string*)((intptr_t)args + sizeof(void*)),
*(corto_string*)((intptr_t)args + sizeof(void*) + sizeof(corto_string)));
*(corto_object*)((intptr_t)args + sizeof(void*)),
*(corto_string*)((intptr_t)args + sizeof(void*) + sizeof(corto_object)));
}

void __corto_sequence_construct(corto_function f, void *result, void *args) {
Expand Down
19 changes: 11 additions & 8 deletions packages/corto/lang/src/corto_iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,37 @@
#include "corto_iter.h"

void corto_iterMoveFirst(corto_iter* iter) {
iter->moveFirst(iter);
iter->moveFirst(iter);
}

void* corto_iterMove(corto_iter* iter, unsigned int index) {
return iter->move(iter, index);
return iter->move(iter, index);
}

int corto_iterHasNext(corto_iter* iter) {
return iter->hasNext(iter);
return iter->hasNext(iter);
}

void* corto_iterNext(corto_iter* iter) {
return iter->next(iter);
return iter->next(iter);
}

void* corto_iterNextPtr(corto_iter* iter) {
return iter->nextPtr(iter);
return iter->nextPtr(iter);
}

void* corto_iterRemove(corto_iter* iter) {
return iter->remove(iter);
return iter->remove(iter);
}

void corto_iterInsert(corto_iter* iter, void* o) {
iter->insert(iter, o);
iter->insert(iter, o);
}

void corto_iterSet(corto_iter* iter, void* o) {
iter->set(iter, o);
iter->set(iter, o);
}

void corto_iterRelease(corto_iter* iter) {
iter->release(iter);
}
2 changes: 1 addition & 1 deletion packages/corto/lang/src/corto_replicator.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ corto_void _corto_replicator_post(corto_replicator this, corto_event e) {
/* $end */
}

corto_resultIter _corto_replicator_request(corto_replicator this, corto_string parent, corto_string expr) {
corto_resultIter _corto_replicator_request(corto_replicator this, corto_object parent, corto_string expr) {
/* $begin(corto/lang/replicator/request) */
corto_resultIter result;
corto_requestActionCall(&this->onRequest, &result, parent, expr);
Expand Down
97 changes: 63 additions & 34 deletions packages/corto/lang/src/corto_select.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ typedef struct corto_selectData {
corto_id parent;
corto_id name;
corto_id type;
corto_selectItem item;
corto_selectItem *next;
corto_result item;
corto_result *next;
}corto_selectData;

static corto_selectData* corto_selectDataGet(void) {
Expand Down Expand Up @@ -270,7 +270,7 @@ static int corto_selectValidate(corto_selectData *data) {

static void corto_setItemData(
corto_object o,
corto_selectItem *item,
corto_result *item,
corto_selectData *data)
{
if (o != root_o) {
Expand Down Expand Up @@ -363,20 +363,47 @@ static corto_object corto_selectIterNext(
static void corto_selectRequestReplicators(
corto_selectData *data,
corto_selectStack *frame,
corto_ll replicators)
corto__scope *scope)
{
corto_iter iter = corto_llIter(replicators);

while (corto_iterHasNext(&iter)) {
corto_id parentId; corto_fullname(frame->o, parentId);
corto_replicator_olsData_t *odata = corto_iterNext(&iter);

/* Make select request to replicator */
data->replicators[data->activeReplicators ++] =
corto_replicator_request(
odata->replicator,
parentId,
frame->filter ? frame->filter : "*");
if (data->activeReplicators < 0) {
corto_ll replicators = corto_olsFind(scope, CORTO_OLS_REPLICATOR);
data->activeReplicators = 0;

if (replicators) {
corto_iter iter = corto_llIter(replicators);

while (corto_iterHasNext(&iter)) {
corto_replicator_olsData_t *odata = corto_iterNext(&iter);

/* Make select request to replicator */
data->replicators[data->activeReplicators ++] =
corto_replicator_request(
odata->replicator,
frame->o,
frame->filter ? frame->filter : "*");
}
}
}
}

static void corto_selectIterateReplicators(corto_selectData *data) {
if (data->activeReplicators) {
/* Walk over iterators until one with data available has been found */
while ((++data->currentReplicator < data->activeReplicators)) {
corto_resultIter *iter = &data->replicators[data->currentReplicator];
if (corto_iterHasNext(iter)) {
corto_result *result = corto_iterNext(iter);
data->next = &data->item;

/* Copy data, so replicator can safely release it */
strcpy(data->item.name, result->name);
strcpy(data->item.parent, result->parent);
strcpy(data->item.type, result->type);

/* Return item */
break;
}
}
}
}

Expand All @@ -390,27 +417,28 @@ static void corto_selectScope(
corto__scope *scope = corto__scopeClaim(frame->o);

/* Request replicators once per scope, and do it before iterating over
* corto store objects so replicators have some time to make the
* request */
if (data->activeReplicators < 0) {
corto_ll replicators = corto_olsFind(scope, CORTO_OLS_REPLICATOR);
data->activeReplicators = 0;

if (replicators) {
corto_selectRequestReplicators(data, frame, replicators);
}
}
* corto store objects so replicators have more time to fetch data. */
corto_selectRequestReplicators(data, frame, scope);

data->next = NULL;
while ((o = corto_selectIterNext(frame, lastKey))) {
if (!frame->filter || corto_selectMatch(frame->filter, corto_nameof(o))) {
data->next = &data->item;
corto_setItemData(o, data->next, data);
break;

/* If not iterating over a replicator, we're iterating over the store */
if (data->currentReplicator == -1) {
while ((o = corto_selectIterNext(frame, lastKey))) {
if (!frame->filter || corto_selectMatch(frame->filter, corto_nameof(o))) {
data->next = &data->item;
corto_setItemData(o, data->next, data);
break;
}
}
}

corto__scopeRelease(frame->o);

/* Handle replicator iteration outside of scope lock */
if (!data->next) {
corto_selectIterateReplicators(data);
}
}

/* Depth first search */
Expand Down Expand Up @@ -544,7 +572,7 @@ static int corto_selectRun(corto_selectData *data) {
return -1;
}

static int corto_selectHasNext(corto_iter *iter) {
static int corto_selectHasNext(corto_resultIter *iter) {
corto_selectData *data = corto_selectDataGet();
corto_selectStack *frame = &data->stack[data->sp];
CORTO_UNUSED(iter);
Expand All @@ -565,7 +593,7 @@ static int corto_selectHasNext(corto_iter *iter) {
* to check for two values */
}

static void* corto_selectNext(corto_iter *iter) {
static void* corto_selectNext(corto_resultIter *iter) {
corto_selectData *data = corto_selectDataGet();

CORTO_UNUSED(iter);
Expand All @@ -576,7 +604,7 @@ static void* corto_selectNext(corto_iter *iter) {
corto_int16 corto_select(
corto_object scope,
corto_string expr,
corto_iter *iter_out)
corto_resultIter *iter_out)
{
corto_selectData *data = corto_selectDataGet();

Expand All @@ -589,6 +617,7 @@ corto_int16 corto_select(
data->sp = 0;
data->next = NULL;
data->activeReplicators = -1;
data->currentReplicator = -1;

iter_out->hasNext = corto_selectHasNext;
iter_out->next = corto_selectNext;
Expand Down
20 changes: 20 additions & 0 deletions packages/corto/lang/test/include/test_selectItem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* test_selectItem.h
*
* This file contains generated code. Do not modify!
*/

#ifndef TEST_SELECTITEM_H
#define TEST_SELECTITEM_H

#include "corto.h"
#include "test__interface.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif
#endif

Loading

0 comments on commit 58f64d3

Please sign in to comment.