tidpool.c 3.8 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

S
hash  
Shengliang Guan 已提交
16
#define _DEFAULT_SOURCE
S
log  
Shengliang Guan 已提交
17
#include "tlog.h"
H
hzcheng 已提交
18 19

typedef struct {
S
hash  
Shengliang Guan 已提交
20 21 22 23
  int32_t         maxId;
  int32_t         numOfFree;
  int32_t         freeSlot;
  bool           *freeList;
H
hzcheng 已提交
24 25 26
  pthread_mutex_t mutex;
} id_pool_t;

S
hash  
Shengliang Guan 已提交
27
void *taosInitIdPool(int32_t maxId) {
S
slguan 已提交
28
  id_pool_t *pIdPool = calloc(1, sizeof(id_pool_t));
H
hzcheng 已提交
29 30
  if (pIdPool == NULL) return NULL;

S
slguan 已提交
31
  pIdPool->freeList = calloc(maxId, sizeof(bool));
S
slguan 已提交
32
  if (pIdPool->freeList == NULL) {
H
hzcheng 已提交
33 34 35 36 37
    free(pIdPool);
    return NULL;
  }

  pIdPool->maxId = maxId;
S
slguan 已提交
38
  pIdPool->numOfFree = maxId;
H
hzcheng 已提交
39 40 41 42
  pIdPool->freeSlot = 0;

  pthread_mutex_init(&pIdPool->mutex, NULL);

43
  uDebug("pool:%p is setup, maxId:%d", pIdPool, pIdPool->maxId);
H
hzcheng 已提交
44

S
slguan 已提交
45
  return pIdPool;
H
hzcheng 已提交
46 47
}

S
hash  
Shengliang Guan 已提交
48
int32_t taosAllocateId(void *handle) {
S
slguan 已提交
49 50 51 52
  id_pool_t *pIdPool = handle;
  if (handle == NULL) {
    return -1;
  }
H
hzcheng 已提交
53

S
hash  
Shengliang Guan 已提交
54
  int32_t slot = -1;
S
slguan 已提交
55
  pthread_mutex_lock(&pIdPool->mutex);
H
hzcheng 已提交
56 57

  if (pIdPool->numOfFree > 0) {
S
hash  
Shengliang Guan 已提交
58
    for (int32_t i = 0; i < pIdPool->maxId; ++i) {
S
slguan 已提交
59
      slot = (i + pIdPool->freeSlot) % pIdPool->maxId;
S
slguan 已提交
60 61
      if (!pIdPool->freeList[slot]) {
        pIdPool->freeList[slot] = true;
S
slguan 已提交
62 63 64 65 66
        pIdPool->freeSlot = slot + 1;
        pIdPool->numOfFree--;
        break;
      }
    }
H
hzcheng 已提交
67 68
  }

S
slguan 已提交
69
  pthread_mutex_unlock(&pIdPool->mutex);
S
slguan 已提交
70
  return slot + 1;
H
hzcheng 已提交
71 72
}

S
hash  
Shengliang Guan 已提交
73
void taosFreeId(void *handle, int32_t id) {
S
slguan 已提交
74 75
  id_pool_t *pIdPool = handle;
  if (handle == NULL) return;
H
hzcheng 已提交
76

S
slguan 已提交
77
  pthread_mutex_lock(&pIdPool->mutex);
H
hzcheng 已提交
78

S
hash  
Shengliang Guan 已提交
79
  int32_t slot = (id - 1) % pIdPool->maxId;
S
slguan 已提交
80 81
  if (pIdPool->freeList[slot]) {
    pIdPool->freeList[slot] = false;
S
slguan 已提交
82 83
    pIdPool->numOfFree++;
  }
H
hzcheng 已提交
84

S
slguan 已提交
85
  pthread_mutex_unlock(&pIdPool->mutex);
H
hzcheng 已提交
86 87 88
}

void taosIdPoolCleanUp(void *handle) {
S
slguan 已提交
89
  id_pool_t *pIdPool = handle;
H
hzcheng 已提交
90

S
slguan 已提交
91
  if (pIdPool == NULL) return;
H
hzcheng 已提交
92

93
  uDebug("pool:%p is cleaned", pIdPool);
H
hzcheng 已提交
94 95 96 97 98 99 100 101 102 103

  if (pIdPool->freeList) free(pIdPool->freeList);

  pthread_mutex_destroy(&pIdPool->mutex);

  memset(pIdPool, 0, sizeof(id_pool_t));

  free(pIdPool);
}

S
hash  
Shengliang Guan 已提交
104
int32_t taosIdPoolNumOfUsed(void *handle) {
S
slguan 已提交
105
  id_pool_t *pIdPool = handle;
106 107

  pthread_mutex_lock(&pIdPool->mutex);
S
hash  
Shengliang Guan 已提交
108
  int32_t ret = pIdPool->maxId - pIdPool->numOfFree;
109 110 111
  pthread_mutex_unlock(&pIdPool->mutex);

  return ret;
H
hzcheng 已提交
112 113
}

S
hash  
Shengliang Guan 已提交
114 115
bool taosIdPoolMarkStatus(void *handle, int32_t id) {
  bool       ret = false;
S
slguan 已提交
116 117
  id_pool_t *pIdPool = handle;
  pthread_mutex_lock(&pIdPool->mutex);
H
hzcheng 已提交
118

S
hash  
Shengliang Guan 已提交
119
  int32_t slot = (id - 1) % pIdPool->maxId;
S
slguan 已提交
120 121
  if (!pIdPool->freeList[slot]) {
    pIdPool->freeList[slot] = true;
S
slguan 已提交
122
    pIdPool->numOfFree--;
123 124 125
    ret = true;
  } else {
    ret = false;
H
hzcheng 已提交
126
  }
S
slguan 已提交
127 128

  pthread_mutex_unlock(&pIdPool->mutex);
129
  return ret;
H
hzcheng 已提交
130
}
S
slguan 已提交
131

S
hash  
Shengliang Guan 已提交
132 133
int32_t taosUpdateIdPool(id_pool_t *handle, int32_t maxId) {
  id_pool_t *pIdPool = (id_pool_t *)handle;
S
slguan 已提交
134
  if (maxId <= pIdPool->maxId) {
135
    return 0;
S
slguan 已提交
136 137
  }

S
slguan 已提交
138
  bool *idList = calloc(maxId, sizeof(bool));
S
slguan 已提交
139 140 141 142
  if (idList == NULL) {
    return -1;
  }

S
slguan 已提交
143 144
  pthread_mutex_lock(&pIdPool->mutex);

S
slguan 已提交
145
  memcpy(idList, pIdPool->freeList, sizeof(bool) * pIdPool->maxId);
S
slguan 已提交
146 147 148
  pIdPool->numOfFree += (maxId - pIdPool->maxId);
  pIdPool->maxId = maxId;

S
slguan 已提交
149
  bool *oldIdList = pIdPool->freeList;
S
slguan 已提交
150 151 152
  pIdPool->freeList = idList;
  free(oldIdList);

S
slguan 已提交
153
  pthread_mutex_unlock(&pIdPool->mutex);
S
slguan 已提交
154 155 156 157

  return 0;
}

S
hash  
Shengliang Guan 已提交
158
int32_t taosIdPoolMaxSize(void *handle) {
159 160 161
  id_pool_t *pIdPool = (id_pool_t *)handle;

  pthread_mutex_lock(&pIdPool->mutex);
S
hash  
Shengliang Guan 已提交
162
  int32_t ret = pIdPool->maxId;
163 164 165
  pthread_mutex_unlock(&pIdPool->mutex);

  return ret;
S
slguan 已提交
166
}