--TEST--
Test > operator : different types
--FILE--
<?php
$valid_true = array(1, "1", "true", 1.0, array(1));
$valid_false = array(0, "", 0.0, array(), NULL);

$int1 = 679;
$int2 = -67835;
$valid_int1 = array("678", "678abc", " 678", "678  ", 678.0, 6.789E2, "+678", +678);
$valid_int2 = array("-67836", "-67836abc", " -67836", "-67836  ", -67835.0001, -6.78351E4);
$invalid_int1 = array(679, "679");
$invalid_int2 = array(-67835, "-67835");

$float1 = 57385.45835;
$float2 = -67345.76567;
$valid_float1 = array("57385.45834",  "57385.45834aaa", "  57385.45834", 5.738545834e4);
$valid_float2 = array("-67345.76568", "-67345.76568aaa", "  -67345.76568", -6.734576568E4);
$invalid_float1 = array(57385.45835, 5.738545835e4);
$invalid_float2 = array(-67345.76567, -6.734576567E4);

$toCompare = array(
// boolean test will result in both sides being converted to boolean so !0 = true and true is not > true for example
// also note that a string of "0" is converted to false but a string of "0.0" is converted to true
// false cannot be tested as 0 can never be > 0 or 1
  true, $valid_false, $valid_true,
  $int1, $valid_int1, $invalid_int1,
  $int2, $valid_int2, $invalid_int2,
  $float1, $valid_float1, $invalid_float1,
  $float2, $valid_float2, $invalid_float2
);

$failed = false;
for ($i = 0; $i < count($toCompare); $i +=3) {
   $typeToTest = $toCompare[$i];
   $valid_compares = $toCompare[$i + 1];
   $invalid_compares = $toCompare[$i + 2];

   foreach($valid_compares as $compareVal) {
      if ($typeToTest > $compareVal) {
         // do nothing
      }
      else {
         echo "FAILED: '$typeToTest' <= '$compareVal'\n";
         $failed = true;
      }
   }

   foreach($invalid_compares as $compareVal) {
      if ($typeToTest > $compareVal) {
         echo "FAILED: '$typeToTest' > '$compareVal'\n";
         $failed = true;
      }
   }

}
if ($failed == false) {
   echo "Test Passed\n";
}
?>
===DONE===
--EXPECT--
Test Passed
===DONE===

{'repo_name': 'MagicalTux/goro', 'stars': '659', 'repo_language': 'PHP', 'file_name': 'compatibility.md', 'mime_type': 'text/plain', 'hash': 8460741207141823052, 'source_dataset': 'data'}


/*
 * Copyright (c) 2015-2018, Intel Corporation
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of Intel Corporation nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/** \file
 * \brief Multibit: fast bitset structure, main runtime.
 *
 * *Structure*
 *
 * For sizes <= MMB_FLAT_MAX_BITS, a flat bit vector is used, stored as N
 * 64-bit blocks followed by one "runt block".
 *
 * In larger cases, we use a sequence of blocks forming a tree. Each bit in an
 * internal block indicates whether its child block contains valid data. Every
 * level bar the last is complete. The last level is just a basic bit vector.
 *
 * -----------------------------------------------------------------------------
 * WARNING:
 *
 * mmbit code assumes that it is legal to load 8 bytes before the end of the
 * mmbit. This means that for small mmbits (< 8byte), data may be read from
 * before the base pointer. It is the user's responsibility to ensure that this
 * is possible.
 * -----------------------------------------------------------------------------
 */
#ifndef MULTIBIT_H
#define MULTIBIT_H

#include "config.h"
#include "ue2common.h"
#include "bitutils.h"
#include "partial_store.h"
#include "unaligned.h"
#include "multibit_internal.h"

#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif

#define MMB_ONE (1ULL)
#define MMB_ALL_ONES (0xffffffffffffffffULL)

/** \brief Number of bits in a block. */
#define MMB_KEY_BITS (sizeof(MMB_TYPE) * 8)

#define MMB_KEY_MASK (MMB_KEY_BITS - 1)

// Key structure defines
#define MMB_KEY_SHIFT 6

/** \brief Max size of a flat multibit. */
#define MMB_FLAT_MAX_BITS 256

// Utility functions and data
// see multibit.c for contents
extern const u8 mmbit_keyshift_lut[32];
extern const u8 mmbit_maxlevel_from_keyshift_lut[32];
extern const u8 mmbit_maxlevel_direct_lut[32];
extern const u32 mmbit_root_offset_from_level[7];
extern const u64a mmbit_zero_to_lut[65];

static really_inline
MMB_TYPE mmb_load(const u8 * bits) {
    return unaligned_load_u64a(bits);
}

static really_inline
void mmb_store(u8 *bits, MMB_TYPE val) {
    unaligned_store_u64a(bits, val);
}

static really_inline
void mmb_store_partial(u8 *bits, MMB_TYPE val, u32 block_bits) {
    assert(block_bits <= MMB_KEY_BITS);
    partial_store_u64a(bits, val, ROUNDUP_N(block_bits, 8U) / 8U);
}

static really_inline
MMB_TYPE mmb_single_bit(u32 bit) {
    assert(bit < MMB_KEY_BITS);
    return MMB_ONE << bit;
}

static really_inline
MMB_TYPE mmb_mask_zero_to(u32 bit) {
    assert(bit <= MMB_KEY_BITS);
#ifdef ARCH_32_BIT
    return mmbit_zero_to_lut[bit];
#else
    if (bit == MMB_KEY_BITS) {
        return MMB_ALL_ONES;
    } else {
        return mmb_single_bit(bit) - MMB_ONE;
    }
#endif
}

/** \brief Returns a mask of set bits up to position \a bit. Does not handle
 * the case where bit == MMB_KEY_BITS. */
static really_inline
MMB_TYPE mmb_mask_zero_to_nocheck(u32 bit) {
    assert(bit < MMB_KEY_BITS);
#ifdef ARCH_32_BIT
    return mmbit_zero_to_lut[bit];
#else
    return mmb_single_bit(bit) - MMB_ONE;
#endif
}

static really_inline
u32 mmb_test(MMB_TYPE val, u32 bit) {
    assert(bit < MMB_KEY_BITS);
    return (val >> bit) & MMB_ONE;
}

static really_inline
void mmb_set(MMB_TYPE * val, u32 bit) {
    assert(bit < MMB_KEY_BITS);
    *val |= mmb_single_bit(bit);
}

static really_inline
void mmb_clear(MMB_TYPE * val, u32 bit) {
    assert(bit < MMB_KEY_BITS);
    *val &= ~mmb_single_bit(bit);
}

static really_inline
u32 mmb_ctz(MMB_TYPE val) {
    return ctz64(val);
}

static really_inline
u32 mmb_popcount(MMB_TYPE val) {
    return popcount64(val);
}

#ifndef MMMB_DEBUG
#define MDEBUG_PRINTF(x, ...) do { } while(0)
#else
#define MDEBUG_PRINTF DEBUG_PRINTF
#endif

