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 {
|
||||
promiseid_t id;
|
||||
JSValue values[3];
|
||||
promise_t* next;
|
||||
} promise_t;
|
||||
|
||||
typedef struct _tf_task_t {
|
||||
@ -1006,16 +1005,45 @@ tf_trace_t* tf_task_get_trace(tf_task_t* task)
|
||||
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)
|
||||
{
|
||||
for (promise_t* it = task->_promises; it; it = it->next)
|
||||
if (!task->_promises)
|
||||
{
|
||||
if (it->id == id)
|
||||
{
|
||||
return it;
|
||||
}
|
||||
}
|
||||
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)
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
promise_t* promise = *it;
|
||||
*it = (*it)->next;
|
||||
free(promise);
|
||||
int index = it - task->_promises;
|
||||
memmove(it, it + 1, sizeof(promise_t) * (task->_promise_count - index - 1));
|
||||
task->_promise_count--;
|
||||
_tf_task_trace_promises(task);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1046,15 +1070,16 @@ promiseid_t tf_task_allocate_promise(tf_task_t* task)
|
||||
promiseId = task->_nextPromise++;
|
||||
} while (_tf_task_find_promise(task, promiseId));
|
||||
|
||||
promise_t* promise = malloc(sizeof(promise_t));
|
||||
*promise = (promise_t)
|
||||
promise_t promise =
|
||||
{
|
||||
.id = promiseId,
|
||||
.next = task->_promises,
|
||||
.values = { JS_NULL, JS_NULL, JS_NULL },
|
||||
};
|
||||
promise->values[0] = JS_NewPromiseCapability(task->_context, &promise->values[1]);
|
||||
task->_promises = promise;
|
||||
promise.values[0] = JS_NewPromiseCapability(task->_context, &promise.values[1]);
|
||||
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++;
|
||||
_tf_task_trace_promises(task);
|
||||
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));
|
||||
}
|
||||
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->_loadedFiles);
|
||||
while (task->_scriptExports)
|
||||
|
Loading…
Reference in New Issue
Block a user