blob: eb48f18cf949894bc590e7c2e6f2f4ee45131c9b [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
33/* Implements a lock-free cache for int->int functions. */
34
35template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bits>
36struct hb_cache_t
37{
Behdad Esfahbod606bf572018-09-16 19:33:48 +020038 static_assert ((key_bits >= cache_bits), "");
Behdad Esfahboddf827a62018-10-01 11:34:20 +020039 static_assert ((key_bits + value_bits - cache_bits <= 8 * sizeof (hb_atomic_int_t)), "");
Behdad Esfahbod3426a362018-10-01 12:55:57 +020040 static_assert (sizeof (hb_atomic_int_t) == sizeof (unsigned int), "");
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020041
42 inline void init (void) { clear (); }
43 inline void fini (void) {}
44
45 inline void clear (void)
Behdad Esfahbod30546872018-09-27 16:54:23 -040046 {
47 for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
48 values[i].set_relaxed (-1);
49 }
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020050
Behdad Esfahbod0ea42e12018-09-11 12:22:42 +020051 inline bool get (unsigned int key, unsigned int *value) const
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020052 {
53 unsigned int k = key & ((1u<<cache_bits)-1);
54 unsigned int v = values[k].get_relaxed ();
Behdad Esfahboddf827a62018-10-01 11:34:20 +020055 if ((key_bits + value_bits - cache_bits == 8 * sizeof (hb_atomic_int_t) && v == (unsigned int) -1) ||
56 (v >> value_bits) != (key >> cache_bits))
Behdad Esfahbod0f520ad2018-09-11 12:02:34 +020057 return false;
58 *value = v & ((1u<<value_bits)-1);
59 return true;
60 }
61
62 inline bool set (unsigned int key, unsigned int value)
63 {
64 if (unlikely ((key >> key_bits) || (value >> value_bits)))
65 return false; /* Overflows */
66 unsigned int k = key & ((1u<<cache_bits)-1);
67 unsigned int v = ((key>>cache_bits)<<value_bits) | value;
68 values[k].set_relaxed (v);
69 return true;
70 }
71
72 private:
73 hb_atomic_int_t values[1u<<cache_bits];
74};
75
76typedef hb_cache_t<21, 16, 8> hb_cmap_cache_t;
77typedef hb_cache_t<16, 24, 8> hb_advance_cache_t;
78
79
80#endif /* HB_CACHE_HH */