LCOV - code coverage report
Current view: top level - lib - id-pool.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 45 55 81.8 %
Date: 2016-09-14 01:02:56 Functions: 7 8 87.5 %
Branches: 18 30 60.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2014 Nicira, Inc.
       3                 :            :  * Copyright (c) 2014 Netronome.
       4                 :            :  *
       5                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       6                 :            :  * you may not use this file except in compliance with the License.
       7                 :            :  * You may obtain a copy of the License at:
       8                 :            :  *
       9                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
      10                 :            :  *
      11                 :            :  * Unless required by applicable law or agreed to in writing, software
      12                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      13                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14                 :            :  * See the License for the specific language governing permissions and
      15                 :            :  * limitations under the License.
      16                 :            :  */
      17                 :            : 
      18                 :            : #include <config.h>
      19                 :            : #include "id-pool.h"
      20                 :            : #include "openvswitch/hmap.h"
      21                 :            : #include "hash.h"
      22                 :            : 
      23                 :            : struct id_node {
      24                 :            :     struct hmap_node node;
      25                 :            :     uint32_t id;
      26                 :            : };
      27                 :            : 
      28                 :            : struct id_pool {
      29                 :            :     struct hmap map;
      30                 :            :     uint32_t base;         /* IDs in the range of [base, base + n_ids). */
      31                 :            :     uint32_t n_ids;        /* Total number of ids in the pool. */
      32                 :            :     uint32_t next_free_id; /* Possible next free id. */
      33                 :            : };
      34                 :            : 
      35                 :            : static void id_pool_init(struct id_pool *pool,
      36                 :            :                          uint32_t base, uint32_t n_ids);
      37                 :            : static void id_pool_uninit(struct id_pool *pool);
      38                 :            : static struct id_node *id_pool_find(struct id_pool *pool, uint32_t id);
      39                 :            : 
      40                 :            : struct id_pool *
      41                 :         12 : id_pool_create(uint32_t base, uint32_t n_ids)
      42                 :            : {
      43                 :            :     struct id_pool *pool;
      44                 :            : 
      45                 :         12 :     pool = xmalloc(sizeof *pool);
      46                 :         12 :     id_pool_init(pool, base, n_ids);
      47                 :            : 
      48                 :         12 :     return pool;
      49                 :            : }
      50                 :            : 
      51                 :            : void
      52                 :         60 : id_pool_destroy(struct id_pool *pool)
      53                 :            : {
      54         [ +  + ]:         60 :     if (pool) {
      55                 :         12 :         id_pool_uninit(pool);
      56                 :         12 :         free(pool);
      57                 :            :     }
      58                 :         60 : }
      59                 :            : 
      60                 :            : static void
      61                 :         12 : id_pool_init(struct id_pool *pool, uint32_t base, uint32_t n_ids)
      62                 :            : {
      63                 :         12 :     pool->base = base;
      64                 :         12 :     pool->n_ids = n_ids;
      65                 :         12 :     pool->next_free_id = base;
      66                 :         12 :     hmap_init(&pool->map);
      67                 :         12 : }
      68                 :            : 
      69                 :            : static void
      70                 :         12 : id_pool_uninit(struct id_pool *pool)
      71                 :            : {
      72                 :            :     struct id_node *id_node;
      73                 :            : 
      74 [ +  + ][ -  + ]:         39 :     HMAP_FOR_EACH_POP(id_node, node, &pool->map) {
                 [ +  + ]
      75                 :         27 :         free(id_node);
      76                 :            :     }
      77                 :            : 
      78                 :         12 :     hmap_destroy(&pool->map);
      79                 :         12 : }
      80                 :            : 
      81                 :            : static struct id_node *
      82                 :         29 : id_pool_find(struct id_pool *pool, uint32_t id)
      83                 :            : {
      84                 :            :     size_t hash;
      85                 :            :     struct id_node *id_node;
      86                 :            : 
      87                 :         29 :     hash = hash_int(id, 0);
      88 [ +  + ][ -  + ]:         29 :     HMAP_FOR_EACH_WITH_HASH(id_node, node, hash, &pool->map) {
      89         [ +  - ]:          6 :         if (id == id_node->id) {
      90                 :          6 :             return id_node;
      91                 :            :         }
      92                 :            :     }
      93                 :         23 :     return NULL;
      94                 :            : }
      95                 :            : 
      96                 :            : void
      97                 :         27 : id_pool_add(struct id_pool *pool, uint32_t id)
      98                 :            : {
      99                 :         27 :     struct id_node *id_node = xmalloc(sizeof *id_node);
     100                 :            :     size_t hash;
     101                 :            : 
     102                 :         27 :     id_node->id = id;
     103                 :         27 :     hash = hash_int(id, 0);
     104                 :         27 :     hmap_insert(&pool->map, &id_node->node, hash);
     105                 :         27 : }
     106                 :            : 
     107                 :            : bool
     108                 :         23 : id_pool_alloc_id(struct id_pool *pool, uint32_t *id_)
     109                 :            : {
     110                 :            :     uint32_t id;
     111                 :            : 
     112         [ -  + ]:         23 :     if (pool->n_ids == 0) {
     113                 :          0 :         return false;
     114                 :            :     }
     115                 :            : 
     116         [ +  + ]:         23 :     if (!(id_pool_find(pool, pool->next_free_id))) {
     117                 :         21 :         id = pool->next_free_id;
     118                 :         21 :         goto found_free_id;
     119                 :            :     }
     120                 :            : 
     121         [ +  - ]:          6 :     for(id = pool->base; id < pool->base + pool->n_ids; id++) {
     122         [ +  + ]:          6 :         if (!id_pool_find(pool, id)) {
     123                 :          2 :             goto found_free_id;
     124                 :            :         }
     125                 :            :     }
     126                 :            : 
     127                 :            :     /* Not available. */
     128                 :          0 :     return false;
     129                 :            : 
     130                 :            : found_free_id:
     131                 :         23 :     id_pool_add(pool, id);
     132                 :            : 
     133         [ +  - ]:         23 :     if (id < pool->base + pool->n_ids) {
     134                 :         23 :         pool->next_free_id = id + 1;
     135                 :            :     } else {
     136                 :          0 :         pool->next_free_id = pool->base;
     137                 :            :     }
     138                 :            : 
     139                 :         23 :     *id_ = id;
     140                 :         23 :     return true;
     141                 :            : }
     142                 :            : 
     143                 :            : void
     144                 :          0 : id_pool_free_id(struct id_pool *pool, uint32_t id)
     145                 :            : {
     146                 :            :     struct id_node *id_node;
     147 [ #  # ][ #  # ]:          0 :     if (id > pool->base && (id <= pool->base + pool->n_ids)) {
     148                 :          0 :         id_node = id_pool_find(pool, id);
     149         [ #  # ]:          0 :         if (id_node) {
     150                 :          0 :             hmap_remove(&pool->map, &id_node->node);
     151                 :          0 :             free(id_node);
     152                 :            :         }
     153                 :            :     }
     154                 :          0 : }

Generated by: LCOV version 1.12