added qse_htl_yanknode(), qse_htl_upyank().
added qse_raddic_deletevendorbyname(), qse_raddic_deletevendorbyid()
This commit is contained in:
@ -578,9 +578,30 @@ qse_htl_node_t* qse_htl_update (qse_htl_t* ht, void* data)
|
||||
return node;
|
||||
}
|
||||
|
||||
qse_htl_node_t* qse_htl_upyank (qse_htl_t* ht, void* data, void** olddata)
|
||||
{
|
||||
qse_htl_node_t* node;
|
||||
void* datap, * olddatap;
|
||||
|
||||
node = qse_htl_search(ht, data);
|
||||
if (!node) return QSE_NULL;
|
||||
|
||||
if (ht->copier)
|
||||
{
|
||||
datap = ht->copier (ht, data);
|
||||
if (!datap) return QSE_NULL;
|
||||
}
|
||||
else datap = data;
|
||||
|
||||
*olddata = node->data;
|
||||
node->data = datap;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
qse_htl_node_t* qse_htl_ensert (qse_htl_t* ht, void* data)
|
||||
{
|
||||
qse_htl_node_t *node;
|
||||
qse_htl_node_t* node;
|
||||
|
||||
node = qse_htl_search(ht, data);
|
||||
if (!node) node = qse_htl_insert(ht, data);
|
||||
@ -588,19 +609,14 @@ qse_htl_node_t* qse_htl_ensert (qse_htl_t* ht, void* data)
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
* Yank an entry from the hash table, without freeing the data.
|
||||
*/
|
||||
void* qse_htl_yank (qse_htl_t* ht, void* data)
|
||||
|
||||
qse_htl_node_t* qse_htl_yanknode (qse_htl_t* ht, void* data)
|
||||
{
|
||||
qse_uint32_t key;
|
||||
qse_uint32_t entry;
|
||||
qse_uint32_t reversed;
|
||||
void *old;
|
||||
qse_htl_node_t* node;
|
||||
|
||||
if (!ht) return QSE_NULL;
|
||||
|
||||
key = ht->hasher(ht, data);
|
||||
entry = key & ht->mask;
|
||||
reversed = reverse(key);
|
||||
@ -613,9 +629,23 @@ void* qse_htl_yank (qse_htl_t* ht, void* data)
|
||||
list_delete(ht, &ht->buckets[entry], node);
|
||||
ht->num_elements--;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Yank an entry from the hash table, without freeing the data.
|
||||
*/
|
||||
void* qse_htl_yank (qse_htl_t* ht, void* data)
|
||||
{
|
||||
qse_htl_node_t* node;
|
||||
void* old;
|
||||
|
||||
node = qse_htl_yanknode (ht, data);
|
||||
if (!node) return QSE_NULL;
|
||||
|
||||
old = node->data;
|
||||
QSE_MMGR_FREE (ht->mmgr, node);
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
|
@ -217,7 +217,7 @@ qse_raddic_vendor_t* qse_raddic_findvendorbyvalue (qse_raddic_t* dic, int vendor
|
||||
qse_raddic_vendor_t* qse_raddic_addvendor (qse_raddic_t* dic, const qse_char_t* name, int value)
|
||||
{
|
||||
qse_size_t length;
|
||||
qse_raddic_vendor_t* dv;
|
||||
qse_raddic_vendor_t* dv, * old_dv;
|
||||
qse_htl_node_t* np;
|
||||
|
||||
if (value >= 65535) return QSE_NULL;
|
||||
@ -227,10 +227,11 @@ qse_raddic_vendor_t* qse_raddic_addvendor (qse_raddic_t* dic, const qse_char_t*
|
||||
/* no +1 for the terminating null because dv->name is char[1] */
|
||||
dv = QSE_MMGR_ALLOC(dic->mmgr, QSE_SIZEOF(*dv) + (length * QSE_SIZEOF(*name)));
|
||||
if (dv == QSE_NULL) return QSE_NULL;
|
||||
|
||||
|
||||
qse_strcpy(dv->name, name);
|
||||
dv->vendorpec = value;
|
||||
dv->type = dv->length = 1; /* defaults */
|
||||
dv->nextv = QSE_NULL;
|
||||
|
||||
/* return an existing item or insert a new item */
|
||||
np = qse_htl_ensert(&dic->vendors_byname, dv);
|
||||
@ -241,16 +242,96 @@ qse_raddic_vendor_t* qse_raddic_addvendor (qse_raddic_t* dic, const qse_char_t*
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
/* update indexing by value */
|
||||
if (!qse_htl_upsert(&dic->vendors_byvalue, dv))
|
||||
/* attempt to update the lookup table by value */
|
||||
np = qse_htl_upyank(&dic->vendors_byvalue, dv, (void**)&old_dv);
|
||||
if (np)
|
||||
{
|
||||
qse_htl_delete (&dic->vendors_byname, dv);
|
||||
return QSE_NULL;
|
||||
/* updated the existing item successfully.
|
||||
* link the old item to the current item */
|
||||
QSE_ASSERT (np->data == dv);
|
||||
QSE_ASSERT (dv->vendorpec == old_dv->vendorpec);
|
||||
dv->nextv = old_dv;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* update failure, this entry must be new. try insertion */
|
||||
if (!qse_htl_insert (&dic->vendors_byvalue, dv))
|
||||
{
|
||||
qse_htl_delete (&dic->vendors_byname, dv);
|
||||
return QSE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return dv;
|
||||
}
|
||||
|
||||
int qse_raddic_deletevendorbyname (qse_raddic_t* dic, const qse_char_t* name)
|
||||
{
|
||||
qse_raddic_vendor_t* dv, * dv2;
|
||||
|
||||
dv = qse_raddic_findvendorbyname(dic, name);
|
||||
if (!dv) return -1;
|
||||
|
||||
dv2 = qse_raddic_findvendorbyvalue(dic, dv->vendorpec);
|
||||
QSE_ASSERT (dv2 != QSE_NULL);
|
||||
|
||||
if (dv != dv2)
|
||||
{
|
||||
qse_raddic_vendor_t* x, * y;
|
||||
|
||||
QSE_ASSERT (qse_strcasecmp(dv->name, dv2->name) != 0);
|
||||
QSE_ASSERT (dv->vendorpec == dv2->vendorpec);
|
||||
|
||||
/* when the vendor of the given name is not the first one
|
||||
* referenced by value, i need to unlink the vendor from the
|
||||
* vendor chains with the same ID */
|
||||
x = dv2;
|
||||
y = QSE_NULL;
|
||||
while (x)
|
||||
{
|
||||
if (x == dv)
|
||||
{
|
||||
if (y) y->nextv = x->nextv;
|
||||
break;
|
||||
}
|
||||
y = x;
|
||||
x = x->nextv;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this is the only vendor with the vendor ID. i can
|
||||
* safely remove it from the lookup table by value */
|
||||
qse_htl_delete (&dic->vendors_byvalue, dv);
|
||||
}
|
||||
|
||||
/* delete the vendor from the lookup table by name */
|
||||
qse_htl_delete (&dic->vendors_byname, dv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qse_raddic_deletevendorbyvalue (qse_raddic_t* dic, int value)
|
||||
{
|
||||
qse_raddic_vendor_t* dv;
|
||||
|
||||
dv = qse_raddic_findvendorbyvalue(dic, value);
|
||||
if (!dv) return -1;
|
||||
|
||||
if (dv->nextv)
|
||||
{
|
||||
qse_htl_update (&dic->vendors_byvalue, dv->nextv);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this is the only vendor with the vendor ID. i can
|
||||
* safely remove it from the lookup table by value */
|
||||
qse_htl_delete (&dic->vendors_byvalue, dv);
|
||||
}
|
||||
|
||||
/* delete the vendor from the lookup table by name */
|
||||
qse_htl_delete (&dic->vendors_byname, dv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0 // XXX
|
||||
/*
|
||||
|
Reference in New Issue
Block a user