Coverage Report

Created: 2024-01-23 06:23

/src/harfbuzz/src/hb-cache.hh
Line
Count
Source
1
/*
2
 * Copyright © 2012  Google, Inc.
3
 *
4
 *  This is part of HarfBuzz, a text shaping library.
5
 *
6
 * Permission is hereby granted, without written agreement and without
7
 * license or royalty fees, to use, copy, modify, and distribute this
8
 * software and its documentation for any purpose, provided that the
9
 * above copyright notice and the following two paragraphs appear in
10
 * all copies of this software.
11
 *
12
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16
 * DAMAGE.
17
 *
18
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23
 *
24
 * Google Author(s): Behdad Esfahbod
25
 */
26
27
#ifndef HB_CACHE_HH
28
#define HB_CACHE_HH
29
30
#include "hb.hh"
31
32
33
/* Implements a lockfree cache for int->int functions. */
34
35
template <unsigned int key_bits=16,
36
   unsigned int value_bits=8 + 32 - key_bits,
37
   unsigned int cache_bits=8,
38
   bool thread_safe=true>
39
struct hb_cache_t
40
{
41
  using item_t = typename std::conditional<thread_safe,
42
             hb_atomic_int_t,
43
             typename std::conditional<key_bits + value_bits - cache_bits <= 16,
44
                     short,
45
                     int>::type
46
            >::type;
47
48
  static_assert ((key_bits >= cache_bits), "");
49
  static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), "");
50
51
  hb_cache_t () { init (); }
52
53
623k
  void init () { clear (); }
hb_cache_t<21u, 16u, 8u, true>::init()
Line
Count
Source
53
594k
  void init () { clear (); }
hb_cache_t<24u, 16u, 8u, true>::init()
Line
Count
Source
53
28.5k
  void init () { clear (); }
54
55
  void clear ()
56
623k
  {
57
160M
    for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
58
159M
      values[i] = -1;
59
623k
  }
hb_cache_t<21u, 16u, 8u, true>::clear()
Line
Count
Source
56
594k
  {
57
152M
    for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
58
152M
      values[i] = -1;
59
594k
  }
hb_cache_t<24u, 16u, 8u, true>::clear()
Line
Count
Source
56
28.5k
  {
57
7.32M
    for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
58
7.29M
      values[i] = -1;
59
28.5k
  }
60
61
  bool get (unsigned int key, unsigned int *value) const
62
48.3M
  {
63
48.3M
    unsigned int k = key & ((1u<<cache_bits)-1);
64
48.3M
    unsigned int v = values[k];
65
48.3M
    if ((key_bits + value_bits - cache_bits == 8 * sizeof (item_t) && v == (unsigned int) -1) ||
66
48.3M
  (v >> value_bits) != (key >> cache_bits))
67
46.6M
      return false;
68
1.69M
    *value = v & ((1u<<value_bits)-1);
69
1.69M
    return true;
70
48.3M
  }
hb_cache_t<21u, 16u, 8u, true>::get(unsigned int, unsigned int*) const
Line
Count
Source
62
47.4M
  {
63
47.4M
    unsigned int k = key & ((1u<<cache_bits)-1);
64
47.4M
    unsigned int v = values[k];
65
47.4M
    if ((key_bits + value_bits - cache_bits == 8 * sizeof (item_t) && v == (unsigned int) -1) ||
66
47.4M
  (v >> value_bits) != (key >> cache_bits))
67
46.3M
      return false;
68
1.05M
    *value = v & ((1u<<value_bits)-1);
69
1.05M
    return true;
70
47.4M
  }
hb_cache_t<24u, 16u, 8u, true>::get(unsigned int, unsigned int*) const
Line
Count
Source
62
900k
  {
63
900k
    unsigned int k = key & ((1u<<cache_bits)-1);
64
900k
    unsigned int v = values[k];
65
900k
    if ((key_bits + value_bits - cache_bits == 8 * sizeof (item_t) && v == (unsigned int) -1) ||
66
900k
  (v >> value_bits) != (key >> cache_bits))
67
260k
      return false;
68
639k
    *value = v & ((1u<<value_bits)-1);
69
639k
    return true;
70
900k
  }
71
72
  bool set (unsigned int key, unsigned int value)
73
1.92M
  {
74
1.92M
    if (unlikely ((key >> key_bits) || (value >> value_bits)))
75
375k
      return false; /* Overflows */
76
1.55M
    unsigned int k = key & ((1u<<cache_bits)-1);
77
1.55M
    unsigned int v = ((key>>cache_bits)<<value_bits) | value;
78
1.55M
    values[k] = v;
79
1.55M
    return true;
80
1.92M
  }
hb_cache_t<21u, 16u, 8u, true>::set(unsigned int, unsigned int)
Line
Count
Source
73
1.66M
  {
74
1.66M
    if (unlikely ((key >> key_bits) || (value >> value_bits)))
75
244k
      return false; /* Overflows */
76
1.42M
    unsigned int k = key & ((1u<<cache_bits)-1);
77
1.42M
    unsigned int v = ((key>>cache_bits)<<value_bits) | value;
78
1.42M
    values[k] = v;
79
1.42M
    return true;
80
1.66M
  }
hb_cache_t<24u, 16u, 8u, true>::set(unsigned int, unsigned int)
Line
Count
Source
73
260k
  {
74
260k
    if (unlikely ((key >> key_bits) || (value >> value_bits)))
75
130k
      return false; /* Overflows */
76
129k
    unsigned int k = key & ((1u<<cache_bits)-1);
77
129k
    unsigned int v = ((key>>cache_bits)<<value_bits) | value;
78
129k
    values[k] = v;
79
129k
    return true;
80
260k
  }
81
82
  private:
83
  item_t values[1u<<cache_bits];
84
};
85
86
87
#endif /* HB_CACHE_HH */