/* * Copyright (c) 2019 TAOS Data, Inc. * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the GNU Affero General Public License, version 3 * or later ("AGPL"), as published by the Free Software Foundation. * * This program 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. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #define _DEFAULT_SOURCE #include "tidpool.h" #include "tlog.h" void *taosInitIdPool(int32_t maxId) { id_pool_t *pIdPool = calloc(1, sizeof(id_pool_t)); if (pIdPool == NULL) return NULL; pIdPool->freeList = calloc(maxId, sizeof(bool)); if (pIdPool->freeList == NULL) { free(pIdPool); return NULL; } pIdPool->maxId = maxId; pIdPool->numOfFree = maxId; pIdPool->freeSlot = 0; pthread_mutex_init(&pIdPool->mutex, NULL); uDebug("pool:%p is setup, maxId:%d", pIdPool, pIdPool->maxId); return pIdPool; } int32_t taosAllocateId(id_pool_t *pIdPool) { if (pIdPool == NULL) return -1; int32_t slot = -1; pthread_mutex_lock(&pIdPool->mutex); if (pIdPool->numOfFree > 0) { for (int32_t i = 0; i < pIdPool->maxId; ++i) { slot = (i + pIdPool->freeSlot) % pIdPool->maxId; if (!pIdPool->freeList[slot]) { pIdPool->freeList[slot] = true; pIdPool->freeSlot = slot + 1; pIdPool->numOfFree--; break; } } } pthread_mutex_unlock(&pIdPool->mutex); return slot + 1; } void taosFreeId(id_pool_t *pIdPool, int32_t id) { if (pIdPool == NULL) return; pthread_mutex_lock(&pIdPool->mutex); int32_t slot = (id - 1) % pIdPool->maxId; if (pIdPool->freeList[slot]) { pIdPool->freeList[slot] = false; pIdPool->numOfFree++; } pthread_mutex_unlock(&pIdPool->mutex); } void taosIdPoolCleanUp(id_pool_t *pIdPool) { if (pIdPool == NULL) return; uDebug("pool:%p is cleaned", pIdPool); if (pIdPool->freeList) free(pIdPool->freeList); pthread_mutex_destroy(&pIdPool->mutex); memset(pIdPool, 0, sizeof(id_pool_t)); free(pIdPool); } int32_t taosIdPoolNumOfUsed(id_pool_t *pIdPool) { pthread_mutex_lock(&pIdPool->mutex); int32_t ret = pIdPool->maxId - pIdPool->numOfFree; pthread_mutex_unlock(&pIdPool->mutex); return ret; } bool taosIdPoolMarkStatus(id_pool_t *pIdPool, int32_t id) { bool ret = false; pthread_mutex_lock(&pIdPool->mutex); int32_t slot = (id - 1) % pIdPool->maxId; if (!pIdPool->freeList[slot]) { pIdPool->freeList[slot] = true; pIdPool->numOfFree--; ret = true; } else { ret = false; } pthread_mutex_unlock(&pIdPool->mutex); return ret; } int32_t taosUpdateIdPool(id_pool_t *pIdPool, int32_t maxId) { if (maxId <= pIdPool->maxId) { return 0; } bool *idList = calloc(maxId, sizeof(bool)); if (idList == NULL) { return -1; } pthread_mutex_lock(&pIdPool->mutex); memcpy(idList, pIdPool->freeList, sizeof(bool) * pIdPool->maxId); pIdPool->numOfFree += (maxId - pIdPool->maxId); pIdPool->maxId = maxId; bool *oldIdList = pIdPool->freeList; pIdPool->freeList = idList; free(oldIdList); pthread_mutex_unlock(&pIdPool->mutex); return 0; } int32_t taosIdPoolMaxSize(id_pool_t *pIdPool) { pthread_mutex_lock(&pIdPool->mutex); int32_t ret = pIdPool->maxId; pthread_mutex_unlock(&pIdPool->mutex); return ret; }