// Switch the following define on to trace writes to multibit.
//#define MMB_TRACE_WRITES
#ifdef MMB_TRACE_WRITES
#define MMB_TRACE(format, ...)                                                 \
    printf("mmb [%u bits @ %p] " format, total_bits, bits, ##__VA_ARGS__)
#else
#define MMB_TRACE(format, ...)                                                 \
    do {                                                                       \
    } while (0)
#endif

static really_inline
u32 mmbit_keyshift(u32 total_bits) {
    assert(total_bits > 1);
    u32 n = clz32(total_bits - 1); // subtract one as we're rounding down
    return mmbit_keyshift_lut[n];
}

static really_inline
u32 mmbit_maxlevel(u32 total_bits) {
    assert(total_bits > 1);
    u32 n = clz32(total_bits - 1); // subtract one as we're rounding down
    u32 max_level = mmbit_maxlevel_direct_lut[n];
    assert(max_level <= MMB_MAX_LEVEL);
    return max_level;
}

static really_inline
u32 mmbit_maxlevel_from_keyshift(u32 ks) {
    assert(ks <= 30);
    assert(ks % MMB_KEY_SHIFT == 0);

    u32 max_level = mmbit_maxlevel_from_keyshift_lut[ks];
    assert(max_level <= MMB_MAX_LEVEL);
    return max_level;
}

/** \brief get our keyshift for the current level */
static really_inline
u32 mmbit_get_ks(u32 max_level, u32 level) {
    assert(max_level <= MMB_MAX_LEVEL);
    assert(level <= max_level);
    return (max_level - level) * MMB_KEY_SHIFT;
}

/** \brief get our key value for the current level */
static really_inline
u32 mmbit_get_key_val(u32 max_level, u32 level, u32 key) {
    return (key >> mmbit_get_ks(max_level, level)) & MMB_KEY_MASK;
}

/** \brief get the level root for the current level */
static really_inline
u8 *mmbit_get_level_root(u8 *bits, u32 level) {
    assert(level < ARRAY_LENGTH(mmbit_root_offset_from_level));
    return bits + mmbit_root_offset_from_level[level] * sizeof(MMB_TYPE);
}

/** \brief get the level root for the current level as const */
static really_inline
const u8 *mmbit_get_level_root_const(const u8 *bits, u32 level) {
    assert(level < ARRAY_LENGTH(mmbit_root_offset_from_level));
    return bits + mmbit_root_offset_from_level[level] * sizeof(MMB_TYPE);
}

/** \brief get the block for this key on the current level as a u8 ptr */
static really_inline
u8 *mmbit_get_block_ptr(u8 *bits, u32 max_level, u32 level, u32 key) {
    u8 *level_root = mmbit_get_level_root(bits, level);
    u32 ks = mmbit_get_ks(max_level, level);
    return level_root + ((u64a)key >> (ks + MMB_KEY_SHIFT)) * sizeof(MMB_TYPE);
}

/** \brief get the block for this key on the current level as a const u8 ptr */
static really_inline
const u8 *mmbit_get_block_ptr_const(const u8 *bits, u32 max_level, u32 level,
                                    u32 key) {
    const u8 *level_root = mmbit_get_level_root_const(bits, level);
    u32 ks = mmbit_get_ks(max_level, level);
    return level_root + ((u64a)key >> (ks + MMB_KEY_SHIFT)) * sizeof(MMB_TYPE);
}

/** \brief get the _byte_ for this key on the current level as a u8 ptr */
static really_inline
u8 *mmbit_get_byte_ptr(u8 *bits, u32 max_level, u32 level, u32 key) {
    u8 *level_root = mmbit_get_level_root(bits, level);
    u32 ks = mmbit_get_ks(max_level, level);
    return level_root + ((u64a)key >> (ks + MMB_KEY_SHIFT - 3));
}

/** \brief get our key value for the current level */
static really_inline
u32 mmbit_get_key_val_byte(u32 max_level, u32 level, u32 key) {
    return (key >> (mmbit_get_ks(max_level, level))) & 0x7;
}

/** \brief Load a flat bitvector block corresponding to N bits. */
static really_inline
MMB_TYPE mmbit_get_flat_block(const u8 *bits, u32 n_bits) {
    assert(n_bits <= MMB_KEY_BITS);
    u32 n_bytes = ROUNDUP_N(n_bits, 8) / 8;
    switch (n_bytes) {
    case 1:
        return *bits;
    case 2:
        return unaligned_load_u16(bits);
    case 3:
    case 4: {
        u32 rv;
        assert(n_bytes <= sizeof(rv));
        memcpy(&rv, bits + n_bytes - sizeof(rv), sizeof(rv));
        rv >>= (sizeof(rv) - n_bytes) * 8; /* need to shift to get things in
                                            * the right position and remove
                                            * junk */
        assert(rv == partial_load_u32(bits, n_bytes));
        return rv;
    }
    default: {
        u64a rv;
        assert(n_bytes <= sizeof(rv));
        memcpy(&rv, bits + n_bytes - sizeof(rv), sizeof(rv));
        rv >>= (sizeof(rv) - n_bytes) * 8; /* need to shift to get things in
                                            * the right position and remove
                                            * junk */
        assert(rv == partial_load_u64a(bits, n_bytes));
        return rv;
    }
    }
}

/** \brief True if this multibit is small enough to use a flat model */
static really_inline
u32 mmbit_is_flat_model(u32 total_bits) {
    return total_bits <= MMB_FLAT_MAX_BITS;
}

static really_inline
u32 mmbit_flat_size(u32 total_bits) {
    assert(mmbit_is_flat_model(total_bits));
    return ROUNDUP_N(total_bits, 8) / 8;
}

static really_inline
u32 mmbit_flat_select_byte(u32 key, UNUSED u32 total_bits) {
    return key / 8;
}

/** \brief returns the dense index of the bit in the given mask. */
static really_inline
u32 mmbit_mask_index(u32 bit, MMB_TYPE mask) {
    assert(bit < MMB_KEY_BITS);
    assert(mmb_test(mask, bit));

    mask &= mmb_mask_zero_to(bit);
    if (mask == 0ULL) {
        return 0; // Common case.
    }
    return mmb_popcount(mask);
}

/** \brief Clear all bits. */
static really_inline
void mmbit_clear(u8 *bits, u32 total_bits) {
    MDEBUG_PRINTF("%p total_bits %u\n", bits, total_bits);
    MMB_TRACE("CLEAR\n");
    if (!total_bits) {
        return;
    }
    if (mmbit_is_flat_model(total_bits)) {
        memset(bits, 0, mmbit_flat_size(total_bits));
        return;
    }
    mmb_store(bits, 0);
}

/** \brief Specialisation of \ref mmbit_set for flat models. */
static really_inline
char mmbit_set_flat(u8 *bits, u32 total_bits, u32 key) {
    bits += mmbit_flat_select_byte(key, total_bits);
    u8 mask = 1U << (key % 8);
    char was_set = !!(*bits & mask);
    *bits |= mask;
    return was_set;
}

static really_inline
char mmbit_set_big(u8 *bits, u32 total_bits, u32 key) {
    const u32 max_level = mmbit_maxlevel(total_bits);
    u32 level = 0;
    do {
        u8 * byte_ptr = mmbit_get_byte_ptr(bits, max_level, level, key);
        u8 keymask = 1U << mmbit_get_key_val_byte(max_level, level, key);
        u8 byte = *byte_ptr;
        if (likely(!(byte & keymask))) {
            *byte_ptr = byte | keymask;
            while (level++ != max_level) {
                u8 *block_ptr_1 = mmbit_get_block_ptr(bits, max_level, level, key);
                MMB_TYPE keymask_1 = mmb_single_bit(mmbit_get_key_val(max_level, level, key));
                mmb_store(block_ptr_1, keymask_1);
            }
            return 0;
        }
    } while (level++ != max_level);
    return 1;
}

/** Internal version of \ref mmbit_set without MMB_TRACE, so it can be used by
 * \ref mmbit_sparse_iter_dump. */
static really_inline
char mmbit_set_i(u8 *bits, u32 total_bits, u32 key) {
    assert(key < total_bits);
    if (mmbit_is_flat_model(total_bits)) {
        return mmbit_set_flat(bits, total_bits, key);
    } else {
        return mmbit_set_big(bits, total_bits, key);
    }
}

static really_inline
char mmbit_isset(const u8 *bits, u32 total_bits, u32 key);

/** \brief Sets the given key in the multibit. Returns 0 if the key was NOT
 * already set, 1 otherwise. */
static really_inline
char mmbit_set(u8 *bits, u32 total_bits, u32 key) {
    MDEBUG_PRINTF("%p total_bits %u key %u\n", bits, total_bits, key);
    char status = mmbit_set_i(bits, total_bits, key);
    MMB_TRACE("SET %u (prev status: %d)\n", key, (int)status);
    assert(mmbit_isset(bits, total_bits, key));
    return status;
}

/** \brief Specialisation of \ref mmbit_isset for flat models. */
static really_inline
char mmbit_isset_flat(const u8 *bits, u32 total_bits, u32 key) {
    bits += mmbit_flat_select_byte(key, total_bits);
    return !!(*bits & (1U << (key % 8U)));
}

static really_inline
char mmbit_isset_big(const u8 *bits, u32 total_bits, u32 key) {
    const u32 max_level = mmbit_maxlevel(total_bits);
    u32 level = 0;
    do {
        const u8 *block_ptr = mmbit_get_block_ptr_const(bits, max_level, level, key);
        MMB_TYPE block = mmb_load(block_ptr);
        if (!mmb_test(block, mmbit_get_key_val(max_level, level, key))) {
            return 0;
        }
    } while (level++ != max_level);
    return 1;
}

/** \brief Returns whether the given key is set. */
static really_inline
char mmbit_isset(const u8 *bits, u32 total_bits, u32 key) {
    MDEBUG_PRINTF("%p total_bits %u key %u\n", bits, total_bits, key);
    assert(key < total_bits);
    if (mmbit_is_flat_model(total_bits)) {
        return mmbit_isset_flat(bits, total_bits, key);
    } else {
        return mmbit_isset_big(bits, total_bits, key);
    }
}

/** \brief Specialisation of \ref mmbit_unset for flat models. */
static really_inline
void mmbit_unset_flat(u8 *bits, u32 total_bits, u32 key) {
    bits += mmbit_flat_select_byte(key, total_bits);
    *bits &= ~(1U << (key % 8U));
}

// TODO:
// build two versions of this - unset_dangerous that doesn't clear the summary
// block and a regular unset that actually clears ALL the way up the levels if
// possible - might make a utility function for the clear
static really_inline
void mmbit_unset_big(u8 *bits, u32 total_bits, u32 key) {
    /* This function is lazy as it does not clear the summary block
     * entry if the child becomes empty. This is not a correctness problem as the
     * summary block entries are used to mean that their children are valid
     * rather than that they have a set child. */
    const u32 max_level = mmbit_maxlevel(total_bits);
    u32 level = 0;
    do {
        u8 *block_ptr = mmbit_get_block_ptr(bits, max_level, level, key);
        u32 key_val = mmbit_get_key_val(max_level, level, key);
        MMB_TYPE block = mmb_load(block_ptr);
        if (!mmb_test(block, key_val)) {
            return;
        }
        if (level == max_level) {
            mmb_clear(&block, key_val);
            mmb_store(block_ptr, block);
        }
    } while (level++ != max_level);
}

/** \brief Switch off a given key. */
static really_inline
void mmbit_unset(u8 *bits, u32 total_bits, u32 key) {
    MDEBUG_PRINTF("%p total_bits %u key %u\n", bits, total_bits, key);
    assert(key < total_bits);
    MMB_TRACE("UNSET %u (prev status: %d)\n", key,
              (int)mmbit_isset(bits, total_bits, key));

    if (mmbit_is_flat_model(total_bits)) {
        mmbit_unset_flat(bits, total_bits, key);
    } else {
        mmbit_unset_big(bits, total_bits, key);
    }
}

/** \brief Specialisation of \ref mmbit_iterate for flat models. */
static really_inline
u32 mmbit_iterate_flat(const u8 *bits, u32 total_bits, u32 it_in) {
    // Short cut for single-block cases.
    if (total_bits <= MMB_KEY_BITS) {
        MMB_TYPE block = mmbit_get_flat_block(bits, total_bits);
        if (it_in != MMB_INVALID) {
            it_in++;
            assert(it_in < total_bits);
            block &= ~mmb_mask_zero_to(it_in);
        }
        if (block) {
            return mmb_ctz(block);
        }
        return MMB_INVALID;
    }

    const u32 last_block = total_bits / MMB_KEY_BITS;
    u32 start; // starting block index

    if (it_in != MMB_INVALID) {
        it_in++;
        assert(it_in < total_bits);

        start = (ROUNDUP_N(it_in, MMB_KEY_BITS) / MMB_KEY_BITS) - 1;
        u32 start_key = start * MMB_KEY_BITS;
        u32 block_size = MIN(MMB_KEY_BITS, total_bits - start_key);
        MMB_TYPE block =
            mmbit_get_flat_block(bits + (start * sizeof(MMB_TYPE)), block_size);
        block &= ~mmb_mask_zero_to(it_in - start_key);

        if (block) {
            return start_key + mmb_ctz(block);
        } else if (start_key + MMB_KEY_BITS >= total_bits) {
            return MMB_INVALID; // That was the final block.
        }
        start++;
    } else {
        start = 0;
    }

    // Remaining full-sized blocks.
    for (; start < last_block; start++) {
        MMB_TYPE block = mmb_load(bits + (start * sizeof(MMB_TYPE)));
        if (block) {
            return (start * MMB_KEY_BITS) + mmb_ctz(block);
        }
    }

    // We may have a final, smaller than full-sized, block to deal with at the
    // end.
    if (total_bits % MMB_KEY_BITS) {
        u32 start_key = start * MMB_KEY_BITS;
        u32 block_size = MIN(MMB_KEY_BITS, total_bits - start_key);
        MMB_TYPE block =
            mmbit_get_flat_block(bits + (start * sizeof(MMB_TYPE)), block_size);
        if (block) {
            return start_key + mmb_ctz(block);
        }
    }

    return MMB_INVALID;
}

static really_inline
u32 mmbit_iterate_big(const u8 * bits, u32 total_bits, u32 it_in) {
    const u32 max_level = mmbit_maxlevel(total_bits);
    u32 level = 0;
    u32 key = 0;
    u32 key_rem = 0;

    if (it_in != MMB_INVALID) {
        // We're continuing a previous iteration, so we need to go
        // to max_level so we can pick up where we left off.
        // NOTE: assumes that we're valid down the whole tree
        key = it_in >> MMB_KEY_SHIFT;
        key_rem = (it_in & MMB_KEY_MASK) + 1;
        level = max_level;
    }
    while (1) {
        if (key_rem < MMB_KEY_BITS) {
            const u8 *block_ptr = mmbit_get_level_root_const(bits, level) +
                                  key * sizeof(MMB_TYPE);
            MMB_TYPE block
                = mmb_load(block_ptr) & ~mmb_mask_zero_to_nocheck(key_rem);
            if (block) {
                key = (key << MMB_KEY_SHIFT) + mmb_ctz(block);
                if (level++ == max_level) {
                    break;
                }
                key_rem = 0;
                continue; // jump the rootwards step if we found a 'tree' non-zero bit
            }
        }
        // rootwards step (block is zero or key_rem == MMB_KEY_BITS)
        if (level-- == 0) {
            return MMB_INVALID; // if we don't find anything and we're at the top level, we're done
        }
        key_rem = (key & MMB_KEY_MASK) + 1;
        key >>= MMB_KEY_SHIFT;
    }
    assert(key < total_bits);
    assert(mmbit_isset(bits, total_bits, key));
    return key;
}

/** \brief Unbounded iterator. Returns the index of the next set bit after \a
 * it_in, or MMB_INVALID.
 *
 * Note: assumes that if you pass in a value of it_in other than MMB_INVALID,
 * that bit must be on (assumes all its summary blocks are set).
 */
static really_inline
u32 mmbit_iterate(const u8 *bits, u32 total_bits, u32 it_in) {
    MDEBUG_PRINTF("%p total_bits %u it_in %u\n", bits, total_bits, it_in);
    assert(it_in < total_bits || it_in == MMB_INVALID);
    if (!total_bits) {
        return MMB_INVALID;
    }
    if (it_in == total_bits - 1) {
        return MMB_INVALID; // it_in is the last key.
    }

    u32 key;
    if (mmbit_is_flat_model(total_bits)) {
        key = mmbit_iterate_flat(bits, total_bits, it_in);
    } else {
        key = mmbit_iterate_big(bits, total_bits, it_in);
    }
    assert(key == MMB_INVALID || mmbit_isset(bits, total_bits, key));
    return key;
}

/** \brief Specialisation of \ref mmbit_any and \ref mmbit_any_precise for flat
 * models. */
static really_inline
char mmbit_any_flat(const u8 *bits, u32 total_bits) {
    if (total_bits <= MMB_KEY_BITS) {
        return !!mmbit_get_flat_block(bits, total_bits);
    }

    const u8 *end = bits + mmbit_flat_size(total_bits);
    for (const u8 *last = end - sizeof(MMB_TYPE); bits < last;
         bits += sizeof(MMB_TYPE)) {
        if (mmb_load(bits)) {
            return 1;
        }
    }

    // Overlapping load at the end.
    return !!mmb_load(end - sizeof(MMB_TYPE));
}

/** \brief True if any keys are (or might be) on in the given multibit.
 *
 * NOTE: mmbit_any is sloppy (may return true when only summary bits are set).
 * Use \ref mmbit_any_precise if you need/want a correct answer.
 */
static really_inline
char mmbit_any(const u8 *bits, u32 total_bits) {
    MDEBUG_PRINTF("%p total_bits %u\n", bits, total_bits);
    if (!total_bits) {
        return 0;
    }
    if (mmbit_is_flat_model(total_bits)) {
        return mmbit_any_flat(bits, total_bits);
    }
    return !!mmb_load(bits);
}

/** \brief True if there are any keys on. Guaranteed precise. */
static really_inline
char mmbit_any_precise(const u8 *bits, u32 total_bits) {
    MDEBUG_PRINTF("%p total_bits %u\n", bits, total_bits);
    if (!total_bits) {
        return 0;
    }
    if (mmbit_is_flat_model(total_bits)) {
        return mmbit_any_flat(bits, total_bits);
    }

    return mmbit_iterate_big(bits, total_bits, MMB_INVALID) != MMB_INVALID;
}

static really_inline
char mmbit_all_flat(const u8 *bits, u32 total_bits) {
    while (total_bits > MMB_KEY_BITS) {
        if (mmb_load(bits) != MMB_ALL_ONES) {
            return 0;
        }
        bits += sizeof(MMB_TYPE);
        total_bits -= MMB_KEY_BITS;
    }
    while (total_bits > 8) {
        if (*bits != 0xff) {
            return 0;
        }
        bits++;
        total_bits -= 8;
    }
    u8 mask = (u8)mmb_mask_zero_to_nocheck(total_bits);
    return (*bits & mask) == mask;
}

static really_inline
char mmbit_all_big(const u8 *bits, u32 total_bits) {
    u32 ks = mmbit_keyshift(total_bits);

    u32 level = 0;
    for (;;) {
        // Number of bits we expect to see switched on on this level.
        u32 level_bits;
        if (ks != 0) {
            u32 next_level_width = MMB_KEY_BITS << (ks - MMB_KEY_SHIFT);
            level_bits = ROUNDUP_N(total_bits, next_level_width) >> ks;
        } else {
            level_bits = total_bits;
        }

        const u8 *block_ptr = mmbit_get_level_root_const(bits, level);

        // All full-size blocks should be all-ones.
        while (level_bits >= MMB_KEY_BITS) {
            MMB_TYPE block = mmb_load(block_ptr);
            if (block != MMB_ALL_ONES) {
                return 0;
            }
            block_ptr += sizeof(MMB_TYPE);
            level_bits -= MMB_KEY_BITS;
        }

        // If we have bits remaining, we have a runt block on the end.
        if (level_bits > 0) {
            MMB_TYPE block = mmb_load(block_ptr);
            MMB_TYPE mask = mmb_mask_zero_to_nocheck(level_bits);
            if ((block & mask) != mask) {
                return 0;
            }
        }

        if (ks == 0) {
            break;
        }

        ks -= MMB_KEY_SHIFT;
        level++;
    }

    return 1;
}

/** \brief True if all keys are on. Guaranteed precise. */
static really_inline
char mmbit_all(const u8 *bits, u32 total_bits) {
    MDEBUG_PRINTF("%p total_bits %u\n", bits, total_bits);

    if (mmbit_is_flat_model(total_bits)) {
        return mmbit_all_flat(bits, total_bits);
    }
    return mmbit_all_big(bits, total_bits);
}

static really_inline
MMB_TYPE get_flat_masks(u32 base, u32 it_start, u32 it_end) {
    if (it_end <= base) {
        return 0;
    }
    u32 udiff = it_end - base;
    MMB_TYPE mask = udiff < 64 ? mmb_mask_zero_to_nocheck(udiff) : MMB_ALL_ONES;
    if (it_start >= base) {
        u32 ldiff = it_start - base;
        MMB_TYPE lmask = ldiff < 64 ? ~mmb_mask_zero_to_nocheck(ldiff) : 0;
        mask &= lmask;
    }
    return mask;
}

/** \brief Specialisation of \ref mmbit_iterate_bounded for flat models. */
static really_inline
u32 mmbit_iterate_bounded_flat(const u8 *bits, u32 total_bits, u32 begin,
                               u32 end) {
    // Short cut for single-block cases.
    if (total_bits <= MMB_KEY_BITS) {
        MMB_TYPE block = mmbit_get_flat_block(bits, total_bits);
        block &= get_flat_masks(0, begin, end);
        if (block) {
            return mmb_ctz(block);
        }
        return MMB_INVALID;
    }

    const u32 last_block = ROUNDDOWN_N(total_bits, MMB_KEY_BITS);

    // Iterate over full-sized blocks.
    for (u32 i = ROUNDDOWN_N(begin, MMB_KEY_BITS), e = MIN(end, last_block);
         i < e; i += MMB_KEY_BITS) {
        const u8 *block_ptr = bits + i / 8;
        MMB_TYPE block = mmb_load(block_ptr);
        block &= get_flat_masks(i, begin, end);
        if (block) {
            return i + mmb_ctz(block);
        }
    }

    // Final block, which is less than full-sized.
    if (end > last_block) {
        const u8 *block_ptr = bits + last_block / 8;
        u32 num_bits = total_bits - last_block;
        MMB_TYPE block = mmbit_get_flat_block(block_ptr, num_bits);
        block &= get_flat_masks(last_block, begin, end);
        if (block) {
            return last_block + mmb_ctz(block);
        }
    }

    return MMB_INVALID;
}

static really_inline
MMB_TYPE get_lowhi_masks(u32 level, u32 max_level, u64a block_min, u64a block_max,
                         u64a block_base) {
    const u32 level_shift = (max_level - level) * MMB_KEY_SHIFT;
    u64a lshift = (block_min - block_base) >> level_shift;
    u64a ushift = (block_max - block_base) >> level_shift;
    MMB_TYPE lmask = lshift < 64 ? ~mmb_mask_zero_to_nocheck(lshift) : 0;
    MMB_TYPE umask =
        ushift < 63 ? mmb_mask_zero_to_nocheck(ushift + 1) : MMB_ALL_ONES;
    return lmask & umask;
}

static really_inline
u32 mmbit_iterate_bounded_big(const u8 *bits, u32 total_bits, u32 it_start, u32 it_end) {
    u64a key = 0;
    u32 ks = mmbit_keyshift(total_bits);
    const u32 max_level = mmbit_maxlevel_from_keyshift(ks);
    u32 level = 0;
    --it_end; // make end-limit inclusive
    for (;;) {
        assert(level <= max_level);

        u64a block_width = MMB_KEY_BITS << ks;
        u64a block_base = key * block_width;
        u64a block_min = MAX(it_start, block_base);
        u64a block_max = MIN(it_end, block_base + block_width - 1);
        const u8 *block_ptr =
            mmbit_get_level_root_const(bits, level) + key * sizeof(MMB_TYPE);
        MMB_TYPE block = mmb_load(block_ptr);
        block &= get_lowhi_masks(level, max_level, block_min, block_max, block_base);
        if (block) {
            // Found a bit, go down a level
            key = (key << MMB_KEY_SHIFT) + mmb_ctz(block);
            if (level++ == max_level) {
                return key;
            }
            ks -= MMB_KEY_SHIFT;
        } else {
            // No bit found, go up a level
            // we know that this block didn't have any answers, so we can push
            // our start iterator forward.
            u64a next_start = block_base + block_width;
            if (next_start > it_end) {
                break;
            }
            if (level-- == 0) {
                break;
            }
            it_start = next_start;
            key >>= MMB_KEY_SHIFT;
            ks += MMB_KEY_SHIFT;
        }
    }
    return MMB_INVALID;
}

/** \brief Bounded iterator. Returns the index of the first set bit between
 * it_start (inclusive) and it_end (exclusive) or MMB_INVALID if no bits are
 * set in that range.
 */
static really_inline
u32 mmbit_iterate_bounded(const u8 *bits, u32 total_bits, u32 it_start,
                          u32 it_end) {
    MDEBUG_PRINTF("%p total_bits %u it_start %u it_end %u\n", bits, total_bits,
                  it_start, it_end);
    assert(it_start <= it_end);
    assert(it_end <= total_bits);
    if (!total_bits || it_end == it_start) {
        return MMB_INVALID;
    }
    assert(it_start < total_bits);
    u32 key;
    if (mmbit_is_flat_model(total_bits)) {
        key = mmbit_iterate_bounded_flat(bits, total_bits, it_start, it_end);
    } else {
        key = mmbit_iterate_bounded_big(bits, total_bits, it_start, it_end);
    }
    assert(key == MMB_INVALID || mmbit_isset(bits, total_bits, key));
    return key;
}

/** \brief Specialisation of \ref mmbit_unset_range for flat models. */
static really_inline
void mmbit_unset_range_flat(u8 *bits, u32 total_bits, u32 begin, u32 end) {
    const u32 last_block = ROUNDDOWN_N(total_bits, MMB_KEY_BITS);

    // Iterate over full-sized blocks.
    for (u32 i = ROUNDDOWN_N(begin, MMB_KEY_BITS), e = MIN(end, last_block);
         i < e; i += MMB_KEY_BITS) {
        u8 *block_ptr = bits + i / 8;
        MMB_TYPE block = mmb_load(block_ptr);
        MMB_TYPE mask = get_flat_masks(i, begin, end);
        mmb_store(block_ptr, block & ~mask);
    }

    // Final block, which is less than full-sized.
    if (end > last_block) {
        u8 *block_ptr = bits + last_block / 8;
        u32 num_bits = total_bits - last_block;
        MMB_TYPE block = mmbit_get_flat_block(block_ptr, num_bits);
        MMB_TYPE mask = get_flat_masks(last_block, begin, end);
        mmb_store_partial(block_ptr, block & ~mask, num_bits);
    }
}

static really_inline
void mmbit_unset_range_big(u8 *bits, const u32 total_bits, u32 begin,
                           u32 end) {
    // TODO: combine iterator and unset operation; completely replace this
    u32 i = begin;
    for (;;) {
        i = mmbit_iterate_bounded(bits, total_bits, i, end);
        if (i == MMB_INVALID) {
            break;
        }
        mmbit_unset_big(bits, total_bits, i);
        if (++i == end) {
            break;
        }
    }
}

/** \brief Unset a whole range of bits. Ensures that all bits between \a begin
 * (inclusive) and \a end (exclusive) are switched off.  */
static really_inline
void mmbit_unset_range(u8 *bits, const u32 total_bits, u32 begin, u32 end) {
    MDEBUG_PRINTF("%p total_bits %u begin %u end %u\n", bits, total_bits, begin,
                  end);
    assert(begin <= end);
    assert(end <= total_bits);
    if (mmbit_is_flat_model(total_bits)) {
        mmbit_unset_range_flat(bits, total_bits, begin, end);
    } else {
        mmbit_unset_range_big(bits, total_bits, begin, end);
    }
    // No bits are on in [begin, end) once we're done.
    assert(MMB_INVALID == mmbit_iterate_bounded(bits, total_bits, begin, end));
}

/** \brief Specialisation of \ref mmbit_init_range for flat models. */
static really_inline
void mmbit_init_range_flat(u8 *bits, const u32 total_bits, u32 begin, u32 end) {
    const u32 last_block = ROUNDDOWN_N(total_bits, MMB_KEY_BITS);

    // Iterate over full-sized blocks.
    for (u32 i = 0; i < last_block; i += MMB_KEY_BITS) {
        mmb_store(bits + i / 8, get_flat_masks(i, begin, end));
    }

    // Final block, which is less than full-sized.
    if (total_bits % MMB_KEY_BITS) {
        u32 num_bits = total_bits - last_block;
        MMB_TYPE block = get_flat_masks(last_block, begin, end);
        mmb_store_partial(bits + last_block / 8, block, num_bits);
    }
}

static really_inline
void mmbit_init_range_big(u8 *bits, const u32 total_bits, u32 begin, u32 end) {
    u32 ks = mmbit_keyshift(total_bits);
    u32 level = 0;

    for (;;) {
        u8 *block = mmbit_get_level_root(bits, level);
        u32 k1 = begin >> ks, k2 = end >> ks;

        // Summary blocks need to account for the runt block on the end.
        if ((k2 << ks) != end) {
            k2++;
        }

        // Partial block to deal with beginning.
        block += (k1 / MMB_KEY_BITS) * sizeof(MMB_TYPE);
        if (k1 % MMB_KEY_BITS) {
            u32 idx = k1 / MMB_KEY_BITS;
            u32 block_end = (idx + 1) * MMB_KEY_BITS;

            // Because k1 % MMB_KEY_BITS != 0, we can avoid checking edge cases
            // here (see the branch in mmb_mask_zero_to).
            MMB_TYPE mask = MMB_ALL_ONES << (k1 % MMB_KEY_BITS);

            if (k2 < block_end) {
                assert(k2 % MMB_KEY_BITS);
                mask &= mmb_mask_zero_to_nocheck(k2 % MMB_KEY_BITS);
                mmb_store(block, mask);
                goto next_level;
            } else {
                mmb_store(block, mask);
                k1 = block_end;
                block += sizeof(MMB_TYPE);
            }
        }

        // Write blocks filled with ones until we get to the last block.
        for (; k1 < (k2 & ~MMB_KEY_MASK); k1 += MMB_KEY_BITS) {
            mmb_store(block, MMB_ALL_ONES);
            block += sizeof(MMB_TYPE);
        }

        // Final block.
        if (likely(k1 < k2)) {
            // Again, if k2 was at a block boundary, it would have been handled
            // by the previous loop, so we know k2 % MMB_KEY_BITS != 0 and can
            // avoid the branch in mmb_mask_zero_to here.
            assert(k2 % MMB_KEY_BITS);
            MMB_TYPE mask = mmb_mask_zero_to_nocheck(k2 % MMB_KEY_BITS);
            mmb_store(block, mask);
        }

    next_level:
        if (ks == 0) {
            break; // Last level is done, finished.
        }

        ks -= MMB_KEY_SHIFT;
        level++;
    }
}

/** \brief Initialises the multibit so that only the given range of bits are
 * set.
 *
 * Ensures that all bits between \a begin (inclusive) and \a end (exclusive)
 * are switched on.
 */
static really_inline
void mmbit_init_range(u8 *bits, const u32 total_bits, u32 begin, u32 end) {
    MDEBUG_PRINTF("%p total_bits %u begin %u end %u\n", bits, total_bits, begin,
                  end);
    assert(begin <= end);
    assert(end <= total_bits);

    if (!total_bits) {
        return;
    }

    // Short cut for cases where we're not actually setting any bits; just
    // clear the multibit.
    if (begin == end) {
        mmbit_clear(bits, total_bits);
        return;
    }

    if (mmbit_is_flat_model(total_bits)) {
        mmbit_init_range_flat(bits, total_bits, begin, end);
    } else {
        mmbit_init_range_big(bits, total_bits, begin, end);
    }

    assert(begin == end ||
           mmbit_iterate(bits, total_bits, MMB_INVALID) == begin);
    assert(!end || begin == end ||
           mmbit_iterate(bits, total_bits, end - 1) == MMB_INVALID);
}

/** \brief Determine the number of \ref mmbit_sparse_state elements required.
 * */
static really_inline
u32 mmbit_sparse_iter_state_size(u32 total_bits) {
    if (mmbit_is_flat_model(total_bits)) {
        return 2;
    }
    u32 levels = mmbit_maxlevel(total_bits);
    return levels + 1;
}

#ifdef DUMP_SUPPORT
// Dump function, defined in multibit.c.
void mmbit_sparse_iter_dump(const struct mmbit_sparse_iter *it, u32 total_bits);
#endif

/** Internal: common loop used by mmbit_sparse_iter_{begin,next}_big. Returns
 * matching next key given starting state, or MMB_INVALID. */
static really_inline
u32 mmbit_sparse_iter_exec(const u8 *bits, u32 key, u32 *idx, u32 level,
                           const u32 max_level, struct mmbit_sparse_state *s,
                           const struct mmbit_sparse_iter *it_root,
                           const struct mmbit_sparse_iter *it) {
    for (;;) {
        MMB_TYPE block = s[level].mask;
        if (block) {
            u32 bit = mmb_ctz(block);
            key = (key << MMB_KEY_SHIFT) + bit;
            u32 bit_idx = mmbit_mask_index(bit, it->mask);
            if (level++ == max_level) {
                // we've found a key
                *idx = it->val + bit_idx;
                return key;
            } else {
                // iterator record is the start of the level (current it->val)
                // plus N, where N is the dense index of the bit in the current
                // level's itmask
                u32 iter_key = it->val + bit_idx;
                it = it_root + iter_key;
                MMB_TYPE nextblock =
                    mmb_load(mmbit_get_level_root_const(bits, level) +
                             key * sizeof(MMB_TYPE));
                s[level].mask = nextblock & it->mask;
                s[level].itkey = iter_key;
            }
        } else {
            // No bits set in this block
            if (level-- == 0) {
                break; // no key available
            }
            key >>= MMB_KEY_SHIFT;
            // Update state mask and iterator
            s[level].mask &= (s[level].mask - 1);
            it = it_root + s[level].itkey;
        }
    }
    return MMB_INVALID;
}

static really_inline
u32 mmbit_sparse_iter_begin_big(const u8 *bits, u32 total_bits, u32 *idx,
                                const struct mmbit_sparse_iter *it_root,
                                struct mmbit_sparse_state *s) {
    const struct mmbit_sparse_iter *it = it_root;
    u32 key = 0;
    MMB_TYPE block = mmb_load(bits) & it->mask;
    if (!block) {
        return MMB_INVALID;
    }

    // Load first block into top level state.
    const u32 max_level = mmbit_maxlevel(total_bits);
    s[0].mask = block;
    s[0].itkey = 0;
    return mmbit_sparse_iter_exec(bits, key, idx, 0, max_level,
                                  s, it_root, it);
}

/** \brief Specialisation of \ref mmbit_sparse_iter_begin for flat models. */
static really_inline
u32 mmbit_sparse_iter_begin_flat(const u8 *bits, u32 total_bits, u32 *idx,
                                 const struct mmbit_sparse_iter *it_root,
                                 struct mmbit_sparse_state *s) {
    // Small cases have everything in the root iterator mask.
    if (total_bits <= MMB_KEY_BITS) {
        MMB_TYPE block = mmbit_get_flat_block(bits, total_bits);
        block &= it_root->mask;
        if (!block) {
            return MMB_INVALID;
        }

        s->mask = block;
        u32 key = mmb_ctz(block);
        *idx = mmbit_mask_index(key, it_root->mask);
        return key;
    }

    // Otherwise, the root iterator mask tells us which blocks (which we lay out
    // linearly in the flat model) could contain keys.
    assert(mmbit_maxlevel(total_bits) == 1); // Should only be two levels
    MMB_TYPE root = it_root->mask;
    for (; root; root &= (root - 1)) {
        u32 bit = mmb_ctz(root);
        u32 bit_idx = mmbit_mask_index(bit, it_root->mask);
        u32 iter_key = it_root->val + bit_idx;
        const struct mmbit_sparse_iter *it = it_root + iter_key;
        u32 block_key_min = bit * MMB_KEY_BITS;
        u32 block_key_max = block_key_min + MMB_KEY_BITS;
        MMB_TYPE block;
        if (block_key_max > total_bits) {
            block_key_max = total_bits;
            block = mmbit_get_flat_block(bits + (bit * sizeof(MMB_TYPE)),
                                          block_key_max - block_key_min);
        } else {
            block = mmb_load(bits + (bit * sizeof(MMB_TYPE)));
        }

        block &= it->mask;
        if (block) {
            s[0].mask = root;
            s[1].mask = block;
            s[1].itkey = iter_key;
            u32 key = mmb_ctz(block);
            *idx = it->val + mmbit_mask_index(key, it->mask);
            return key + block_key_min;
        }
    }

    return MMB_INVALID;
}

/** \brief Sparse iterator, find first key.
 *
 * Returns the first of the bits specified by the iterator \a it_root that is
 * on, and initialises the state \a s. If none of the bits specified by the
 * iterator are on, returns MMB_INVALID.
 */
static really_inline
u32 mmbit_sparse_iter_begin(const u8 *bits, u32 total_bits, u32 *idx,
                            const struct mmbit_sparse_iter *it_root,
                            struct mmbit_sparse_state *s) {
    assert(ISALIGNED_N(it_root, alignof(struct mmbit_sparse_iter)));

    // Our state _may_ be on the stack
#ifndef _WIN32
    assert(ISALIGNED_N(s, alignof(struct mmbit_sparse_state)));
#else
    assert(ISALIGNED_N(s, 4));
#endif

    MDEBUG_PRINTF("%p total_bits %u\n", bits, total_bits);
    // iterator should have _something_ at the root level
    assert(it_root->mask != 0);
    u32 key;
    if (mmbit_is_flat_model(total_bits)) {
        key = mmbit_sparse_iter_begin_flat(bits, total_bits, idx, it_root, s);
    } else {
        key = mmbit_sparse_iter_begin_big(bits, total_bits, idx, it_root, s);
    }
    if (key != MMB_INVALID) {
        assert(key < total_bits);
        assert(mmbit_isset(bits, total_bits, key));
    }
    return key;
}

static really_inline
u32 mmbit_sparse_iter_next_big(const u8 *bits, u32 total_bits, u32 last_key,
                               u32 *idx,
                               const struct mmbit_sparse_iter *it_root,
                               struct mmbit_sparse_state *s) {
    const u32 max_level = mmbit_maxlevel(total_bits);
    u32 key = last_key >> MMB_KEY_SHIFT;
    s[max_level].mask &= (s[max_level].mask - 1);
    const struct mmbit_sparse_iter *it = it_root + s[max_level].itkey;
    return mmbit_sparse_iter_exec(bits, key, idx, max_level, max_level, s,
                                  it_root, it);
}

/** \brief Specialisation of \ref mmbit_sparse_iter_next for flat models. */
static really_inline
u32 mmbit_sparse_iter_next_flat(const u8 *bits, const u32 total_bits, u32 *idx,
                                const struct mmbit_sparse_iter *it_root,
                                struct mmbit_sparse_state *s) {
    if (total_bits <= MMB_KEY_BITS) {
        // All of our data is already in the s->mask, so we just need to scrape
        // off the next match.
        s->mask &= (s->mask - 1);
        if (s->mask) {
            u32 key = mmb_ctz(s->mask);
            *idx = mmbit_mask_index(key, it_root->mask);
            return key;
        }
    } else {
        assert(s[0].mask);

        s[1].mask &= (s[1].mask - 1); // Remove previous key from iter state.
        u32 bit = mmb_ctz(s[0].mask); // Flat block currently being accessed.

        for (;;) {
            if (s[1].mask) {
                u32 key = mmb_ctz(s[1].mask);
                const struct mmbit_sparse_iter *it = it_root + s[1].itkey;
                *idx = it->val + mmbit_mask_index(key, it->mask);
                key += (bit * MMB_KEY_BITS);
                return key;
            }

            // Otherwise, we have no keys left in this block. Consult the root
            // mask and find the next one.

            s[0].mask &= s[0].mask - 1;
            if (!s[0].mask) {
                break;
            }

            bit = mmb_ctz(s[0].mask);
            u32 bit_idx = mmbit_mask_index(bit, it_root->mask);
            u32 iter_key = it_root->val + bit_idx;
            const struct mmbit_sparse_iter *it = it_root + iter_key;
            u32 block_key_min = bit * MMB_KEY_BITS;
            u32 block_key_max = block_key_min + MMB_KEY_BITS;
            MMB_TYPE block;
            if (block_key_max > total_bits) {
                block_key_max = total_bits;
                block = mmbit_get_flat_block(bits + (bit * sizeof(MMB_TYPE)),
                                              block_key_max - block_key_min);
            } else {
                block = mmb_load(bits + (bit * sizeof(MMB_TYPE)));
            }

            s[1].mask = block & it->mask;
            s[1].itkey = iter_key;
        }
    }

    return MMB_INVALID;
}

/** \brief Sparse iterator, find next key.
 *
 * Takes in a sparse iterator tree structure \a it_root and a state array, and
 * finds the next on bit (from the set of bits specified in the iterator).
 *
 * NOTE: The sparse iterator stores copies of the multibit blocks in its state,
 * so it is not necessarily safe to set or unset bits in the multibit while
 * iterating: the changes you make may or may not be taken into account
 * by the iterator.
 */
static really_inline
u32 mmbit_sparse_iter_next(const u8 *bits, u32 total_bits, u32 last_key,
                           u32 *idx, const struct mmbit_sparse_iter *it_root,
                           struct mmbit_sparse_state *s) {
    assert(ISALIGNED_N(it_root, alignof(struct mmbit_sparse_iter)));

    // Our state _may_ be on the stack
#ifndef _WIN32
    assert(ISALIGNED_N(s, alignof(struct mmbit_sparse_state)));
#else
    assert(ISALIGNED_N(s, 4));
#endif

    MDEBUG_PRINTF("%p total_bits %u\n", bits, total_bits);
    MDEBUG_PRINTF("NEXT (total_bits=%u, last_key=%u)\n", total_bits, last_key);
    UNUSED u32 last_idx = *idx; // for assertion at the end
    // our iterator should have _something_ at the root level
    assert(it_root->mask != 0);
    assert(last_key < total_bits);

    u32 key;
    if (mmbit_is_flat_model(total_bits)) {
        key = mmbit_sparse_iter_next_flat(bits, total_bits, idx, it_root, s);
    } else {
        key = mmbit_sparse_iter_next_big(bits, total_bits, last_key, idx,
                                         it_root, s);
    }
    if (key != MMB_INVALID) {
        MDEBUG_PRINTF("END NEXT: key=%u, idx=%u\n", key, *idx);
        assert(key < total_bits);
        assert(key > last_key);
        assert(mmbit_isset(bits, total_bits, key));
        assert(*idx > last_idx);
    } else {
        MDEBUG_PRINTF("END NEXT: no more keys\n");
    }
    return key;
}

/** \brief Specialisation of \ref mmbit_sparse_iter_unset for flat models. */
static really_inline
void mmbit_sparse_iter_unset_flat(u8 *bits, u32 total_bits,
                                  const struct mmbit_sparse_iter *it_root) {
    if (total_bits <= MMB_KEY_BITS) {
        // Everything is in the root mask: we can just mask those bits off.
        MMB_TYPE block = mmbit_get_flat_block(bits, total_bits);
        block &= ~it_root->mask;
        mmb_store_partial(bits, block, total_bits);
        return;
    }

    // Larger case, we have two iterator levels to worry about.
    u32 bit_idx = 0;
    for (MMB_TYPE root = it_root->mask; root; root &= (root - 1), bit_idx++) {
        u32 bit = mmb_ctz(root);
        u32 block_key_min = bit * MMB_KEY_BITS;
        u32 block_key_max = block_key_min + MMB_KEY_BITS;
        u8 *block_ptr = bits + (bit * sizeof(MMB_TYPE));
        u32 iter_key = it_root->val + bit_idx;
        const struct mmbit_sparse_iter *it = it_root + iter_key;
        if (block_key_max <= total_bits) {
            // Full-sized block.
            MMB_TYPE block = mmb_load(block_ptr);
            block &= ~it->mask;
            mmb_store(block_ptr, block);
        } else {
            // Runt (final) block.
            u32 num_bits = total_bits - block_key_min;
            MMB_TYPE block = mmbit_get_flat_block(block_ptr, num_bits);
            block &= ~it->mask;
            mmb_store_partial(block_ptr, block, num_bits);
            break; // We know this is the last block.
        }
    }
}

static really_inline
void mmbit_sparse_iter_unset_big(u8 *bits, u32 total_bits,
                                 const struct mmbit_sparse_iter *it_root,
                                 struct mmbit_sparse_state *s) {
    const struct mmbit_sparse_iter *it = it_root;
    MMB_TYPE block = mmb_load(bits) & it->mask;
    if (!block) {
        return;
    }

    u32 key = 0;
    const u32 max_level = mmbit_maxlevel(total_bits);
    u32 level = 0;

    // Load first block into top level state
    s[level].mask = block;
    s[level].itkey = 0;
    for (;;) {
        block = s[level].mask;
        if (block) {
            if (level == max_level) {
                // bottom level block: we want to mask out the bits specified
                // by the iterator mask and then go back up a level.
                u8 *block_ptr =
                    mmbit_get_level_root(bits, level) + key * sizeof(MMB_TYPE);
                MMB_TYPE real_block = mmb_load(block_ptr);
                real_block &= ~(it->mask);
                mmb_store(block_ptr, real_block);
                goto uplevel; // still cheap and nasty
            } else {
                u32 bit = mmb_ctz(block);
                key = (key << MMB_KEY_SHIFT) + bit;
                level++;

                // iterator record is the start of the level (current it->val)
                // plus N, where N is the dense index of the bit in the current
                // level's itmask
                u32 iter_key = it->val + mmbit_mask_index(bit, it->mask);
                it = it_root + iter_key;
                MMB_TYPE nextblock =
                    mmb_load(mmbit_get_level_root_const(bits, level) +
                             key * sizeof(MMB_TYPE));
                s[level].mask = nextblock & it->mask;
                s[level].itkey = iter_key;
            }
        } else {
uplevel:
            // No bits set in this block
            if (level == 0) {
                return; // we are done
            }
            u8 *block_ptr =
                mmbit_get_level_root(bits, level) + key * sizeof(MMB_TYPE);
            MMB_TYPE real_block = mmb_load(block_ptr);
            key >>= MMB_KEY_SHIFT;
            level--;

            if (real_block == 0) {
                // If we've zeroed our block For Real (unmasked by iterator),
                // we can clear the parent bit that led us to it, so that
                // we don't go down this particular garden path again later.
                u32 bit = mmb_ctz(s[level].mask);
                u8 *parent_ptr =
                    mmbit_get_level_root(bits, level) + key * sizeof(MMB_TYPE);
                MMB_TYPE parent_block = mmb_load(parent_ptr);
                mmb_clear(&parent_block, bit);
                mmb_store(parent_ptr, parent_block);
            }

            // Update state mask and iterator
            s[level].mask &= (s[level].mask - 1);
            it = it_root + s[level].itkey;
        }
    }
}

/** \brief Sparse iterator, unset all bits.
 *
 * Takes in a sparse iterator tree structure and switches off any entries found
 * therein.
 */
static really_inline
void mmbit_sparse_iter_unset(u8 *bits, u32 total_bits,
                             const struct mmbit_sparse_iter *it,
                             struct mmbit_sparse_state *s) {
    assert(ISALIGNED_N(it, alignof(struct mmbit_sparse_iter)));

    // Our state _may_ be on the stack
#ifndef _WIN32
    assert(ISALIGNED_N(s, alignof(struct mmbit_sparse_state)));
#else
    assert(ISALIGNED_N(s, 4));
#endif

    MDEBUG_PRINTF("%p total_bits %u\n", bits, total_bits);

#ifdef MMB_TRACE_WRITES
    MMB_TRACE("ITER-UNSET iter=[");
    mmbit_sparse_iter_dump(it, total_bits);
    printf("] actually on=[");
    struct mmbit_sparse_state tmp[MAX_SPARSE_ITER_STATES];
    u32 idx = 0;
    u32 i = mmbit_sparse_iter_begin(bits, total_bits, &idx, it, tmp);
    for (; i != MMB_INVALID;
         i = mmbit_sparse_iter_next(bits, total_bits, i, &idx, it, tmp)) {
        printf(" %u", i);
    }
    printf("]\n");
#endif

    if (mmbit_is_flat_model(total_bits)) {
        mmbit_sparse_iter_unset_flat(bits, total_bits, it);
    } else {
        mmbit_sparse_iter_unset_big(bits, total_bits, it, s);
    }
}

#ifdef __cplusplus
} // extern "C"
#endif

