Binary search promises.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3711 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
2e1e4f90e7
commit
263a59f6c5
71
src/task.c
71
src/task.c
@ -58,7 +58,6 @@ typedef struct _promise_t promise_t;
|
|||||||
typedef struct _promise_t {
|
typedef struct _promise_t {
|
||||||
promiseid_t id;
|
promiseid_t id;
|
||||||
JSValue values[3];
|
JSValue values[3];
|
||||||
promise_t* next;
|
|
||||||
} promise_t;
|
} promise_t;
|
||||||
|
|
||||||
typedef struct _tf_task_t {
|
typedef struct _tf_task_t {
|
||||||
@ -1006,16 +1005,45 @@ tf_trace_t* tf_task_get_trace(tf_task_t* task)
|
|||||||
return task->_trace;
|
return task->_trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _promise_compare(const void* a, const void* b)
|
||||||
|
{
|
||||||
|
promiseid_t ida = (promiseid_t)(intptr_t)a;
|
||||||
|
const promise_t* pb = b;
|
||||||
|
return ida < pb->id ? -1 : pb->id < ida ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _insert_index(const void* key, const void* base, size_t count, size_t size, int (*compare)(const void*, const void*))
|
||||||
|
{
|
||||||
|
int lower = 0;
|
||||||
|
int upper = count;
|
||||||
|
while (lower < upper && lower < (int)count)
|
||||||
|
{
|
||||||
|
int guess = (lower + upper) / 2;
|
||||||
|
int result = compare(key, ((char*)base) + size * guess);
|
||||||
|
if (result < 0)
|
||||||
|
{
|
||||||
|
upper = guess;
|
||||||
|
}
|
||||||
|
else if (result > 0)
|
||||||
|
{
|
||||||
|
lower = guess + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return guess;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return lower;
|
||||||
|
}
|
||||||
|
|
||||||
static promise_t* _tf_task_find_promise(tf_task_t* task, promiseid_t id)
|
static promise_t* _tf_task_find_promise(tf_task_t* task, promiseid_t id)
|
||||||
{
|
{
|
||||||
for (promise_t* it = task->_promises; it; it = it->next)
|
if (!task->_promises)
|
||||||
{
|
{
|
||||||
if (it->id == id)
|
|
||||||
{
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
promise_t* it = bsearch((void*)(intptr_t)id, task->_promises, task->_promise_count, sizeof(promise_t), _promise_compare);
|
||||||
|
return it ? it : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _tf_task_trace_promises(tf_task_t* task)
|
static void _tf_task_trace_promises(tf_task_t* task)
|
||||||
@ -1025,17 +1053,13 @@ static void _tf_task_trace_promises(tf_task_t* task)
|
|||||||
|
|
||||||
static void _tf_task_free_promise(tf_task_t* task, promiseid_t id)
|
static void _tf_task_free_promise(tf_task_t* task, promiseid_t id)
|
||||||
{
|
{
|
||||||
for (promise_t** it = &task->_promises; *it; it = &(*it)->next)
|
promise_t* it = bsearch((void*)(intptr_t)id, task->_promises, task->_promise_count, sizeof(promise_t), _promise_compare);
|
||||||
|
if (it)
|
||||||
{
|
{
|
||||||
if ((*it)->id == id)
|
int index = it - task->_promises;
|
||||||
{
|
memmove(it, it + 1, sizeof(promise_t) * (task->_promise_count - index - 1));
|
||||||
promise_t* promise = *it;
|
|
||||||
*it = (*it)->next;
|
|
||||||
free(promise);
|
|
||||||
task->_promise_count--;
|
task->_promise_count--;
|
||||||
_tf_task_trace_promises(task);
|
_tf_task_trace_promises(task);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1046,15 +1070,16 @@ promiseid_t tf_task_allocate_promise(tf_task_t* task)
|
|||||||
promiseId = task->_nextPromise++;
|
promiseId = task->_nextPromise++;
|
||||||
} while (_tf_task_find_promise(task, promiseId));
|
} while (_tf_task_find_promise(task, promiseId));
|
||||||
|
|
||||||
promise_t* promise = malloc(sizeof(promise_t));
|
promise_t promise =
|
||||||
*promise = (promise_t)
|
|
||||||
{
|
{
|
||||||
.id = promiseId,
|
.id = promiseId,
|
||||||
.next = task->_promises,
|
|
||||||
.values = { JS_NULL, JS_NULL, JS_NULL },
|
.values = { JS_NULL, JS_NULL, JS_NULL },
|
||||||
};
|
};
|
||||||
promise->values[0] = JS_NewPromiseCapability(task->_context, &promise->values[1]);
|
promise.values[0] = JS_NewPromiseCapability(task->_context, &promise.values[1]);
|
||||||
task->_promises = promise;
|
int index = _insert_index((void*)(intptr_t)promiseId, task->_promises, task->_promise_count, sizeof(promise_t), _promise_compare);
|
||||||
|
task->_promises = realloc(task->_promises, sizeof(promise_t) * (task->_promise_count + 1));
|
||||||
|
memmove(task->_promises + index, task->_promises + index + 1, sizeof(promise_t) * (task->_promise_count - index));
|
||||||
|
task->_promises[index] = promise;
|
||||||
task->_promise_count++;
|
task->_promise_count++;
|
||||||
_tf_task_trace_promises(task);
|
_tf_task_trace_promises(task);
|
||||||
return promiseId;
|
return promiseId;
|
||||||
@ -1327,10 +1352,12 @@ void tf_task_destroy(tf_task_t* task)
|
|||||||
{
|
{
|
||||||
JS_FreeValue(task->_context, tf_taskstub_get_task_object(task->_parent));
|
JS_FreeValue(task->_context, tf_taskstub_get_task_object(task->_parent));
|
||||||
}
|
}
|
||||||
while (task->_promises)
|
while (task->_promise_count)
|
||||||
{
|
{
|
||||||
tf_task_reject_promise(task, task->_promises->id, JS_NULL);
|
tf_task_reject_promise(task, task->_promises[task->_promise_count - 1].id, JS_NULL);
|
||||||
}
|
}
|
||||||
|
free(task->_promises);
|
||||||
|
task->_promises = NULL;
|
||||||
JS_FreeValue(task->_context, task->_requires);
|
JS_FreeValue(task->_context, task->_requires);
|
||||||
JS_FreeValue(task->_context, task->_loadedFiles);
|
JS_FreeValue(task->_context, task->_loadedFiles);
|
||||||
while (task->_scriptExports)
|
while (task->_scriptExports)
|
||||||
|
Loading…
Reference in New Issue
Block a user