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:
Cory McWilliams 2021-12-28 17:44:48 +00:00
parent 2e1e4f90e7
commit 263a59f6c5

View File

@ -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;
}
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);
task->_promise_count--;
_tf_task_trace_promises(task);
break;
}
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);
}
}
@ -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)