Coverage Report

Created: 2024-01-20 12:25

/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
617k
  void init () { clear (); }
hb_cache_t<21u, 16u, 8u, true>::init()
Line
Count
Source
53
595k
  void init () { clear (); }
hb_cache_t<24u, 16u, 8u, true>::init()
Line
Count
Source
53
22.4k
  void init () { clear (); }
54
55
  void clear ()
56
617k
  {
57
158M
    for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
58
158M
      values[i] = -1;
59
617k
  }
hb_cache_t<21u, 16u, 8u, true>::clear()
Line
Count
Source
56
595k
  {
57
153M
    for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
58
152M
      values[i] = -1;
59
595k
  }
hb_cache_t<24u, 16u, 8u, true>::clear()
Line
Count
Source
56
22.4k
  {
57
5.76M
    for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
58
5.74M
      values[i] = -1;
59
22.4k
  }
60
61
  bool get (unsigned int key, unsigned int *value) const
62
51.3M
  {
63
51.3M
    unsigned int k = key & ((1u<<cache_bits)-1);
64
51.3M
    unsigned int v = values[k];
65
51.3M
    if ((key_bits + value_bits - cache_bits == 8 * sizeof (item_t) && v == (unsigned int) -1) ||
66
51.3M
  (v >> value_bits) != (key >> cache_bits))
67
49.4M
      return false;
68
1.85M
    *value = v & ((1u<<value_bits)-1);
69
1.85M
    return true;
70
51.3M
  }
hb_cache_t<21u, 16u, 8u, true>::get(unsigned int, unsigned int*) const
Line
Count
Source
62
50.7M
  {
63
50.7M
    unsigned int k = key & ((1u<<cache_bits)-1);
64
50.7M
    unsigned int v = values[k];
65
50.7M
    if ((key_bits + value_bits - cache_bits == 8 * sizeof (item_t) && v == (unsigned int) -1) ||
66
50.7M
  (v >> value_bits) != (key >> cache_bits))
67
49.3M
      return false;
68
1.41M
    *value = v & ((1u<<value_bits)-1);
69
1.41M
    return true;
70
50.7M
  }
hb_cache_t<24u, 16u, 8u, true>::get(unsigned int, unsigned int*) const
Line
Count
Source
62
616k
  {
63
616k
    unsigned int k = key & ((1u<<cache_bits)-1);
64
616k
    unsigned int v = values[k];
65
616k
    if ((key_bits + value_bits - cache_bits == 8 * sizeof (item_t) && v == (unsigned int) -1) ||
66
616k
  (v >> value_bits) != (key >> cache_bits))
67
175k
      return false;
68
441k
    *value = v & ((1u<<value_bits)-1);
69
441k
    return true;
70
616k
  }
71
72
  bool set (unsigned int key, unsigned int value)
73
2.40M
  {
74
2.40M
    if (unlikely ((key >> key_bits) || (value >> value_bits)))
75
625k
      return false; /* Overflows */
76
1.77M
    unsigned int k = key & ((1u<<cache_bits)-1);
77
1.77M
    unsigned int v = ((key>>cache_bits)<<value_bits) | value;
78
1.77M
    values[k] = v;
79
1.77M
    return true;
80
2.40M
  }
hb_cache_t<21u, 16u, 8u, true>::set(unsigned int, unsigned int)
Line
Count
Source
73
2.22M
  {
74
2.22M
    if (unlikely ((key >> key_bits) || (value >> value_bits)))
75
507k
      return false; /* Overflows */
76
1.71M
    unsigned int k = key & ((1u<<cache_bits)-1);
77
1.71M
    unsigned int v = ((key>>cache_bits)<<value_bits) | value;
78
1.71M
    values[k] = v;
79
1.71M
    return true;
80
2.22M
  }
hb_cache_t<24u, 16u, 8u, true>::set(unsigned int, unsigned int)
Line
Count
Source
73
175k
  {
74
175k
    if (unlikely ((key >> key_bits) || (value >> value_bits)))
75
118k
      return false; /* Overflows */
76
56.8k
    unsigned int k = key & ((1u<<cache_bits)-1);
77
56.8k
    unsigned int v = ((key>>cache_bits)<<value_bits) | value;
78
56.8k
    values[k] = v;
79
56.8k
    return true;
80
175k
  }
81
82
  private:
83
  item_t values[1u<<cache_bits];
84
};
85
86
87
#endif /* HB_CACHE_HH */