Alien-Judy

 view release on metacpan or  search on metacpan

src/judy-1.0.5/src/JudyCommon/JudyPrivate.h  view on Meta::CPAN


// Copy a Word_t to a 7-byte Index pointed at by a uint8_t *:

#define JU_COPY7_LONG_TO_PINDEX(PINDEX,SOURCELONG)      \
    (PINDEX)[0] = (uint8_t)((SOURCELONG) >> 48);        \
    (PINDEX)[1] = (uint8_t)((SOURCELONG) >> 40);        \
    (PINDEX)[2] = (uint8_t)((SOURCELONG) >> 32);        \
    (PINDEX)[3] = (uint8_t)((SOURCELONG) >> 24);        \
    (PINDEX)[4] = (uint8_t)((SOURCELONG) >> 16);        \
    (PINDEX)[5] = (uint8_t)((SOURCELONG) >>  8);        \
    (PINDEX)[6] = (uint8_t)((SOURCELONG))

#endif // JU_64BIT

// ****************************************************************************
// COMMON CODE FRAGMENTS (MACROS)
// ****************************************************************************
//
// These code chunks are shared between various source files.


// SET (REPLACE) ONE DIGIT IN AN INDEX:
//
// To avoid endian issues, use masking and ORing, which operates in a
// big-endian register, rather than treating the Index as an array of bytes,
// though that would be simpler, but would operate in endian-specific memory.
//
// TBD:  This contains two variable shifts, is that bad?

#define JU_SETDIGIT(INDEX,DIGIT,STATE)                  \
        (INDEX) = ((INDEX) & (~cJU_MASKATSTATE(STATE))) \
                           | (((Word_t) (DIGIT))        \
                              << (((STATE) - 1) * cJU_BITSPERBYTE))

// Fast version for single LSB:

#define JU_SETDIGIT1(INDEX,DIGIT) (INDEX) = ((INDEX) & ~0xff) | (DIGIT)


// SET (REPLACE) "N" LEAST DIGITS IN AN INDEX:

#define JU_SETDIGITS(INDEX,INDEX2,cSTATE) \
        (INDEX) = ((INDEX ) & (~JU_LEASTBYTESMASK(cSTATE))) \
                | ((INDEX2) & ( JU_LEASTBYTESMASK(cSTATE)))

// COPY DECODE BYTES FROM JP TO INDEX:
//
// Modify Index digit(s) to match the bytes in jp_DcdPopO in case one or more
// branches are skipped and the digits are significant.  Its probably faster
// to just do this unconditionally than to check if its necessary.
//
// To avoid endian issues, use masking and ORing, which operates in a
// big-endian register, rather than treating the Index as an array of bytes,
// though that would be simpler, but would operate in endian-specific memory.
//
// WARNING:  Must not call JU_LEASTBYTESMASK (via cJU_DCDMASK) with Bytes =
// cJU_ROOTSTATE or a bad mask is generated, but there are no Dcd bytes to copy
// in this case anyway.  In fact there are no Dcd bytes unless State <
// cJU_ROOTSTATE - 1, so dont call this macro except in those cases.
//
// TBD:  It would be nice to validate jp_DcdPopO against known digits to ensure
// no corruption, but this is non-trivial.

#define JU_SETDCD(INDEX,PJP,cSTATE)                             \
    (INDEX) = ((INDEX) & ~cJU_DCDMASK(cSTATE))                  \
                | (JU_JPDCDPOP0(PJP) & cJU_DCDMASK(cSTATE))

// INSERT/DELETE AN INDEX IN-PLACE IN MEMORY:
//
// Given a pointer to an array of "even" (native), same-sized objects
// (indexes), the current population of the array, an offset in the array, and
// a new Index to insert, "shift up" the array elements (Indexes) above the
// insertion point and insert the new Index.  Assume there is sufficient memory
// to do this.
//
// In these macros, "i_offset" is an index offset, and "b_off" is a byte
// offset for odd Index sizes.
//
// Note:  Endian issues only arise fro insertion, not deletion, and even for
// insertion, they are transparent when native (even) objects are used, and
// handled explicitly for odd (non-native) Index sizes.
//
// Note:  The following macros are tricky enough that there is some test code
// for them appended to this file.

#define JU_INSERTINPLACE(PARRAY,POP1,OFFSET,INDEX)              \
        assert((long) (POP1) > 0);                              \
        assert((Word_t) (OFFSET) <= (Word_t) (POP1));           \
        {                                                       \
            Word_t i_offset = (POP1);                           \
                                                                \
            while (i_offset-- > (OFFSET))                       \
                (PARRAY)[i_offset + 1] = (PARRAY)[i_offset];    \
                                                                \
            (PARRAY)[OFFSET] = (INDEX);                         \
        }


// Variation for non-native Indexes, where cIS = Index Size
// and PByte must point to a uint8_t (byte); shift byte-by-byte:
//

#define JU_INSERTINPLACE3(PBYTE,POP1,OFFSET,INDEX)              \
{                                                               \
    Word_t i_off = POP1;                                        \
                                                                \
    while (i_off-- > (OFFSET))                                  \
    {                                                           \
        Word_t  i_dx = i_off * 3;                               \
        (PBYTE)[i_dx + 0 + 3] = (PBYTE)[i_dx + 0];              \
        (PBYTE)[i_dx + 1 + 3] = (PBYTE)[i_dx + 1];              \
        (PBYTE)[i_dx + 2 + 3] = (PBYTE)[i_dx + 2];              \
    }                                                           \
    JU_COPY3_LONG_TO_PINDEX(&((PBYTE)[(OFFSET) * 3]), INDEX);   \
}

#ifdef JU_64BIT

#define JU_INSERTINPLACE5(PBYTE,POP1,OFFSET,INDEX)              \
{                                                               \
    Word_t i_off = POP1;                                        \



( run in 0.699 second using v1.01-cache-2.11-cpan-39bf76dae61 )