#endif // MULTIBIT_H

{'repo_name': 'intel/hyperscan', 'stars': '2800', 'repo_language': 'C++', 'file_name': 'config.h.in', 'mime_type': 'text/x-c', 'hash': 244104557868812469, 'source_dataset': 'data'}


namespace ClassLib017
{
    public class Class073
    {
        public static string Property => "ClassLib017";
    }
}

{'repo_name': 'dotnet/performance', 'stars': '329', 'repo_language': 'C#', 'file_name': 'Class067.cs', 'mime_type': 'text/plain', 'hash': 2944485411767146044, 'source_dataset': 'data'}


//------------- blank.js -------------//
$(document).ready(function() {

	//get object with colros from plugin and store it.
	var objColors = $('body').data('appStart').getColors();
	var colours = {
		white: objColors.white,
		dark: objColors.dark,
		red : objColors.red,
		blue: objColors.blue,
		green : objColors.green,
		yellow: objColors.yellow,
		brown: objColors.brown,
		orange : objColors.orange,
		purple : objColors.purple,
		pink : objColors.pink,
		lime : objColors.lime,
		magenta: objColors.magenta,
		teal: objColors.teal,
		textcolor: '#5a5e63',
		gray: objColors.gray
	}

	//------------- Vector maps -------------//
	$('#world-map-markers').vectorMap({
	    map: 'world_mill_en',
	    scaleColors: [colours.teal, colours.blue],
	    normalizeFunction: 'polynomial',
	    hoverOpacity: 0.7,
	    hoverColor: false,
		focusOn:{
			x: 0.5,
			y: 0.5,
			scale: 2.0
		},
		zoomMin:0.85,
	    markerStyle: {
	      initial: {
	        fill: colours.red,
	        stroke: colours.red
	      }
	    },
	    backgroundColor: colours.white,
	    regionStyle:{
			initial: {
				fill: colours.teal,
				"fill-opacity": 1,
				stroke: colours.teal,
				"stroke-width": 0,
				"stroke-opacity": 0
			},
			hover: {
				"fill-opacity": 0.8
			},
			selected: {
				fill: 'yellow'
			}
		},
	    markers: [
			{latLng: [41.90, 12.45], name: 'Vatican City'},
			{latLng: [43.73, 7.41], name: 'Monaco'},
			{latLng: [-0.52, 166.93], name: 'Nauru'},
			{latLng: [-8.51, 179.21], name: 'Tuvalu'},
			{latLng: [43.93, 12.46], name: 'San Marino'},
			{latLng: [47.14, 9.52], name: 'Liechtenstein'},
			{latLng: [7.11, 171.06], name: 'Marshall Islands'},
			{latLng: [17.3, -62.73], name: 'Saint Kitts and Nevis'},
			{latLng: [3.2, 73.22], name: 'Maldives'},
			{latLng: [35.88, 14.5], name: 'Malta'},
			{latLng: [12.05, -61.75], name: 'Grenada'},
			{latLng: [13.16, -61.23], name: 'Saint Vincent and the Grenadines'},
			{latLng: [13.16, -59.55], name: 'Barbados'},
			{latLng: [17.11, -61.85], name: 'Antigua and Barbuda'},
			{latLng: [-4.61, 55.45], name: 'Seychelles'},
			{latLng: [7.35, 134.46], name: 'Palau'},
			{latLng: [42.5, 1.51], name: 'Andorra'},
			{latLng: [14.01, -60.98], name: 'Saint Lucia'},
			{latLng: [6.91, 158.18], name: 'Federated States of Micronesia'},
			{latLng: [1.3, 103.8], name: 'Singapore'},
			{latLng: [1.46, 173.03], name: 'Kiribati'},
			{latLng: [-21.13, -175.2], name: 'Tonga'},
			{latLng: [15.3, -61.38], name: 'Dominica'},
			{latLng: [-20.2, 57.5], name: 'Mauritius'},
			{latLng: [26.02, 50.55], name: 'Bahrain'},
			{latLng: [0.33, 6.73], name: 'São Tomé and Príncipe'}
	    ]
	});

});

