/* uuid string -> virDomainObj mapping
* for O(1), lockless lookup-by-uuid */
virHashTable *objs;
+
+ /* name -> virDomainObj mapping for O(1),
+ * lockless lookup-by-name */
+ virHashTable *objsName;
};
if (!(doms = virObjectLockableNew(virDomainObjListClass)))
return NULL;
- if (!(doms->objs = virHashCreate(50, virObjectFreeHashData))) {
+ if (!(doms->objs = virHashCreate(50, virObjectFreeHashData)) ||
+ !(doms->objsName = virHashCreate(50, virObjectFreeHashData))) {
virObjectUnref(doms);
return NULL;
}
virDomainObjListPtr doms = obj;
virHashFree(doms->objs);
+ virHashFree(doms->objsName);
}
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,
const char *name)
{
virDomainObjPtr obj;
+
virObjectLock(doms);
- obj = virHashSearch(doms->objs, virDomainObjListSearchName, name);
+ obj = virHashLookup(doms->objsName, name);
virObjectRef(obj);
+ virObjectUnlock(doms);
if (obj) {
virObjectLock(obj);
if (obj->removing) {
obj = NULL;
}
}
- virObjectUnlock(doms);
return obj;
}
oldDef);
} else {
/* 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);
virUUIDFormat(vm->def->uuid, uuidstr);
virReportError(VIR_ERR_OPERATION_FAILED,
virObjectUnref(vm);
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:
return vm;
virObjectLock(doms);
virObjectLock(dom);
virHashRemoveEntry(doms->objs, uuidstr);
+ virHashRemoveEntry(doms->objsName, dom->def->name);
virObjectUnlock(dom);
virObjectUnref(dom);
virObjectUnlock(doms);
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(dom->def->uuid, uuidstr);
- virObjectUnlock(dom);
virHashRemoveEntry(doms->objs, uuidstr);
+ virHashRemoveEntry(doms->objsName, dom->def->name);
+ virObjectUnlock(dom);
}
static int
if (virHashAddEntry(doms->objs, uuidstr, obj) < 0)
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)
(*notify)(obj, 1, opaque);