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 { 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 NULL;
{
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) 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; task->_promise_count--;
*it = (*it)->next; _tf_task_trace_promises(task);
free(promise);
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++; 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)