{'repo_name': 'project-store/theme', 'stars': '366', 'repo_language': 'HTML', 'file_name': 'table-responsive.css', 'mime_type': 'text/plain', 'hash': 4398037491820079559, 'source_dataset': 'data'}


/*
 * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.gjc.util;

import com.sun.enterprise.util.i18n.StringManager;
import com.sun.gjc.monitoring.StatementLeakProbeProvider;
import com.sun.logging.LogDomains;
import org.glassfish.resourcebase.resources.api.PoolInfo;

import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Statement leak detector that prints the stack trace of the thread when a
 * statement object is leaked. Once the leak timeout expires, a statement leak
 * is assumed and the caller stack trace is printed. When statement-leak-reclaim
 * is set to true, the statement object is reclaimed.
 *
 * @author Shalini M
 */
public class StatementLeakDetector {
    private HashMap<Statement, StackTraceElement[]> statementLeakThreadStackHashMap;
    private HashMap<Statement, StatementLeakTask> statementLeakTimerTaskHashMap;
    private PoolInfo poolInfo;
    private boolean statementLeakTracing;
    private long statementLeakTimeoutInMillis;
    private boolean statementLeakReclaim;
    //Lock on HashMap to trace statement leaks
    private final Object statementLeakLock;
    private Map<Statement, StatementLeakListener> listeners;
    private final static Logger _logger = LogDomains.getLogger(
            StatementLeakDetector.class, LogDomains.RSR_LOGGER);
    private final static StringManager localStrings =
            StringManager.getManager(StatementLeakDetector.class);
    private Timer timer;
    private StatementLeakProbeProvider stmtLeakProbeProvider = null;

