static gint _dyn_entry_cmp(const void *a, const void *b) { NVDynValue entry_a = *(NVDynValue *)a; NVDynValue entry_b = *(NVDynValue *)b; NVHandle handle_a = NV_TABLE_DYNVALUE_HANDLE(entry_a); NVHandle handle_b = NV_TABLE_DYNVALUE_HANDLE(entry_b); if (handle_a == handle_b) { return 0; } return (handle_a < handle_b) ? -1 : 1; }
static gboolean nv_table_reserve_table_entry(NVTable *self, NVHandle handle, NVDynValue **dyn_slot) { if (G_UNLIKELY(!(*dyn_slot) && handle > self->num_static_entries)) { /* this is a dynamic value */ NVDynValue *dyn_entries = nv_table_get_dyn_entries(self);; gint l, h, m, ndx; gboolean found = FALSE; if (!nv_table_alloc_check(self, sizeof(dyn_entries[0]))) return FALSE; l = 0; h = self->num_dyn_entries - 1; ndx = -1; while (l <= h) { guint16 mv; m = (l+h) >> 1; mv = NV_TABLE_DYNVALUE_HANDLE(dyn_entries[m]); if (mv == handle) { ndx = m; found = TRUE; break; } else if (mv > handle) { h = m - 1; } else { l = m + 1; } } /* if we find the proper slot we set that, if we don't, we insert a new entry */ if (!found) ndx = l; g_assert(ndx >= 0 && ndx <= self->num_dyn_entries); if (ndx < self->num_dyn_entries) { memmove(&dyn_entries[ndx + 1], &dyn_entries[ndx], (self->num_dyn_entries - ndx) * sizeof(dyn_entries[0])); } *dyn_slot = &dyn_entries[ndx]; /* we set ofs to zero here, which means that the NVEntry won't be found even if the slot is present in dyn_entries */ (**dyn_slot).handle = handle; (**dyn_slot).ofs = 0; if (!found) self->num_dyn_entries++; }
NVEntry * nv_table_get_entry_slow(NVTable *self, NVHandle handle, NVDynValue **dyn_slot) { guint32 ofs; gint l, h, m; NVDynValue *dyn_entries = nv_table_get_dyn_entries(self); guint32 mv; if (!self->num_dyn_entries) { *dyn_slot = NULL; return NULL; } /* open-coded binary search */ *dyn_slot = NULL; l = 0; h = self->num_dyn_entries - 1; ofs = 0; while (l <= h) { m = (l+h) >> 1; mv = NV_TABLE_DYNVALUE_HANDLE(dyn_entries[m]); if (mv == handle) { *dyn_slot = &dyn_entries[m]; ofs = NV_TABLE_DYNVALUE_OFS(dyn_entries[m]); break; } else if (mv > handle) { h = m - 1; } else { l = m + 1; } } NVEntry *entry = nv_table_get_entry_at_ofs(self, ofs); return entry; }