提交 8728a565 编写于 作者: M Michal Privoznik

virDomainObjList: Introduce yet another hash table

This hash table will contain the same data as already existing one.
The only difference is that while the first table uses domain uuid as
key, the new table uses domain name. This will allow much faster (and
lockless) lookups by domain name.
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
上级 620ff93b
...@@ -65,6 +65,10 @@ struct _virDomainObjList { ...@@ -65,6 +65,10 @@ struct _virDomainObjList {
/* uuid string -> virDomainObj mapping /* uuid string -> virDomainObj mapping
* for O(1), lockless lookup-by-uuid */ * for O(1), lockless lookup-by-uuid */
virHashTable *objs; virHashTable *objs;
/* name -> virDomainObj mapping for O(1),
* lockless lookup-by-name */
virHashTable *objsName;
}; };
...@@ -1042,7 +1046,8 @@ virDomainObjListPtr virDomainObjListNew(void) ...@@ -1042,7 +1046,8 @@ virDomainObjListPtr virDomainObjListNew(void)
if (!(doms = virObjectLockableNew(virDomainObjListClass))) if (!(doms = virObjectLockableNew(virDomainObjListClass)))
return NULL; return NULL;
if (!(doms->objs = virHashCreate(50, virObjectFreeHashData))) { if (!(doms->objs = virHashCreate(50, virObjectFreeHashData)) ||
!(doms->objsName = virHashCreate(50, virObjectFreeHashData))) {
virObjectUnref(doms); virObjectUnref(doms);
return NULL; return NULL;
} }
...@@ -1056,6 +1061,7 @@ static void virDomainObjListDispose(void *obj) ...@@ -1056,6 +1061,7 @@ static void virDomainObjListDispose(void *obj)
virDomainObjListPtr doms = obj; virDomainObjListPtr doms = obj;
virHashFree(doms->objs); virHashFree(doms->objs);
virHashFree(doms->objsName);
} }
...@@ -1137,27 +1143,15 @@ virDomainObjListFindByUUIDRef(virDomainObjListPtr doms, ...@@ -1137,27 +1143,15 @@ virDomainObjListFindByUUIDRef(virDomainObjListPtr doms,
return virDomainObjListFindByUUIDInternal(doms, uuid, true); return virDomainObjListFindByUUIDInternal(doms, uuid, true);
} }
static int virDomainObjListSearchName(const void *payload,
const void *name ATTRIBUTE_UNUSED,
const void *data)
{
virDomainObjPtr obj = (virDomainObjPtr)payload;
int want = 0;
virObjectLock(obj);
if (STREQ(obj->def->name, (const char *)data))
want = 1;
virObjectUnlock(obj);
return want;
}
virDomainObjPtr virDomainObjListFindByName(virDomainObjListPtr doms, virDomainObjPtr virDomainObjListFindByName(virDomainObjListPtr doms,
const char *name) const char *name)
{ {
virDomainObjPtr obj; virDomainObjPtr obj;
virObjectLock(doms); virObjectLock(doms);
obj = virHashSearch(doms->objs, virDomainObjListSearchName, name); obj = virHashLookup(doms->objsName, name);
virObjectRef(obj); virObjectRef(obj);
virObjectUnlock(doms);
if (obj) { if (obj) {
virObjectLock(obj); virObjectLock(obj);
if (obj->removing) { if (obj->removing) {
...@@ -1166,7 +1160,6 @@ virDomainObjPtr virDomainObjListFindByName(virDomainObjListPtr doms, ...@@ -1166,7 +1160,6 @@ virDomainObjPtr virDomainObjListFindByName(virDomainObjListPtr doms,
obj = NULL; obj = NULL;
} }
} }
virObjectUnlock(doms);
return obj; return obj;
} }
...@@ -2545,7 +2538,7 @@ virDomainObjListAddLocked(virDomainObjListPtr doms, ...@@ -2545,7 +2538,7 @@ virDomainObjListAddLocked(virDomainObjListPtr doms,
oldDef); oldDef);
} else { } else {
/* UUID does not match, but if a name matches, refuse it */ /* UUID does not match, but if a name matches, refuse it */
if ((vm = virHashSearch(doms->objs, virDomainObjListSearchName, def->name))) { if ((vm = virHashLookup(doms->objsName, def->name))) {
virObjectLock(vm); virObjectLock(vm);
virUUIDFormat(vm->def->uuid, uuidstr); virUUIDFormat(vm->def->uuid, uuidstr);
virReportError(VIR_ERR_OPERATION_FAILED, virReportError(VIR_ERR_OPERATION_FAILED,
...@@ -2563,6 +2556,15 @@ virDomainObjListAddLocked(virDomainObjListPtr doms, ...@@ -2563,6 +2556,15 @@ virDomainObjListAddLocked(virDomainObjListPtr doms,
virObjectUnref(vm); virObjectUnref(vm);
return NULL; return NULL;
} }
if (virHashAddEntry(doms->objsName, def->name, vm) < 0) {
virHashRemoveEntry(doms->objs, uuidstr);
return NULL;
}
/* Since domain is in two hash tables, increment the
* reference counter */
virObjectRef(vm);
} }
cleanup: cleanup:
return vm; return vm;
...@@ -2720,6 +2722,7 @@ void virDomainObjListRemove(virDomainObjListPtr doms, ...@@ -2720,6 +2722,7 @@ void virDomainObjListRemove(virDomainObjListPtr doms,
virObjectLock(doms); virObjectLock(doms);
virObjectLock(dom); virObjectLock(dom);
virHashRemoveEntry(doms->objs, uuidstr); virHashRemoveEntry(doms->objs, uuidstr);
virHashRemoveEntry(doms->objsName, dom->def->name);
virObjectUnlock(dom); virObjectUnlock(dom);
virObjectUnref(dom); virObjectUnref(dom);
virObjectUnlock(doms); virObjectUnlock(doms);
...@@ -2737,9 +2740,10 @@ void virDomainObjListRemoveLocked(virDomainObjListPtr doms, ...@@ -2737,9 +2740,10 @@ void virDomainObjListRemoveLocked(virDomainObjListPtr doms,
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(dom->def->uuid, uuidstr); virUUIDFormat(dom->def->uuid, uuidstr);
virObjectUnlock(dom);
virHashRemoveEntry(doms->objs, uuidstr); virHashRemoveEntry(doms->objs, uuidstr);
virHashRemoveEntry(doms->objsName, dom->def->name);
virObjectUnlock(dom);
} }
static int static int
...@@ -21588,6 +21592,15 @@ virDomainObjListLoadStatus(virDomainObjListPtr doms, ...@@ -21588,6 +21592,15 @@ virDomainObjListLoadStatus(virDomainObjListPtr doms,
if (virHashAddEntry(doms->objs, uuidstr, obj) < 0) if (virHashAddEntry(doms->objs, uuidstr, obj) < 0)
goto error; goto error;
if (virHashAddEntry(doms->objsName, obj->def->name, obj) < 0) {
virHashRemoveEntry(doms->objs, uuidstr);
goto error;
}
/* Since domain is in two hash tables, increment the
* reference counter */
virObjectRef(obj);
if (notify) if (notify)
(*notify)(obj, 1, opaque); (*notify)(obj, 1, opaque);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册