    public StatementLeakDetector(PoolInfo poolInfo, boolean leakTracing,
            long leakTimeoutInMillis, boolean leakReclaim, Timer timer) {
        this.poolInfo = poolInfo;
        statementLeakThreadStackHashMap = new HashMap<Statement, StackTraceElement[]>();
        statementLeakTimerTaskHashMap = new HashMap<Statement, StatementLeakTask>();
        listeners = new HashMap<Statement, StatementLeakListener>();
        statementLeakLock = new Object();
        statementLeakTracing = leakTracing;
        statementLeakTimeoutInMillis = leakTimeoutInMillis;
        statementLeakReclaim = leakReclaim;
        this.timer = timer;
        stmtLeakProbeProvider = new StatementLeakProbeProvider();
    }

    public void reset(boolean leakTracing, long leakTimeoutInMillis, boolean leakReclaim) {
        if (!statementLeakTracing && leakTracing) {
            clearAllStatementLeakTasks();
        }
        statementLeakTracing = leakTracing;
        statementLeakTimeoutInMillis = leakTimeoutInMillis;
        statementLeakReclaim = leakReclaim;
    }

    private void registerListener(Statement stmt, StatementLeakListener listener) {
        listeners.put(stmt, listener);
    }

    private void unRegisterListener(Statement stmt) {
        listeners.remove(stmt);
    }

