LCOV - code coverage report
Current view: top level - src - btree_str_kv.cc (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 203 259 78.4 %
Date: 2015-01-12 15:17:13 Functions: 18 21 85.7 %
Branches: 65 102 63.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
       2                 :            : /*
       3                 :            :  *     Copyright 2010 Couchbase, Inc
       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 <stdio.h>
      19                 :            : #include <stdlib.h>
      20                 :            : #include <string.h>
      21                 :            : #include <stdint.h>
      22                 :            : 
      23                 :            : #include "btree.h"
      24                 :            : #include "btree_str_kv.h"
      25                 :            : 
      26                 :            : #include "memleak.h"
      27                 :            : 
      28                 :            : typedef uint16_t key_len_t;
      29                 :            : 
      30                 :            : /*
      31                 :            : n-byte  keylen   vsize   ...
      32                 :            : [keylen][key ...][value][keylen][key ...][value]
      33                 :            : */
      34                 :            : 
      35                 :          4 : static void _get_str_kv(struct bnode *node, idx_t idx, void *key, void *value)
      36                 :            : {
      37                 :            :     int ksize, vsize, i;
      38                 :            :     void *key_ptr, *ptr;
      39                 :            :     key_len_t keylen, _keylen;
      40                 :            :     size_t offset;
      41                 :            : 
      42                 :          4 :     _get_kvsize(node->kvsize, ksize, vsize);
      43                 :          4 :     ksize = sizeof(void *);
      44                 :            : 
      45                 :          4 :     ptr = node->data;
      46                 :          4 :     offset = 0;
      47                 :            :     // linear search
      48         [ -  + ]:          4 :     for (i=0;i<idx;++i){
      49                 :          0 :         memcpy(&_keylen, (uint8_t*)ptr+offset, sizeof(key_len_t));
      50                 :          0 :         keylen = _endian_decode(_keylen);
      51                 :          0 :         offset += sizeof(key_len_t)+keylen + vsize;
      52                 :            :     }
      53                 :            : 
      54                 :            :     // if KEY already points to previous key, then free it
      55                 :          4 :     memcpy(&key_ptr, key, ksize);
      56         [ +  + ]:          4 :     if (key_ptr) {
      57                 :          2 :         free(key_ptr);
      58                 :            :     }
      59                 :            : 
      60                 :            :     // allocate space for key
      61                 :          4 :     memcpy(&_keylen, (uint8_t*)ptr+offset, sizeof(key_len_t));
      62                 :          4 :     keylen = _endian_decode(_keylen);
      63                 :          4 :     key_ptr = (void*)malloc(sizeof(key_len_t) + keylen);
      64                 :            : 
      65                 :            :     // copy key
      66                 :          4 :     memcpy(key_ptr, &_keylen, sizeof(key_len_t));
      67                 :          4 :     memcpy((uint8_t*)key_ptr + sizeof(key_len_t),
      68                 :          8 :            (uint8_t*)ptr+offset+sizeof(key_len_t), keylen);
      69                 :            :     // copy key pointer
      70                 :          4 :     memcpy(key, &key_ptr, ksize);
      71                 :            :     // copy value
      72         [ +  + ]:          4 :     if (value) {
      73                 :          3 :         memcpy(value, (uint8_t*)ptr + offset + sizeof(key_len_t) + keylen, vsize);
      74                 :            :     }
      75                 :          4 : }
      76                 :            : 
      77                 :          5 : static void _set_str_kv(struct bnode *node, idx_t idx, void *key, void *value)
      78                 :            : {
      79                 :            :     int ksize, vsize, i;
      80                 :            :     void *key_ptr, *ptr;
      81                 :            :     key_len_t keylen, keylen_ins, keylen_idx;
      82                 :            :     key_len_t _keylen, _keylen_ins;
      83                 :            :     size_t offset, offset_idx, offset_next, next_len;
      84                 :            : 
      85                 :          5 :     _get_kvsize(node->kvsize, ksize, vsize);
      86                 :          5 :     ksize = sizeof(void *);
      87                 :            : 
      88                 :          5 :     ptr = node->data;
      89                 :          5 :     offset = keylen = 0;
      90                 :            :     // linear search
      91         [ +  + ]:          6 :     for (i=0;i<idx;++i){
      92                 :          1 :         memcpy(&_keylen, (uint8_t*)ptr+offset, sizeof(key_len_t));
      93                 :          1 :         keylen = _endian_decode(_keylen);
      94                 :          1 :         offset += sizeof(key_len_t)+keylen + vsize;
      95                 :            :     }
      96                 :          5 :     offset_idx = offset;
      97                 :            : 
      98                 :            :     // copy key info from KEY
      99                 :          5 :     memcpy(&key_ptr, key, ksize);
     100                 :          5 :     memcpy(&_keylen_ins, key_ptr, sizeof(key_len_t));
     101                 :          5 :     keylen_ins = _endian_decode(_keylen_ins);
     102                 :            : 
     103 [ +  - ][ -  + ]:          5 :     if (keylen_ins != keylen && idx+2 <= node->nentry) {
     104                 :            :         // we have to move idx+1 ~ nentry KVs to appropriate position
     105                 :          0 :         next_len = 0;
     106         [ #  # ]:          0 :         for (i=idx;i<node->nentry;++i){
     107                 :          0 :             memcpy(&_keylen, (uint8_t*)ptr + offset, sizeof(key_len_t));
     108                 :          0 :             keylen = _endian_decode(_keylen);
     109                 :            : 
     110         [ #  # ]:          0 :             if (i==idx) keylen_idx = keylen;
     111         [ #  # ]:          0 :             if (i>idx) next_len += sizeof(key_len_t) + keylen + vsize;
     112         [ #  # ]:          0 :             if (i == idx+1) offset_next = offset;
     113                 :            : 
     114                 :          0 :             offset += sizeof(key_len_t) + keylen + vsize;
     115                 :            :         }
     116                 :            :         // move
     117                 :          0 :         memmove((uint8_t*)ptr + offset_next + (keylen_ins - keylen_idx),
     118                 :          0 :             (uint8_t*)ptr + offset_next, next_len);
     119                 :            :     }
     120                 :            : 
     121                 :            :     // copy key into the node
     122                 :          5 :     memcpy((uint8_t*)ptr + offset_idx, key_ptr, sizeof(key_len_t) + keylen_ins);
     123                 :            :     // copy value
     124                 :          5 :     memcpy((uint8_t*)ptr + offset_idx + sizeof(key_len_t) + keylen_ins, value, vsize);
     125                 :          5 : }
     126                 :            : 
     127                 :          1 : static void _ins_str_kv(struct bnode *node, idx_t idx, void *key, void *value)
     128                 :            : {
     129                 :            :     int ksize, vsize, i;
     130                 :            :     void *key_ptr, *ptr;
     131                 :            :     key_len_t keylen, keylen_ins;
     132                 :            :     key_len_t _keylen, _keylen_ins;
     133                 :          1 :     size_t offset, offset_idx, offset_next = 0, next_len;
     134                 :            : 
     135                 :          1 :     _get_kvsize(node->kvsize, ksize, vsize);
     136                 :          1 :     ksize = sizeof(void *);
     137                 :            : 
     138                 :          1 :     ptr = node->data;
     139                 :          1 :     offset = 0;
     140                 :            :     // linear search
     141         [ -  + ]:          1 :     for (i=0;i<idx;++i){
     142                 :          0 :         memcpy(&_keylen, (uint8_t*)ptr+offset, sizeof(key_len_t));
     143                 :          0 :         keylen = _endian_encode(_keylen);
     144                 :          0 :         offset += sizeof(key_len_t)+keylen + vsize;
     145                 :            :     }
     146                 :          1 :     offset_idx = offset;
     147                 :            : 
     148 [ +  - ][ +  - ]:          1 :     if (key && value) {
     149                 :            :         // insert
     150                 :            : 
     151                 :            :         // copy key info from KEY
     152                 :          1 :         memcpy(&key_ptr, key, ksize);
     153                 :          1 :         memcpy(&_keylen_ins, key_ptr, sizeof(key_len_t));
     154                 :          1 :         keylen_ins = _endian_decode(_keylen_ins);
     155                 :            : 
     156                 :            :         // we have to move idx ~ nentry KVs to (next) appropriate position
     157                 :          1 :         next_len = 0;
     158         [ -  + ]:          1 :         for (i=idx;i<node->nentry;++i){
     159                 :          0 :             memcpy(&_keylen, (uint8_t*)ptr + offset, sizeof(key_len_t));
     160                 :          0 :             keylen = _endian_decode(_keylen);
     161                 :          0 :             next_len += sizeof(key_len_t) + keylen + vsize;
     162                 :          0 :             offset += sizeof(key_len_t) + keylen + vsize;
     163                 :            :         }
     164                 :            : 
     165                 :            :         memmove(
     166                 :          1 :             (uint8_t*)ptr + offset_idx + sizeof(key_len_t) + keylen_ins + vsize,
     167                 :          2 :             (uint8_t*)ptr + offset_idx, next_len);
     168                 :            : 
     169                 :            :         // copy key into the node
     170                 :          1 :         memcpy((uint8_t*)ptr + offset_idx, key_ptr, sizeof(key_len_t) + keylen_ins);
     171                 :            :         // copy value
     172                 :          1 :         memcpy((uint8_t*)ptr + offset_idx + sizeof(key_len_t) + keylen_ins,
     173                 :          1 :                value, vsize);
     174                 :            :     }else{
     175                 :            :         // we have to move idx+1 ~ nentry KVs to appropriate position
     176                 :          0 :         next_len = 0;
     177         [ #  # ]:          0 :         for (i=idx;i<node->nentry;++i){
     178                 :          0 :             memcpy(&_keylen, (uint8_t*)ptr + offset, sizeof(key_len_t));
     179                 :          0 :             keylen = _endian_decode(_keylen);
     180         [ #  # ]:          0 :             if (i>idx) next_len += sizeof(key_len_t) + keylen + vsize;
     181         [ #  # ]:          0 :             if (i == idx+1) offset_next = offset;
     182                 :          0 :             offset += sizeof(key_len_t) + keylen + vsize;
     183                 :            :         }
     184                 :            :         // remove
     185                 :          0 :         memmove((uint8_t*)ptr + offset_idx, (uint8_t*)ptr + offset_next,
     186                 :          0 :                  next_len);
     187                 :            :     }
     188                 :          1 : }
     189                 :            : 
     190                 :          1 : static void _copy_str_kv(struct bnode *node_dst,
     191                 :            :                          struct bnode *node_src,
     192                 :            :                          idx_t dst_idx,
     193                 :            :                          idx_t src_idx,
     194                 :            :                          idx_t len)
     195                 :            : {
     196                 :            :     int i;
     197                 :            :     int ksize, vsize;
     198                 :            :     void *ptr_src, *ptr_dst;
     199                 :            :     key_len_t keylen, _keylen;
     200                 :            :     size_t src_offset, src_len, dst_offset;
     201                 :            : 
     202         [ -  + ]:          2 :     if (node_dst == node_src) return;
     203                 :            : 
     204                 :          1 :     _get_kvsize(node_src->kvsize, ksize, vsize);
     205                 :            : 
     206                 :          1 :     ptr_src = node_src->data;
     207                 :          1 :     ptr_dst = node_dst->data;
     208                 :            : 
     209                 :            :     // calculate offset of 0 ~ src_idx-1
     210                 :          1 :     src_offset = 0;
     211         [ -  + ]:          1 :     for (i=0;i<src_idx;++i){
     212                 :          0 :         memcpy(&_keylen, (uint8_t*)ptr_src + src_offset, sizeof(key_len_t));
     213                 :          0 :         keylen = _endian_decode(_keylen);
     214                 :          0 :         src_offset += sizeof(key_len_t) + keylen + vsize;
     215                 :            :     }
     216                 :            : 
     217                 :            :     // calculate offset of 0 ~ dst_idx-1
     218                 :          1 :     dst_offset = 0;
     219         [ -  + ]:          1 :     for (i=0;i<dst_idx;++i){
     220                 :          0 :         memcpy(&_keylen, (uint8_t*)ptr_dst + dst_offset, sizeof(key_len_t));
     221                 :          0 :         keylen = _endian_decode(_keylen);
     222                 :          0 :         dst_offset += sizeof(key_len_t) + keylen + vsize;
     223                 :            :     }
     224                 :            : 
     225                 :            :      // calculate data length to be copied
     226                 :          1 :     src_len = 0;
     227         [ +  + ]:          2 :     for (i=src_idx ; i<src_idx+len ; ++i){
     228                 :          1 :         memcpy(&_keylen, (uint8_t*)ptr_src + src_offset + src_len, sizeof(key_len_t));
     229                 :          1 :         keylen = _endian_decode(_keylen);
     230                 :          1 :         src_len += sizeof(key_len_t) + keylen + vsize;
     231                 :            :     }
     232                 :            : 
     233                 :            :     // copy
     234                 :          1 :     memcpy((uint8_t*)ptr_dst + dst_offset, (uint8_t*)ptr_src + src_offset, src_len);
     235                 :            : }
     236                 :            : 
     237                 :          4 : static size_t _get_str_kv_size(struct btree *tree, void *key, void *value)
     238                 :            : {
     239                 :            :     void *key_ptr;
     240                 :            :     key_len_t keylen, _keylen;
     241                 :            : 
     242         [ +  + ]:          4 :     if (key) {
     243                 :          2 :         memcpy(&key_ptr, key, sizeof(void *));
     244                 :          2 :         memcpy(&_keylen, key_ptr, sizeof(key_len_t));
     245                 :          2 :         keylen = _endian_decode(_keylen);
     246                 :            :     }
     247                 :            : 
     248 [ +  + ][ +  + ]:          4 :     return ((key)?(sizeof(key_len_t) + keylen):0) + ((value)?tree->vsize:0);
     249                 :            : }
     250                 :            : 
     251                 :          3 : static size_t _get_str_data_size(
     252                 :            :     struct bnode *node, void *new_minkey, void *key_arr, void *value_arr, size_t len)
     253                 :            : {
     254                 :            :     int ksize, vsize, i;
     255                 :            :     void *ptr, *key_ptr;
     256                 :            :     size_t offset, size;
     257                 :            :     key_len_t keylen, _keylen;
     258                 :            : 
     259                 :          3 :     _get_kvsize(node->kvsize, ksize, vsize);
     260                 :          3 :     ksize = sizeof(void *);
     261                 :            : 
     262                 :          3 :     ptr = node->data;
     263                 :          3 :     offset = size = 0;
     264                 :            : 
     265         [ +  + ]:          7 :     for (i=0;i<node->nentry;++i){
     266                 :          4 :         memcpy(&_keylen, (uint8_t*)ptr + offset, sizeof(key_len_t));
     267                 :          4 :         keylen = _endian_decode(_keylen);
     268                 :          4 :         offset += sizeof(key_len_t) + keylen + vsize;
     269                 :            : 
     270 [ +  + ][ +  + ]:          4 :         if (new_minkey && i==0) {
     271                 :            :             // if the minimum key should be replaced to NEW_MINKEY
     272                 :          1 :             memcpy(&key_ptr, new_minkey, ksize);
     273                 :          1 :             memcpy(&_keylen, key_ptr, sizeof(key_len_t));
     274                 :          1 :             keylen = _endian_decode(_keylen);
     275                 :            :         }
     276                 :          4 :         size += sizeof(key_len_t) + keylen + vsize;
     277                 :            :     }
     278                 :            : 
     279 [ +  - ][ +  - ]:          3 :     if (key_arr && value_arr && len > 0) {
                 [ +  - ]
     280         [ +  + ]:          9 :         for (i=0;i<len;++i){
     281                 :          6 :             memcpy(&key_ptr, (uint8_t*)key_arr + ksize*i, ksize);
     282                 :          6 :             memcpy(&_keylen, key_ptr, sizeof(key_len_t));
     283                 :          6 :             keylen = _endian_decode(_keylen);
     284                 :          6 :             size += sizeof(key_len_t) + keylen + vsize;
     285                 :            :         }
     286                 :            :     }
     287                 :            : 
     288                 :          3 :     return size;
     289                 :            : }
     290                 :            : 
     291                 :          2 : INLINE void _init_str_kv_var(struct btree *tree, void *key, void *value)
     292                 :            : {
     293         [ +  + ]:          2 :     if (key) memset(key, 0, sizeof(void *));
     294         [ +  + ]:          2 :     if (value) memset(value, 0, tree->vsize);
     295                 :          2 : }
     296                 :            : 
     297                 :          2 : static void _free_str_kv_var(struct btree *tree, void *key, void *value)
     298                 :            : {
     299                 :            :     void *key_ptr;
     300                 :            : 
     301                 :          2 :     memcpy(&key_ptr, key, sizeof(void *));
     302         [ +  + ]:          2 :     if (key_ptr) {
     303                 :          1 :         free(key_ptr);
     304                 :          1 :         key_ptr = NULL;
     305                 :          1 :         memcpy(key, &key_ptr, sizeof(void *));
     306                 :            :     }
     307                 :          2 : }
     308                 :            : 
     309                 :          2 : static void _set_str_key(struct btree *tree, void *dst, void *src)
     310                 :            : {
     311                 :            :     void *key_ptr_old, *key_ptr_new;
     312                 :            :     key_len_t keylen_new, _keylen_new, inflen, keylen_alloc;
     313                 :          2 :     size_t size_key = sizeof(key_len_t);
     314                 :            : 
     315                 :          2 :     memset(&inflen, 0xff, sizeof(inflen));
     316                 :            : 
     317                 :          2 :     memcpy(&key_ptr_new, src, sizeof(void *));
     318                 :          2 :     memcpy(&_keylen_new, key_ptr_new, size_key);
     319                 :          2 :     keylen_new = _endian_decode(_keylen_new);
     320                 :            : 
     321                 :            :     // free previous key (if exist)
     322                 :          2 :     memcpy(&key_ptr_old, dst, sizeof(void *));
     323         [ +  + ]:          2 :     if (key_ptr_old) {
     324                 :          1 :         free(key_ptr_old);
     325                 :            :     }
     326                 :            : 
     327         [ +  - ]:          2 :     keylen_alloc = (keylen_new == inflen)?(0):(keylen_new);
     328                 :          2 :     key_ptr_old = (void*)malloc(size_key + keylen_alloc);
     329                 :            :     // copy keylen
     330                 :          2 :     memcpy(key_ptr_old, key_ptr_new, size_key);
     331         [ +  - ]:          2 :     if (keylen_alloc) {
     332                 :          2 :         memcpy((uint8_t*)key_ptr_old + size_key,
     333                 :          2 :                (uint8_t*)key_ptr_new + size_key, keylen_new);
     334                 :            :     }
     335                 :          2 :     memcpy(dst, &key_ptr_old, sizeof(void *));
     336                 :          2 : }
     337                 :            : 
     338                 :          2 : INLINE void _set_str_value(struct btree *tree, void *dst, void *src)
     339                 :            : {
     340                 :          2 :     memcpy(dst, src, tree->vsize);
     341                 :          2 : }
     342                 :            : 
     343                 :          3 : INLINE void _get_str_nth_idx(struct bnode *node, idx_t num,
     344                 :            :                              idx_t den, idx_t *idx)
     345                 :            : {
     346                 :          3 :     size_t rem = node->nentry - (int)(node->nentry / den) * den;
     347                 :          3 :     *idx = (int)(node->nentry / den) * num + ((num < rem)?(num):(rem));
     348                 :          3 : }
     349                 :            : 
     350                 :          0 : INLINE void _get_str_nth_splitter(struct bnode *prev_node,
     351                 :            :                                   struct bnode *node, void *key)
     352                 :            : {
     353                 :            :     // always return the smallest key of 'node'
     354                 :          0 :     _get_str_kv(node, 0, key, NULL);
     355                 :          0 : }
     356                 :            : 
     357                 :          1 : void btree_str_kv_set_key(void *key, void *str, size_t len)
     358                 :            : {
     359                 :            :     void *key_ptr;
     360                 :          1 :     key_len_t keylen = len;
     361                 :            :     key_len_t _keylen;
     362                 :            : 
     363                 :          1 :     key_ptr = (void *)malloc(sizeof(key_len_t) + keylen);
     364                 :          1 :     _keylen = _endian_encode(keylen);
     365                 :          1 :     memcpy(key_ptr, &_keylen, sizeof(key_len_t));
     366                 :          1 :     memcpy((uint8_t*)key_ptr + sizeof(key_len_t), str, keylen);
     367                 :          1 :     memcpy(key, &key_ptr, sizeof(void *));
     368                 :          1 : }
     369                 :            : 
     370                 :            : // create an infinite key that is larger than any other keys
     371                 :          0 : void btree_str_kv_set_inf_key(void *key)
     372                 :            : {
     373                 :            :     void *key_ptr;
     374                 :            :     key_len_t keylen;
     375                 :            :     key_len_t _keylen;
     376                 :            : 
     377                 :            :     // just containing length (0xff..) info
     378                 :          0 :     key_ptr = (void *)malloc(sizeof(key_len_t));
     379                 :          0 :     memset(&keylen, 0xff, sizeof(key_len_t));
     380                 :          0 :     _keylen = _endian_encode(keylen);
     381                 :          0 :     memcpy(key_ptr, &_keylen, sizeof(key_len_t));
     382                 :          0 :     memcpy(key, &key_ptr, sizeof(void *));
     383                 :          0 : }
     384                 :            : 
     385                 :            : // return true if KEY is infinite key
     386                 :          0 : int btree_str_kv_is_inf_key(void *key)
     387                 :            : {
     388                 :            :     void *key_ptr;
     389                 :            :     key_len_t keylen, inflen;
     390                 :            :     key_len_t _keylen;
     391                 :            : 
     392                 :          0 :     memset(&inflen, 0xff, sizeof(key_len_t));
     393                 :          0 :     memcpy(&key_ptr, key, sizeof(void *));
     394         [ #  # ]:          0 :     if (key_ptr) {
     395                 :          0 :         memcpy(&_keylen, key_ptr, sizeof(key_len_t));
     396                 :          0 :         keylen = _endian_decode(_keylen);
     397         [ #  # ]:          0 :         if (keylen == inflen) {
     398                 :          0 :             return 1;
     399                 :            :         }
     400                 :            :     }
     401                 :          0 :     return 0;
     402                 :            : }
     403                 :            : 
     404                 :          2 : void btree_str_kv_get_key(void *key, void *strbuf, size_t *len)
     405                 :            : {
     406                 :            :     void *key_ptr;
     407                 :            :     key_len_t keylen, inflen;
     408                 :            :     key_len_t _keylen;
     409                 :            : 
     410                 :          2 :     memset(&inflen, 0xff, sizeof(key_len_t));
     411                 :            : 
     412                 :          2 :     memcpy(&key_ptr, key, sizeof(void *));
     413         [ +  + ]:          2 :     if (key_ptr) {
     414                 :          1 :         memcpy(&_keylen, key_ptr, sizeof(key_len_t));
     415                 :          1 :         keylen = _endian_decode(_keylen);
     416                 :            : 
     417                 :          1 :         memcpy(strbuf, (uint8_t*)key_ptr + sizeof(key_len_t), keylen);
     418                 :          1 :         *len = keylen;
     419                 :            :     } else {
     420                 :          1 :         *len = 0;
     421                 :            :     }
     422                 :          2 : }
     423                 :            : 
     424                 :          1 : void btree_str_kv_free_key(void *key)
     425                 :            : {
     426                 :            :     void *key_ptr;
     427                 :          1 :     memcpy(&key_ptr, key, sizeof(void *));
     428         [ +  - ]:          1 :     if (key_ptr) free(key_ptr);
     429                 :          1 :     key_ptr = NULL;
     430                 :          1 :     memcpy(key, &key_ptr, sizeof(void *));
     431                 :          1 : }
     432                 :            : 
     433                 :          1 : INLINE bid_t _str_value_to_bid_64(void *value)
     434                 :            : {
     435                 :          1 :     return *((bid_t *)value);
     436                 :            : }
     437                 :            : 
     438                 :          1 : INLINE void* _str_bid_to_value_64(bid_t *bid)
     439                 :            : {
     440                 :          1 :     return (void *)bid;
     441                 :            : }
     442                 :            : 
     443                 :          7 : int _cmp_str64(void *key1, void *key2, void* aux)
     444                 :            : {
     445                 :            :     (void) aux;
     446                 :            :     void *key_ptr1, *key_ptr2;
     447                 :            :     key_len_t keylen1, keylen2, inflen;
     448                 :            :     key_len_t _keylen1, _keylen2;
     449                 :            : 
     450                 :          7 :     memcpy(&key_ptr1, key1, sizeof(void *));
     451                 :          7 :     memcpy(&key_ptr2, key2, sizeof(void *));
     452                 :            : 
     453 [ +  + ][ +  + ]:          7 :     if (key_ptr1 == NULL && key_ptr2 == NULL) {
     454                 :          1 :         return 0;
     455         [ +  + ]:          6 :     } else if (key_ptr1 == NULL) {
     456                 :          1 :         return -1;
     457         [ +  + ]:          5 :     } else if (key_ptr2 == NULL) {
     458                 :          1 :         return 1;
     459                 :            :     }
     460                 :            : 
     461                 :          4 :     memcpy(&_keylen1, key_ptr1, sizeof(key_len_t));
     462                 :          4 :     memcpy(&_keylen2, key_ptr2, sizeof(key_len_t));
     463                 :          4 :     keylen1 = _endian_decode(_keylen1);
     464                 :          4 :     keylen2 = _endian_decode(_keylen2);
     465                 :            : 
     466                 :          4 :     memset(&inflen, 0xff, sizeof(key_len_t));
     467         [ -  + ]:          4 :     if (keylen1 == inflen) {
     468                 :          0 :         return 1;
     469         [ -  + ]:          4 :     } else if (keylen2 == inflen) {
     470                 :          0 :         return -1;
     471                 :            :     }
     472                 :            : 
     473         [ +  + ]:          4 :     if (keylen1 == keylen2) {
     474                 :            :         return memcmp((uint8_t*)key_ptr1 + sizeof(key_len_t),
     475                 :          2 :                       (uint8_t*)key_ptr2 + sizeof(key_len_t), keylen1);
     476                 :            :     }else{
     477         [ +  - ]:          2 :         key_len_t len = MIN(keylen1, keylen2);
     478                 :            :         int cmp = memcmp((uint8_t*)key_ptr1 + sizeof(key_len_t),
     479                 :          2 :                          (uint8_t*)key_ptr2 + sizeof(key_len_t), len);
     480         [ +  + ]:          2 :         if (cmp != 0) return cmp;
     481                 :            :         else {
     482                 :          7 :             return (int)((int)keylen1 - (int)keylen2);
     483                 :            :         }
     484                 :            :     }
     485                 :            : }
     486                 :            : 
     487                 :         15 : struct btree_kv_ops * btree_str_kv_get_kb64_vb64(struct btree_kv_ops *kv_ops)
     488                 :            : {
     489                 :            :     struct btree_kv_ops *btree_kv_ops;
     490         [ +  + ]:         15 :     if (kv_ops) {
     491                 :          9 :         btree_kv_ops = kv_ops;
     492                 :            :     }else{
     493                 :          6 :         btree_kv_ops = (struct btree_kv_ops *)malloc(sizeof(struct btree_kv_ops));
     494                 :            :     }
     495                 :            : 
     496                 :         15 :     btree_kv_ops->get_kv = _get_str_kv;
     497                 :         15 :     btree_kv_ops->set_kv = _set_str_kv;
     498                 :         15 :     btree_kv_ops->ins_kv = _ins_str_kv;
     499                 :         15 :     btree_kv_ops->copy_kv = _copy_str_kv;
     500                 :         15 :     btree_kv_ops->set_key = _set_str_key;
     501                 :         15 :     btree_kv_ops->set_value = _set_str_value;
     502                 :         15 :     btree_kv_ops->get_data_size = _get_str_data_size;
     503                 :         15 :     btree_kv_ops->get_kv_size = _get_str_kv_size;
     504                 :         15 :     btree_kv_ops->init_kv_var = _init_str_kv_var;
     505                 :         15 :     btree_kv_ops->free_kv_var = _free_str_kv_var;
     506                 :            : 
     507                 :         15 :     btree_kv_ops->get_nth_idx = _get_str_nth_idx;
     508                 :         15 :     btree_kv_ops->get_nth_splitter = _get_str_nth_splitter;
     509                 :            : 
     510                 :         15 :     btree_kv_ops->cmp = _cmp_str64;
     511                 :            : 
     512                 :         15 :     btree_kv_ops->bid2value = _str_bid_to_value_64;
     513                 :         15 :     btree_kv_ops->value2bid = _str_value_to_bid_64;
     514                 :            : 
     515                 :         15 :     return btree_kv_ops;
     516                 :            : }

Generated by: LCOV version 1.11