<commit_before>/*
 * virdomainobjlist.c: domain objects list utilities
 *
 * Copyright (C) 2006-2015 Red Hat, Inc.
 * Copyright (C) 2006-2008 <NAME>
 * Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Author: <NAME> <<EMAIL>>
 */

#include <config.h>

#include "internal.h"
#include "datatypes.h"
#include "virdomainobjlist.h"
#include "snapshot_conf.h"
#include "viralloc.h"
#include "virfile.h"
#include "virlog.h"
#include "virstring.h"

#define VIR_FROM_THIS VIR_FROM_DOMAIN

VIR_LOG_INIT("conf.virdomainobjlist");

static virClassPtr virDomainObjListClass;
static void virDomainObjListDispose(void *obj);


struct _virDomainObjList {
    virObjectRWLockable parent;

    /* 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;
};


static int virDomainObjListOnceInit(void)
{
    if (!VIR_CLASS_NEW(virDomainObjList, virClassForObjectRWLockable()))
        return -1;

    return 0;
}

VIR_ONCE_GLOBAL_INIT(virDomainObjList)

virDomainObjListPtr virDomainObjListNew(void)
{
    virDomainObjListPtr doms;

    if (virDomainObjListInitialize() < 0)
        return NULL;

    if (!(doms = virObjectRWLockableNew(virDomainObjListClass)))
        return NULL;

    if (!(doms->objs = virHashCreate(50, virObjectFreeHashData)) ||
        !(doms->objsName = virHashCreate(50, virObjectFreeHashData))) {
        virObjectUnref(doms);
        return NULL;
    }

    return doms;
}


static void virDomainObjListDispose(void *obj)
{
    virDomainObjListPtr doms = obj;

    virHashFree(doms->objs);
    virHashFree(doms->objsName);
}


static int virDomainObjListSearchID(const void *payload,
                                    const void *name ATTRIBUTE_UNUSED,
                                    const void *data)
{
    virDomainObjPtr obj = (virDomainObjPtr)payload;
    const int *id = data;
    int want = 0;

    virObjectLock(obj);
    if (virDomainObjIsActive(obj) &&
        obj->def->id == *id)
        want = 1;
    virObjectUnlock(obj);
    return want;
}


virDomainObjPtr
virDomainObjListFindByID(virDomainObjListPtr doms,
                         int id)
{
    virDomainObjPtr obj;

    virObjectRWLockRead(doms);
    obj = virHashSearch(doms->objs, virDomainObjListSearchID, &id, NULL);
    virObjectRef(obj);
    virObjectRWUnlock(doms);
    if (obj) {
        virObjectLock(obj);
        if (obj->removing) {
            virObjectUnlock(obj);
            virObjectUnref(obj);
            obj = NULL;
        }
    }

    return obj;
}


virDomainObjPtr
virDomainObjListFindByUUID(virDomainObjListPtr doms,
                           const unsigned char *uuid)
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    virDomainObjPtr obj;

    virObjectRWLockRead(doms);
    virUUIDFormat(uuid, uuidstr);

    obj = virHashLookup(doms->objs, uuidstr);
    virObjectRef(obj);
    virObjectRWUnlock(doms);
    if (obj) {
        virObjectLock(obj);
        if (obj->removing) {
            virObjectUnlock(obj);
            virObjectUnref(obj);
            obj = NULL;
        }
    }
    return obj;
}


virDomainObjPtr virDomainObjListFindByName(virDomainObjListPtr doms,
                                           const char *name)
{
    virDomainObjPtr obj;

    virObjectRWLockRead(doms);
    obj = virHashLookup(doms->objsName, name);
    virObjectRef(obj);
    virObjectRWUnlock(doms);
    if (obj) {
        virObjectLock(obj);
        if (obj->removing) {
            virObjectUnlock(obj);
            virObjectUnref(obj);
            obj = NULL;
        }
    }
    return obj;
}


/**
 * @doms: Domain object list pointer
 * @vm: Domain object to be added
 *
 * Upon entry @vm should have at least 1 ref and be locked.
 *
 * Add the @vm into the @doms->objs and @doms->objsName hash
 * tables.
 *
 * Returns 0 on success with 2 references and locked
 *        -1 on failure with 1 reference and locked
 */
static int
virDomainObjListAddObjLocked(virDomainObjListPtr doms,
                             virDomainObjPtr vm)
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];

    virUUIDFormat(vm->def->uuid, uuidstr);
    if (virHashAddEntry(doms->objs, uuidstr, vm) < 0)
        return -1;

    if (virHashAddEntry(doms->objsName, vm->def->name, vm) < 0) {
        virObjectRef(vm);
        virHashRemoveEntry(doms->objs, uuidstr);
        return -1;<commit_msg>conf: Split FindBy{UUID|Name} into locked helpers<commit_after>/*
 * virdomainobjlist.c: domain objects list utilities
 *
 * Copyright (C) 2006-2015 Red Hat, Inc.
 * Copyright (C) 2006-2008 <NAME>
 * Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Author: <NAME> <<EMAIL>>
 */

#include <config.h>

#include "internal.h"
#include "datatypes.h"
#include "virdomainobjlist.h"
#include "snapshot_conf.h"
#include "viralloc.h"
#include "virfile.h"
#include "virlog.h"
#include "virstring.h"

#define VIR_FROM_THIS VIR_FROM_DOMAIN

VIR_LOG_INIT("conf.virdomainobjlist");

static virClassPtr virDomainObjListClass;
static void virDomainObjListDispose(void *obj);


struct _virDomainObjList {
    virObjectRWLockable parent;

    /* 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;
};


static int virDomainObjListOnceInit(void)
{
    if (!VIR_CLASS_NEW(virDomainObjList, virClassForObjectRWLockable()))
        return -1;

    return 0;
}

VIR_ONCE_GLOBAL_INIT(virDomainObjList)

virDomainObjListPtr virDomainObjListNew(void)
{
    virDomainObjListPtr doms;

    if (virDomainObjListInitialize() < 0)
        return NULL;

    if (!(doms = virObjectRWLockableNew(virDomainObjListClass)))
        return NULL;

    if (!(doms->objs = virHashCreate(50, virObjectFreeHashData)) ||
        !(doms->objsName = virHashCreate(50, virObjectFreeHashData))) {
        virObjectUnref(doms);
        return NULL;
    }

    return doms;
}


static void virDomainObjListDispose(void *obj)
{
    virDomainObjListPtr doms = obj;

    virHashFree(doms->objs);
    virHashFree(doms->objsName);
}


static int virDomainObjListSearchID(const void *payload,
                                    const void *name ATTRIBUTE_UNUSED,
                                    const void *data)
{
    virDomainObjPtr obj = (virDomainObjPtr)payload;
    const int *id = data;
    int want = 0;

    virObjectLock(obj);
    if (virDomainObjIsActive(obj) &&
        obj->def->id == *id)
        want = 1;
    virObjectUnlock(obj);
    return want;
}


virDomainObjPtr
virDomainObjListFindByID(virDomainObjListPtr doms,
                         int id)
{
    virDomainObjPtr obj;

    virObjectRWLockRead(doms);
    obj = virHashSearch(doms->objs, virDomainObjListSearchID, &id, NULL);
    virObjectRef(obj);
    virObjectRWUnlock(doms);
    if (obj) {
        virObjectLock(obj);
        if (obj->removing) {
            virObjectUnlock(obj);
            virObjectUnref(obj);
            obj = NULL;
        }
    }

    return obj;
}


static virDomainObjPtr
virDomainObjListFindByUUIDLocked(virDomainObjListPtr doms,
                                 const unsigned char *uuid)
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    virDomainObjPtr obj;

    virUUIDFormat(uuid, uuidstr);
    obj = virHashLookup(doms->objs, uuidstr);
    virObjectRef(obj);
    if (obj) {
        virObjectLock(obj);
        if (obj->removing) {
            virObjectUnlock(obj);
            virObjectUnref(obj);
            obj = NULL;
        }
    }
    return obj;
}


/**
 * @doms: Domain object list
 * @uuid: UUID to search the doms->objs table
 *
 * Lookup the @uuid in the doms->objs hash table and return a
 * locked and ref counted domain object if found. Caller is
 * expected to use the virDomainObjEndAPI when done with the object.
 */
virDomainObjPtr
virDomainObjListFindByUUID(virDomainObjListPtr doms,
                           const unsigned char *uuid)
{
    virDomainObjPtr obj;

    virObjectRWLockRead(doms);
    obj = virDomainObjListFindByUUIDLocked(doms, uuid);
    virObjectRWUnlock(doms);

    return obj;
}


static virDomainObjPtr
virDomainObjListFindByNameLocked(virDomainObjListPtr doms,
                                 const char *name)
{
    virDomainObjPtr obj;

    obj = virHashLookup(doms->objsName, name);
    virObjectRef(obj);
    if (obj) {
        virObjectLock(obj);
        if (obj->removing) {
            virObjectUnlock(obj);
            virObjectUnref(obj);
            obj = NULL;
        }
    }
    return obj;
}


/**
 * @doms: Domain object list
 * @name: Name to search the doms->objsName table
 *
 * Lookup the @name in the doms->objsName hash table and return a
 * locked and ref counted domain object if found. Caller is expected
 * to use the virDomainObjEndAPI when done with the object.
 */
virDomainObjPtr
virDomainObjListFindByName(virDomainObjListPtr doms,
                           const char *name)
{
    virDomainObjPtr obj;

    virObjectRWLockRead(doms);
    obj = virDomainObjListFindByNameLocked(doms, name);
    virObjectRWUnlock(doms);

    return obj;
}


/**
 * @doms: Domain object list pointer
 * @vm: Domain object to be added
 *
 * Upon entry @vm should have at least 1 ref and be locked.
 *
 * Add the @vm into the @doms->objs and @doms->objsName hash
 * tables.
 *
 * Returns 0 on success with 2 references and locked
 *        -1 on failure with 1 reference and locked
 */
static int
virDomainObjListAddObjLocked(virDomainObjListPtr doms,
                             virDomainObjPtr vm)
{
    char uuidstr[VIR_UUID_STRING_BUFLEN];

    virUUIDFormat(vm->def->uuid, uuidstr);
    if (virHashAddEntry(doms->objs, uuidstr, vm) < 0)
        return -1;

    if (virHashAddEntry(doms->objsName, vm->def->name, vm) < 0) {
        virObjectRef(vm);
        virHashRemoveEntry(doms->objs, uuidstr);
        return -1;
{'fraction_non_alphanumeric': 0.09558303886925795, 'fraction_numerical': 0.007420494699646643, 'mean_word_length': 2.8246621621621624, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5973518', 'n_tokens_mistral': 3653, 'n_tokens_neox': 3517, 'n_words': 953}