    /**
     * Starts statement leak tracing
     *
     * @param stmt Statement which needs to be traced
     * @param listener       Leak Listener
     */
    public void startStatementLeakTracing(Statement stmt, StatementLeakListener listener) {
        synchronized (statementLeakLock) {
            if (!statementLeakThreadStackHashMap.containsKey(stmt)) {
                statementLeakThreadStackHashMap.put(stmt, Thread.currentThread().getStackTrace());
                StatementLeakTask statementLeakTask = new StatementLeakTask(stmt);
                statementLeakTimerTaskHashMap.put(stmt, statementLeakTask);
                registerListener(stmt, listener);
                if (timer != null) {
                    timer.schedule(statementLeakTask, statementLeakTimeoutInMillis);
                    if(_logger.isLoggable(Level.FINEST)) {
                        _logger.finest("Scheduled Statement leak tracing timer task");
                    }
                }
            }
        }
    }

    /**
     * Stops statement leak tracing
     *
     * @param stmt Statement which needs to be traced
     * @param listener       Leak Listener
     */
    public void stopStatementLeakTracing(Statement stmt, StatementLeakListener listener) {
        synchronized (statementLeakLock) {
            if (statementLeakThreadStackHashMap.containsKey(stmt)) {
                statementLeakThreadStackHashMap.remove(stmt);
                StatementLeakTask statementLeakTask =
                        statementLeakTimerTaskHashMap.remove(stmt);
                statementLeakTask.cancel();
                timer.purge();
                if(_logger.isLoggable(Level.FINEST)) {
                    _logger.finest("Stopped Statement leak tracing timer task");
                }
                unRegisterListener(stmt);
            }
        }
    }

    /**
     * Logs the potential statement leaks
     *
     * @param stmt Statement that is not closed by application
     */
    private void potentialStatementLeakFound(Statement stmt) {
        synchronized (statementLeakLock) {
            if (statementLeakThreadStackHashMap.containsKey(stmt)) {
                StackTraceElement[] threadStack = statementLeakThreadStackHashMap.remove(stmt);
                StatementLeakListener stmtLeakListener = listeners.get(stmt);
                stmtLeakProbeProvider.potentialStatementLeakEvent(poolInfo.getName(),
                        poolInfo.getApplicationName(), poolInfo.getModuleName());
                printStatementLeakTrace(threadStack);
                statementLeakTimerTaskHashMap.remove(stmt);
                if (statementLeakReclaim) {
                    try {
                        stmtLeakListener.reclaimStatement();
                    } catch (SQLException ex) {
                        Object[] params = new Object[]{poolInfo, ex};
                        _logger.log(Level.WARNING,
                                "statement.leak.detector_reclaim_statement_failure",
                                params);
                    }
                }
                //Unregister here as the listeners would still be present in the map.
                unRegisterListener(stmt);
            }
        }
    }

    /**
     * Prints the stack trace of thread leaking statement to server logs
     *
     * @param threadStackTrace Application(caller) thread stack trace
     */
    private void printStatementLeakTrace(StackTraceElement[] threadStackTrace) {
        StringBuffer stackTrace = new StringBuffer();
        String msg = localStrings.getStringWithDefault(
                "potential.statement.leak.msg",
                "A potential statement leak detected for connection pool " + poolInfo +
                        ". The stack trace of the thread is provided below : ",
                new Object[]{poolInfo});
        stackTrace.append(msg);
        stackTrace.append("\n");
        for (int i = 2; i < threadStackTrace.length; i++) {
            stackTrace.append(threadStackTrace[i].toString());
            stackTrace.append("\n");
        }
        _logger.log(Level.WARNING, stackTrace.toString(), "ConnectionPoolName=" + poolInfo);
    }

    /**
     * Clear all statement leak tracing tasks in case of statement leak
     * tracing being turned off
     */
    public void clearAllStatementLeakTasks() {
        synchronized (statementLeakLock) {
            Iterator<Map.Entry<Statement, StatementLeakTask>> entryIterator =
                    statementLeakTimerTaskHashMap.entrySet().iterator();
            while (entryIterator.hasNext()) {
                Map.Entry<Statement,StatementLeakTask> entry = entryIterator.next();
                StatementLeakTask statementLeakTask = entry.getValue();
                statementLeakTask.cancel();
            }
            if (timer != null)
                timer.purge();
            statementLeakThreadStackHashMap.clear();
            statementLeakTimerTaskHashMap.clear();
        }
    }

    private class StatementLeakTask extends TimerTask {

        private Statement statement;

        StatementLeakTask(Statement stmt) {
            this.statement = stmt;
        }

        public void run() {
            potentialStatementLeakFound(statement);
        }
    }

}

{'repo_name': 'eclipse-ee4j/glassfish', 'stars': '178', 'repo_language': 'Java', 'file_name': 'build.xml', 'mime_type': 'text/plain', 'hash': 7010976047205418809, 'source_dataset': 'data'}


/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = require('../utils/Class');
var GetValue = require('../utils/object/GetValue');
var NOOP = require('../utils/NOOP');
var RequestAnimationFrame = require('../dom/RequestAnimationFrame');

// http://www.testufo.com/#test=animation-time-graph

/**
 * @classdesc
 * The core runner class that Phaser uses to handle the game loop. It can use either Request Animation Frame,
 * or SetTimeout, based on browser support and config settings, to create a continuous loop within the browser.
 *
 * Each time the loop fires, `TimeStep.step` is called and this is then passed onto the core Game update loop,
 * it is the core heartbeat of your game. It will fire as often as Request Animation Frame is capable of handling
 * on the target device.
 *
 * Note that there are lots of situations where a browser will stop updating your game. Such as if the player
 * switches tabs, or covers up the browser window with another application. In these cases, the 'heartbeat'
 * of your game will pause, and only resume when focus is returned to it by the player. There is no way to avoid
 * this situation, all you can do is use the visibility events the browser, and Phaser, provide to detect when
 * it has happened and then gracefully recover.
 *
 * @class TimeStep
 * @memberof Phaser.Core
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Game} game - A reference to the Phaser.Game instance that owns this Time Step.
 * @param {Phaser.Types.Core.FPSConfig} config
 */
