package harfbuzz

// Code generated by typesetting-utils/generators/cache/gen.go. DO NOT EDIT.

/* Implements caches for integers key->value functions.
 *
 * The cache is a fixed-size array of 8-bit, 16-bit or 32-bit integers,
 * typically 256 elements.
 *
 * The key is split into two parts: the cache index (high bits)
 * and the rest (low bits).
 *
 * The memory layout is the following :
 * 	KEY 		= <key bits - cache bits><cache bits>
 * 	VALUE 	= <key bits - cache bits><value bits>
 * with the constraints
 *	KEY in [0, 2^key bits[
 *	VALUE in [0, 2^value bits[
 *
 * The cache index is used to index into the array. The array
 * member is an integer that is used BOTH
 * to store the low bits of the key, and the value.
 *
 * The value is stored in the least significant bits of the integer.
 * The low bits of the key are stored in the most significant bits
 * of the integer.
 *
 * A cache hit is detected by comparing the low bits of the key
 * with the high bits of the integer at the array position indexed
 * by the high bits of the key. If they match, the value is extracted
 * from the least significant bits of the integer and returned.
 * Otherwise, a cache miss is reported.
 *
 * Cache operations (storage and retrieval) involve just a few
 * arithmetic operations and a single memory access.
 */

// cache15_8_7 is a cache for integer (key, value) pairs,
// with 0 <= key < 32768 and 0 <= value < 256
type cache15_8_7 [1 << 7]uint16

// clear should be used as init function
func (c *cache15_8_7) clear() {
	for i := range c {
		c[i] = ^uint16(0)
	}
}

func (c cache15_8_7) get(key uint16) (uint16, bool) {
	k := key & ((1 << 7) - 1)
	v := c[k]
	if v == ^uint16(0) || (v>>8) != uint16(key>>7) {
		return 0, false
	}
	return v & ((1 << 8) - 1), true
}

func (c *cache15_8_7) set(key uint16, value uint16) {
	if (key>>15) != 0 || (value>>8) != 0 { /* overflows */
		return
	}
	c.setUnchecked(key, value)
}

// assumes key < 32768 and value < 256
func (c *cache15_8_7) setUnchecked(key uint16, value uint16) {
	k := key & ((1 << 7) - 1)
	v := (uint16(key>>7) << 8) | value
	c[k] = v
}

// cache21_3_8 is a cache for integer (key, value) pairs,
// with 0 <= key < 2097152 and 0 <= value < 8
type cache21_3_8 [1 << 8]uint16

// clear should be used as init function
func (c *cache21_3_8) clear() {
	for i := range c {
		c[i] = ^uint16(0)
	}
}

func (c cache21_3_8) get(key uint32) (uint16, bool) {
	k := key & ((1 << 8) - 1)
	v := c[k]
	if v == ^uint16(0) || (v>>3) != uint16(key>>8) {
		return 0, false
	}
	return v & ((1 << 3) - 1), true
}

func (c *cache21_3_8) set(key uint32, value uint16) {
	if (key>>21) != 0 || (value>>3) != 0 { /* overflows */
		return
	}
	c.setUnchecked(key, value)
}

// assumes key < 2097152 and value < 8
func (c *cache21_3_8) setUnchecked(key uint32, value uint16) {
	k := key & ((1 << 8) - 1)
	v := (uint16(key>>8) << 3) | value
	c[k] = v
}
