blob: 2e98187b5021a9bcaf346185d3d55136984ef44b [file] [log] [blame]
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +02001/*
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
Behdad Esfahbodbb48bf52021-07-08 10:53:45 -060033/* Implements a lockfree cache for int->int functions. */
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020034
Behdad Esfahbodec90d1e2022-08-03 13:00:48 -060035template <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>
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020039struct hb_cache_t
40{
Behdad Esfahbod99070a72022-08-03 13:19:33 -060041 using item_t = typename std::conditional<thread_safe,
Behdad Esfahboda924bbc2023-01-30 14:13:33 -070042 typename std::conditional<key_bits + value_bits - cache_bits <= 16,
43 hb_atomic_short_t,
44 hb_atomic_int_t>::type,
Behdad Esfahbod99070a72022-08-03 13:19:33 -060045 typename std::conditional<key_bits + value_bits - cache_bits <= 16,
46 short,
47 int>::type
48 >::type;
Behdad Esfahbodec90d1e2022-08-03 13:00:48 -060049
Behdad Esfahbodb78546b2022-08-03 13:02:18 -060050 static_assert ((key_bits >= cache_bits), "");
Behdad Esfahbod9855b672022-11-16 13:37:34 -070051 static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), "");
Behdad Esfahbodb78546b2022-08-03 13:02:18 -060052
Behdad Esfahbod115d5722023-01-28 13:22:08 -070053 hb_cache_t () { init (); }
54
Ebrahim Byagowie4120082018-12-17 21:31:01 +033055 void init () { clear (); }
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020056
Ebrahim Byagowie4120082018-12-17 21:31:01 +033057 void clear ()
Behdad Esfahbod30546872018-09-27 16:54:23 -040058 {
59 for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
Behdad Esfahbodf73c15c2022-08-03 12:54:03 -060060 values[i] = -1;
Behdad Esfahbod30546872018-09-27 16:54:23 -040061 }
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020062
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +033063 bool get (unsigned int key, unsigned int *value) const
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020064 {
65 unsigned int k = key & ((1u<<cache_bits)-1);
Behdad Esfahbodf73c15c2022-08-03 12:54:03 -060066 unsigned int v = values[k];
Behdad Esfahbodb78546b2022-08-03 13:02:18 -060067 if ((key_bits + value_bits - cache_bits == 8 * sizeof (item_t) && v == (unsigned int) -1) ||
Behdad Esfahboddf827a62018-10-01 11:34:20 +020068 (v >> value_bits) != (key >> cache_bits))
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020069 return false;
70 *value = v & ((1u<<value_bits)-1);
71 return true;
72 }
73
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +033074 bool set (unsigned int key, unsigned int value)
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020075 {
76 if (unlikely ((key >> key_bits) || (value >> value_bits)))
77 return false; /* Overflows */
78 unsigned int k = key & ((1u<<cache_bits)-1);
79 unsigned int v = ((key>>cache_bits)<<value_bits) | value;
Behdad Esfahbodf73c15c2022-08-03 12:54:03 -060080 values[k] = v;
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020081 return true;
82 }
83
84 private:
Behdad Esfahbodec90d1e2022-08-03 13:00:48 -060085 item_t values[1u<<cache_bits];
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020086};
87
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020088
89#endif /* HB_CACHE_HH */