var TimeStep = new Class({

    initialize:

    function TimeStep (game, config)
    {
        /**
         * A reference to the Phaser.Game instance.
         *
         * @name Phaser.Core.TimeStep#game
         * @type {Phaser.Game}
         * @readonly
         * @since 3.0.0
         */
        this.game = game;

        /**
         * The Request Animation Frame DOM Event handler.
         *
         * @name Phaser.Core.TimeStep#raf
         * @type {Phaser.DOM.RequestAnimationFrame}
         * @readonly
         * @since 3.0.0
         */
        this.raf = new RequestAnimationFrame();

        /**
         * A flag that is set once the TimeStep has started running and toggled when it stops.
         *
         * @name Phaser.Core.TimeStep#started
         * @type {boolean}
         * @readonly
         * @default false
         * @since 3.0.0
         */
        this.started = false;

        /**
         * A flag that is set once the TimeStep has started running and toggled when it stops.
         * The difference between this value and `started` is that `running` is toggled when
         * the TimeStep is sent to sleep, where-as `started` remains `true`, only changing if
         * the TimeStep is actually stopped, not just paused.
         *
         * @name Phaser.Core.TimeStep#running
         * @type {boolean}
         * @readonly
         * @default false
         * @since 3.0.0
         */
        this.running = false;

        /**
         * The minimum fps rate you want the Time Step to run at.
         *
         * @name Phaser.Core.TimeStep#minFps
         * @type {integer}
         * @default 5
         * @since 3.0.0
         */
        this.minFps = GetValue(config, 'min', 5);

        /**
         * The target fps rate for the Time Step to run at.
         *
         * Setting this value will not actually change the speed at which the browser runs, that is beyond
         * the control of Phaser. Instead, it allows you to determine performance issues and if the Time Step
         * is spiraling out of control.
         *
         * @name Phaser.Core.TimeStep#targetFps
         * @type {integer}
         * @default 60
         * @since 3.0.0
         */
        this.targetFps = GetValue(config, 'target', 60);

        /**
         * The minFps value in ms.
         * Defaults to 200ms between frames (i.e. super slow!)
         *
         * @name Phaser.Core.TimeStep#_min
         * @type {number}
         * @private
         * @since 3.0.0
         */
        this._min = 1000 / this.minFps;

        /**
         * The targetFps value in ms.
         * Defaults to 16.66ms between frames (i.e. normal)
         *
         * @name Phaser.Core.TimeStep#_target
         * @type {number}
         * @private
         * @since 3.0.0
         */
        this._target = 1000 / this.targetFps;

        /**
         * An exponential moving average of the frames per second.
         *
         * @name Phaser.Core.TimeStep#actualFps
         * @type {integer}
         * @readonly
         * @default 60
         * @since 3.0.0
         */
        this.actualFps = this.targetFps;

        /**
         * The time at which the next fps rate update will take place.
         * When an fps update happens, the `framesThisSecond` value is reset.
         *
         * @name Phaser.Core.TimeStep#nextFpsUpdate
         * @type {integer}
         * @readonly
         * @default 0
         * @since 3.0.0
         */
        this.nextFpsUpdate = 0;

        /**
         * The number of frames processed this second.
         *
         * @name Phaser.Core.TimeStep#framesThisSecond
         * @type {integer}
         * @readonly
         * @default 0
         * @since 3.0.0
         */
        this.framesThisSecond = 0;

        /**
         * A callback to be invoked each time the Time Step steps.
         *
         * @name Phaser.Core.TimeStep#callback
         * @type {Phaser.Types.Core.TimeStepCallback}
         * @default NOOP
         * @since 3.0.0
         */
        this.callback = NOOP;

        /**
         * You can force the Time Step to use Set Timeout instead of Request Animation Frame by setting
         * the `forceSetTimeOut` property to `true` in the Game Configuration object. It cannot be changed at run-time.
         *
         * @name Phaser.Core.TimeStep#forceSetTimeOut
         * @type {boolean}
         * @readonly
         * @default false
         * @since 3.0.0
         */
        this.forceSetTimeOut = GetValue(config, 'forceSetTimeOut', false);

        /**
         * The time, calculated at the start of the current step, as smoothed by the delta value.
         *
         * @name Phaser.Core.TimeStep#time
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.time = 0;

        /**
         * The time at which the game started running. This value is adjusted if the game is then
         * paused and resumes.
         *
         * @name Phaser.Core.TimeStep#startTime
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.startTime = 0;

        /**
         * The time, as returned by `performance.now` of the previous step.
         *
         * @name Phaser.Core.TimeStep#lastTime
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.lastTime = 0;

        /**
         * The current frame the game is on. This counter is incremented once every game step, regardless of how much
         * time has passed and is unaffected by delta smoothing.
         *
         * @name Phaser.Core.TimeStep#frame
         * @type {integer}
         * @readonly
         * @default 0
         * @since 3.0.0
         */
        this.frame = 0;

        /**
         * Is the browser currently considered in focus by the Page Visibility API?
         * This value is set in the `blur` method, which is called automatically by the Game instance.
         *
         * @name Phaser.Core.TimeStep#inFocus
         * @type {boolean}
         * @readonly
         * @default true
         * @since 3.0.0
         */
        this.inFocus = true;

        /**
         * The timestamp at which the game became paused, as determined by the Page Visibility API.
         *
         * @name Phaser.Core.TimeStep#_pauseTime
         * @type {number}
         * @private
         * @default 0
         * @since 3.0.0
         */
        this._pauseTime = 0;

        /**
         * An internal counter to allow for the browser 'cooling down' after coming back into focus.
         *
         * @name Phaser.Core.TimeStep#_coolDown
         * @type {integer}
         * @private
         * @default 0
         * @since 3.0.0
         */
        this._coolDown = 0;

        /**
         * The delta time, in ms, since the last game step. This is a clamped and smoothed average value.
         *
         * @name Phaser.Core.TimeStep#delta
         * @type {integer}
         * @default 0
         * @since 3.0.0
         */
        this.delta = 0;

        /**
         * Internal index of the delta history position.
         *
         * @name Phaser.Core.TimeStep#deltaIndex
         * @type {integer}
         * @default 0
         * @since 3.0.0
         */
        this.deltaIndex = 0;

        /**
         * Internal array holding the previous delta values, used for delta smoothing.
         *
         * @name Phaser.Core.TimeStep#deltaHistory
         * @type {integer[]}
         * @since 3.0.0
         */
        this.deltaHistory = [];

        /**
         * The maximum number of delta values that are retained in order to calculate a smoothed moving average.
         *
         * This can be changed in the Game Config via the `fps.deltaHistory` property. The default is 10.
         *
         * @name Phaser.Core.TimeStep#deltaSmoothingMax
         * @type {integer}
         * @default 10
         * @since 3.0.0
         */
        this.deltaSmoothingMax = GetValue(config, 'deltaHistory', 10);

        /**
         * The number of frames that the cooldown is set to after the browser panics over the FPS rate, usually
         * as a result of switching tabs and regaining focus.
         *
         * This can be changed in the Game Config via the `fps.panicMax` property. The default is 120.
         *
         * @name Phaser.Core.TimeStep#panicMax
         * @type {integer}
         * @default 120
         * @since 3.0.0
         */
        this.panicMax = GetValue(config, 'panicMax', 120);

        /**
         * The actual elapsed time in ms between one update and the next.
         *
         * Unlike with `delta`, no smoothing, capping, or averaging is applied to this value.
         * So please be careful when using this value in math calculations.
         *
         * @name Phaser.Core.TimeStep#rawDelta
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.rawDelta = 0;

        /**
         * The time, as returned by `performance.now` at the very start of the current step.
         * This can differ from the `time` value in that it isn't calculated based on the delta value.
         *
         * @name Phaser.Core.TimeStep#now
         * @type {number}
         * @default 0
         * @since 3.18.0
         */
        this.now = 0;

        /**
         * Apply smoothing to the delta value used within Phasers internal calculations?
         *
         * This can be changed in the Game Config via the `fps.smoothStep` property. The default is `true`.
         *
         * Smoothing helps settle down the delta values after browser tab switches, or other situations
         * which could cause significant delta spikes or dips. By default it has been enabled in Phaser 3
         * since the first version, but is now exposed under this property (and the corresponding game config
         * `smoothStep` value), to allow you to easily disable it, should you require.
         *
         * @name Phaser.Core.TimeStep#smoothStep
         * @type {boolean}
         * @since 3.22.0
         */
        this.smoothStep = GetValue(config, 'smoothStep', true);
    },

    /**
     * Called by the Game instance when the DOM window.onBlur event triggers.
     *
     * @method Phaser.Core.TimeStep#blur
     * @since 3.0.0
     */
    blur: function ()
    {
        this.inFocus = false;
    },

    /**
     * Called by the Game instance when the DOM window.onFocus event triggers.
     *
     * @method Phaser.Core.TimeStep#focus
     * @since 3.0.0
     */
    focus: function ()
    {
        this.inFocus = true;

        this.resetDelta();
    },

    /**
     * Called when the visibility API says the game is 'hidden' (tab switch out of view, etc)
     *
     * @method Phaser.Core.TimeStep#pause
     * @since 3.0.0
     */
    pause: function ()
    {
        this._pauseTime = window.performance.now();
    },

    /**
     * Called when the visibility API says the game is 'visible' again (tab switch back into view, etc)
     *
     * @method Phaser.Core.TimeStep#resume
     * @since 3.0.0
     */
    resume: function ()
    {
        this.resetDelta();

        this.startTime += this.time - this._pauseTime;
    },

    /**
     * Resets the time, lastTime, fps averages and delta history.
     * Called automatically when a browser sleeps them resumes.
     *
     * @method Phaser.Core.TimeStep#resetDelta
     * @since 3.0.0
     */
    resetDelta: function ()
    {
        var now = window.performance.now();

        this.time = now;
        this.lastTime = now;
        this.nextFpsUpdate = now + 1000;
        this.framesThisSecond = 0;

        //  Pre-populate smoothing array

        for (var i = 0; i < this.deltaSmoothingMax; i++)
        {
            this.deltaHistory[i] = Math.min(this._target, this.deltaHistory[i]);
        }

        this.delta = 0;
        this.deltaIndex = 0;

        this._coolDown = this.panicMax;
    },

    /**
     * Starts the Time Step running, if it is not already doing so.
     * Called automatically by the Game Boot process.
     *
     * @method Phaser.Core.TimeStep#start
     * @since 3.0.0
     *
     * @param {Phaser.Types.Core.TimeStepCallback} callback - The callback to be invoked each time the Time Step steps.
     */
    start: function (callback)
    {
        if (this.started)
        {
            return this;
        }

        this.started = true;
        this.running = true;

        for (var i = 0; i < this.deltaSmoothingMax; i++)
        {
            this.deltaHistory[i] = this._target;
        }

        this.resetDelta();

        this.startTime = window.performance.now();

        this.callback = callback;

        this.raf.start(this.step.bind(this), this.forceSetTimeOut, this._target);
    },

    /**
     * The main step method. This is called each time the browser updates, either by Request Animation Frame,
     * or by Set Timeout. It is responsible for calculating the delta values, frame totals, cool down history and more.
     * You generally should never call this method directly.
     *
     * @method Phaser.Core.TimeStep#step
     * @since 3.0.0
     */
    step: function ()
    {
        //  Because the timestamp passed in from raf represents the beginning of the main thread frame that we’re currently in,
        //  not the actual time now, and as we want to compare this time value against Event timeStamps and the like, we need a
        //  more accurate one:

        var time = window.performance.now();

        this.now = time;

        var before = time - this.lastTime;

        if (before < 0)
        {
            //  Because, Chrome.
            before = 0;
        }

        this.rawDelta = before;

        var idx = this.deltaIndex;
        var history = this.deltaHistory;
        var max = this.deltaSmoothingMax;

        //  delta time (time is in ms)
        var dt = before;

        //  Delta Average
        var avg = before;

        //  When a browser switches tab, then comes back again, it takes around 10 frames before
        //  the delta time settles down so we employ a 'cooling down' period before we start
        //  trusting the delta values again, to avoid spikes flooding through our delta average

        if (this.smoothStep)
        {
            if (this._coolDown > 0 || !this.inFocus)
            {
                this._coolDown--;

                dt = Math.min(dt, this._target);
            }

            if (dt > this._min)
            {
                //  Probably super bad start time or browser tab context loss,
                //  so use the last 'sane' dt value

                dt = history[idx];

                //  Clamp delta to min (in case history has become corrupted somehow)
                dt = Math.min(dt, this._min);
            }

            //  Smooth out the delta over the previous X frames

            //  add the delta to the smoothing array
            history[idx] = dt;

            //  adjusts the delta history array index based on the smoothing count
            //  this stops the array growing beyond the size of deltaSmoothingMax
            this.deltaIndex++;

            if (this.deltaIndex > max)
            {
                this.deltaIndex = 0;
            }

            //  Loop the history array, adding the delta values together
            avg = 0;

            for (var i = 0; i < max; i++)
            {
                avg += history[i];
            }

            //  Then divide by the array length to get the average delta
            avg /= max;
        }

        //  Set as the world delta value
        this.delta = avg;

        //  Real-world timer advance
        this.time += this.rawDelta;

        // Update the estimate of the frame rate, `fps`. Every second, the number
        // of frames that occurred in that second are included in an exponential
        // moving average of all frames per second, with an alpha of 0.25. This
        // means that more recent seconds affect the estimated frame rate more than
        // older seconds.
        //
        // When a browser window is NOT minimized, but is covered up (i.e. you're using
        // another app which has spawned a window over the top of the browser), then it
        // will start to throttle the raf callback time. It waits for a while, and then
        // starts to drop the frame rate at 1 frame per second until it's down to just over 1fps.
        // So if the game was running at 60fps, and the player opens a new window, then
        // after 60 seconds (+ the 'buffer time') it'll be down to 1fps, so rafin'g at 1Hz.
        //
        // When they make the game visible again, the frame rate is increased at a rate of
        // approx. 8fps, back up to 60fps (or the max it can obtain)
        //
        // There is no easy way to determine if this drop in frame rate is because the
        // browser is throttling raf, or because the game is struggling with performance
        // because you're asking it to do too much on the device.

        if (time > this.nextFpsUpdate)
        {
            //  Compute the new exponential moving average with an alpha of 0.25.
            this.actualFps = 0.25 * this.framesThisSecond + 0.75 * this.actualFps;
            this.nextFpsUpdate = time + 1000;
            this.framesThisSecond = 0;
        }

        this.framesThisSecond++;

        //  Interpolation - how far between what is expected and where we are?
        var interpolation = avg / this._target;

        this.callback(time, avg, interpolation);

        //  Shift time value over
        this.lastTime = time;

        this.frame++;
    },

    /**
     * Manually calls `TimeStep.step`.
     *
     * @method Phaser.Core.TimeStep#tick
     * @since 3.0.0
     */
    tick: function ()
    {
        this.step();
    },

    /**
     * Sends the TimeStep to sleep, stopping Request Animation Frame (or SetTimeout) and toggling the `running` flag to false.
     *
     * @method Phaser.Core.TimeStep#sleep
     * @since 3.0.0
     */
    sleep: function ()
    {
        if (this.running)
        {
            this.raf.stop();

            this.running = false;
        }
    },

    /**
     * Wakes-up the TimeStep, restarting Request Animation Frame (or SetTimeout) and toggling the `running` flag to true.
     * The `seamless` argument controls if the wake-up should adjust the start time or not.
     *
     * @method Phaser.Core.TimeStep#wake
     * @since 3.0.0
     *
     * @param {boolean} [seamless=false] - Adjust the startTime based on the lastTime values.
     */
    wake: function (seamless)
    {
        if (this.running)
        {
            return;
        }
        else if (seamless)
        {
            this.startTime += -this.lastTime + (this.lastTime + window.performance.now());
        }

        this.raf.start(this.step.bind(this), this.useRAF);

        this.running = true;

        this.step();
    },

    /**
     * Gets the duration which the game has been running, in seconds.
     *
     * @method Phaser.Core.TimeStep#getDuration
     * @since 3.17.0
     *
     * @return {number} The duration in seconds.
     */
    getDuration: function ()
    {
        return Math.round(this.lastTime - this.startTime) / 1000;
    },

    /**
     * Gets the duration which the game has been running, in ms.
     *
     * @method Phaser.Core.TimeStep#getDurationMS
     * @since 3.17.0
     *
     * @return {number} The duration in ms.
     */
    getDurationMS: function ()
    {
        return Math.round(this.lastTime - this.startTime);
    },

    /**
     * Stops the TimeStep running.
     *
     * @method Phaser.Core.TimeStep#stop
     * @since 3.0.0
     *
     * @return {this} The TimeStep object.
     */
    stop: function ()
    {
        this.running = false;
        this.started = false;

        this.raf.stop();

        return this;
    },

    /**
     * Destroys the TimeStep. This will stop Request Animation Frame, stop the step, clear the callbacks and null
     * any objects.
     *
     * @method Phaser.Core.TimeStep#destroy
     * @since 3.0.0
     */
    destroy: function ()
    {
        this.stop();

        this.callback = NOOP;

        this.raf = null;
        this.game = null;
    }

});

