gbproxy: convert nse->bvcs from llist_head to hashtable
For the common lookup-by-bvci, this should reduce the computational
complexity significantly.
Depends: libosmocore.git I8ef73a62fe9846ce45058eb21cf999dd3eed5741
Change-Id: Ic8e9279fd61a3c514fc3203429f36a468f0e81d3
diff --git a/src/gb_proxy_peer.c b/src/gb_proxy_peer.c
index 00bff20..f5a4376 100644
--- a/src/gb_proxy_peer.c
+++ b/src/gb_proxy_peer.c
@@ -90,7 +90,7 @@
hash_for_each(cfg->bss_nses, i, nse, list) {
struct gbproxy_bvc *bvc;
- llist_for_each_entry(bvc, &nse->bvcs, list) {
+ hash_for_each_possible(nse->bvcs, bvc, list, bvci) {
if (bvc->bvci == bvci)
return bvc;
}
@@ -104,9 +104,15 @@
uint16_t nsei)
{
struct gbproxy_nse *nse = gbproxy_nse_by_nsei(cfg, nsei);
+ struct gbproxy_bvc *bvc;
+ int i;
- if (nse && !llist_empty(&nse->bvcs))
- return llist_first_entry(&nse->bvcs, struct gbproxy_bvc, list);
+ if (!nse || hash_empty(nse->bvcs))
+ return NULL;
+
+ /* return the first entry we find */
+ hash_for_each(nse->bvcs, i, bvc, list)
+ return bvc;
return NULL;
}
@@ -117,11 +123,11 @@
const uint8_t *ra)
{
struct gbproxy_nse *nse;
- int i;
+ int i, j;
hash_for_each(cfg->bss_nses, i, nse, list) {
struct gbproxy_bvc *bvc;
- llist_for_each_entry(bvc, &nse->bvcs, list) {
+ hash_for_each(nse->bvcs, j, bvc, list) {
if (!memcmp(bvc->ra, ra, 6))
return bvc;
}
@@ -136,11 +142,11 @@
const uint8_t *la)
{
struct gbproxy_nse *nse;
- int i;
+ int i, j;
hash_for_each(cfg->bss_nses, i, nse, list) {
struct gbproxy_bvc *bvc;
- llist_for_each_entry(bvc, &nse->bvcs, list) {
+ hash_for_each(nse->bvcs, j, bvc, list) {
if (!memcmp(bvc->ra, la, 5))
return bvc;
}
@@ -154,11 +160,11 @@
const uint8_t *la)
{
struct gbproxy_nse *nse;
- int i;
+ int i, j;
hash_for_each(cfg->bss_nses, i, nse, list) {
struct gbproxy_bvc *bvc;
- llist_for_each_entry(bvc, &nse->bvcs, list) {
+ hash_for_each(nse->bvcs, j, bvc, list) {
if (!memcmp(bvc->ra + 3, la + 3, 2))
return bvc;
}
@@ -232,7 +238,7 @@
}
bvc->nse = nse;
- llist_add(&bvc->list, &nse->bvcs);
+ hash_add(nse->bvcs, &bvc->list, bvc->bvci);
INIT_LLIST_HEAD(&bvc->patch_state.logical_links);
@@ -249,7 +255,7 @@
if (!bvc)
return;
- llist_del(&bvc->list);
+ hash_del(&bvc->list);
osmo_timer_del(&bvc->clean_stale_timer);
gbproxy_delete_link_infos(bvc);
@@ -261,8 +267,8 @@
void gbproxy_bvc_move(struct gbproxy_bvc *bvc, struct gbproxy_nse *nse)
{
- llist_del(&bvc->list);
- llist_add(&bvc->list, &nse->bvcs);
+ hash_del(&bvc->list);
+ hash_add(nse->bvcs, &bvc->list, bvc->bvci);
bvc->nse = nse;
}
@@ -272,16 +278,17 @@
* \param[in] bvci if 0: remove all BVCs; if != 0: BVCI of the single BVC to clean up */
int gbproxy_cleanup_bvcs(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci)
{
- int i, counter = 0;
+ int i, j, counter = 0;
struct gbproxy_nse *nse;
struct hlist_node *ntmp;
OSMO_ASSERT(cfg);
hash_for_each_safe(cfg->bss_nses, i, ntmp, nse, list) {
- struct gbproxy_bvc *bvc, *tmp;
+ struct gbproxy_bvc *bvc;
+ struct hlist_node *btmp;
if (nse->nsei != nsei)
continue;
- llist_for_each_entry_safe(bvc, tmp, &nse->bvcs, list) {
+ hash_for_each_safe(nse->bvcs, j, btmp, bvc, list) {
if (bvci && bvc->bvci != bvci)
continue;
@@ -307,20 +314,23 @@
hash_add(cfg->bss_nses, &nse->list, nsei);
- INIT_LLIST_HEAD(&nse->bvcs);
+ hash_init(nse->bvcs);
return nse;
}
void gbproxy_nse_free(struct gbproxy_nse *nse)
{
- struct gbproxy_bvc *bvc, *tmp;
+ struct gbproxy_bvc *bvc;
+ struct hlist_node *tmp;
+ int i;
+
if (!nse)
return;
hash_del(&nse->list);
- llist_for_each_entry_safe(bvc, tmp, &nse->bvcs, list)
+ hash_for_each_safe(nse->bvcs, i, tmp, bvc, list)
gbproxy_bvc_free(bvc);
talloc_free(nse);