module.exports = TimeStep;

{'repo_name': 'photonstorm/phaser', 'stars': '27782', 'repo_language': 'JavaScript', 'file_name': 'Product.js', 'mime_type': 'text/plain', 'hash': 5315389716874826672, 'source_dataset': 'data'}


{'repo_name': 'microsoft/fluentui-system-icons', 'stars': '1333', 'repo_language': 'Swift', 'file_name': 'build-ios.yml', 'mime_type': 'text/plain', 'hash': -5305590189220896191, 'source_dataset': 'data'}


### Reverse a singly linked list

Q: Given the pointer/reference to the head of a singly linked list,

reverse it and return the pointer/reference to the head of reversed linked list.

{'repo_name': 'lightningtgc/JavaScript-Algorithms', 'stars': '193', 'repo_language': 'JavaScript', 'file_name': 'dynamic-programming.md', 'mime_type': 'text/plain', 'hash': -7529757503954807626, 'source_dataset': 'data'}


import React, {Component} from 'react';
import StyleButton from "./styleButton"
const AlignmentControls = (props) => {
  const {editorState,lang} = props;
  const selection = editorState.getSelection();
  const blockType = editorState.getCurrentContent().getBlockForKey(selection.getStartKey()).getType();
  const BLOCK_TYPES = [
    {
      text:lang.alignLeft,
      label: "editor_alignment_left",
      style: 'left'
    }, {
      text:lang.alignCenter,
      label: "editor_alignment_center",
      style: 'center'
    }, {
      text:lang.alignRight,
      label: "editor_alignment_right",
      style: 'right'
    }, {
      text:lang.alignJustify,
      label: "editor_alignment_justify",
      style: 'justify'
    }
  ];
  return (
    <div className="RichEditor-controls">
      {BLOCK_TYPES.map((type, i) => {
        let button = <StyleButton
          key={type.style}
          text={type.text}
          active={type.style === blockType}
          label={type.label}
          onToggle={props.onToggle}
          style={type.style}/>
        return button;
      })}
    </div>
  );
};
module.exports = AlignmentControls;

{'repo_name': 'leejaen/react-lz-editor', 'stars': '857', 'repo_language': 'JavaScript', 'file_name': 'getQiniuUptoken.java', 'mime_type': 'text/plain', 'hash': 529238035984024858, 'source_dataset': 'data'}


<!DOCTYPE html>

	<meta http-equiv="content-type" content="text/html;charset=utf-8">
	<title>乌云搜索|搜索结果</title>
	<link href="//lib.baomitu.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" type="text/css">

			search from wooyun.org

home

about

<?php

require './config.php';

#接受参数
if (!isset($_GET['keywords']))
{
	header("Location: index.html");
	exit;
}
else
{
	$keywords = preg_replace("/[^a-zA-Z0-9\x{4e00}-\x{9fff}]+/u", "", $_GET['keywords']);
}

if (!isset($_GET['page']))
{
 	$page = 1;
}
else
{
	$page = intval($_GET['page']);
}

if (!isset($_GET['kind']))
{
	$kind = 'bugs';
}
else
{
	if ($_GET['kind'] === 'bugs' || $_GET['kind'] === 'drops' || $_GET['kind'] === 'author')
	{
		$kind = $_GET['kind'];
	}
	else
	{
		$kind = 'bugs';
	}
}

echo "
关键词【{$keywords}】的搜索结果：
";

//pdo连接mysql
try
{
    $conn = new PDO("mysql:host={$config['host']};dbname={$config['database']};port={$config['port']};charset=utf8", $config['user'], $config['passwd']);
    //echo "mysql:host={$config['host']};dbname={$config['database']}";
}
catch (PDOException $pe)
{
    die("Could not connect to the database $dbname :" . $pe->getMessage());
}

//查询数目
if ($kind === 'author')
{
    $query0 = "SELECT count(*) FROM `bugs` WHERE author LIKE '%{$keywords}%'";
    $query1 = "SELECT count(*) FROM `drops` WHERE author LIKE '%{$keywords}%'";
    $res0 = $conn->query($query0);
    $res1 = $conn->query($query1);
    $row = $res0->fetch(PDO::FETCH_NUM)[0] + $res1->fetch(PDO::FETCH_NUM)[0];
}
else
{
    $query0="SELECT count(*) FROM `{$kind}` WHERE `title` LIKE '%{$keywords}%'";
    $res0 = $conn->query($query0);
    $row = $res0->fetch(PDO::FETCH_NUM)[0];
}

//得到总页数 $p
if ($row % 15 != 0)
{
    $p = intval($row / 15) + 1;
}
else
{
    $p = $row / 15;
}
if ($row == 0) $p = 1;
if ($page > $p || $page <1 ) $page = 1;

echo "
共 {$row} 条记录
";

$start = ($page - 1) * 15;

if ($kind === 'author')
{
    $query = "(SELECT doc,dates,title,type,author FROM `bugs` WHERE `author` LIKE '%{$keywords}%') UNION ALL (SELECT doc,dates,title,type,author FROM `drops` WHERE `author` LIKE '%{$keywords}%')ORDER BY dates DESC LIMIT {$start},15";
}
else
{
    $query = "SELECT * FROM `{$kind}` WHERE `title` LIKE '%{$keywords}%' ORDER BY dates DESC LIMIT {$start},15";
}

$res = $conn->query($query);
$resulte = $res->fetchAll(PDO::FETCH_ASSOC);
//var_dump($resulte);

//输出结果
echo '

';
echo '
提交时间	标题	漏洞类型	提交者
';

foreach ($resulte as $rrr){
    if ($kind != "author")
    {
        echo "
";
    }
    else
    {
        if (array_key_exists($rrr['type'], $drops))
        {
            echo "
";
        }
        else
        {
            echo "
";
        }
    }

    $time0 = str_split($rrr['dates'], 10);
    echo "{$time0[0]}	";
    echo "{$rrr['title']}	";
	if (array_key_exists($rrr['type'], $drops))
	{
		echo "{$drops[$rrr['type']]}	";
	}
    else
	{
		echo "{$rrr['type']}	";
	}
    echo "{$rrr['author']}	";
    echo "
";
}
echo "

";

$conn = null;

//分页
echo '
';
//首
if ($page==1)
{
	echo '
«
';
}
else
{
	echo "
«
";
}
//中间处理
if ($p > 17)
{
	if ($page < 9)
	{
		$i=1;
	}
	elseif ($page >= 9 && $page + 8 < $p)
    {
		$i = $page-8;
	}
	elseif ($page + 8 >= $p)
    {
		$i = $p-8;
	}
	$j = $i + 17;
}
else
{
	$i = 1;
	$j = $p;
}
//echo $p;
for (;$i <= $j;$i++)
{
	if ($page == $i)
	{
		echo "
{$i}
";
	}
	else
    {
		echo "
{$i}
";
	}
}
//尾
if ($page == $p || $p ==0)
{
    echo '
»
';
}
else
{
    echo "
»
";
}
echo "
";

?>

公开漏洞、知识库等数据来自于wooyun.org

{'repo_name': 'grt1st/wooyun_search', 'stars': '337', 'repo_language': 'PHP', 'file_name': 'index.html', 'mime_type': 'text/html', 'hash': 5751533847265433807, 'source_dataset': 'data'}