//------------------------------------------------------------------------------
// GB_lookup_template: find k so that j == Ah [k]
//------------------------------------------------------------------------------

// Given a sparse, hypersparse, or hyperslice matrix, find k so that j == Ah
// [k], if it appears in the list.  k is not needed by the caller, just the
// variables pstart, pend, pleft, and found.  GB_lookup cannot be used if
// A is a slice (it could be extended to handle this case).

// This fine is #included' by GB.h, so the #include'ing file does either:
//      #include "GB.h"
// or
//      #define GB_KERNEL
//      #include "GB.h"

#ifdef GB_KERNEL
__device__
static inline bool GB_lookup_device
#else
static inline bool GB_lookup        // find j = Ah [k] in a hyperlist
#endif
(
    const bool A_is_hyper,          // true if A is hypersparse
    const int64_t *GB_RESTRICT Ah,  // A->h [0..A->nvec-1]: list of vectors
    const int64_t *GB_RESTRICT Ap,  // A->p [0..A->nvec  ]: pointers to vectors
    int64_t *GB_RESTRICT pleft,     // look only in A->h [pleft..pright]
    int64_t pright,                 // normally A->nvec-1, but can be trimmed
//  const int64_t nvec,             // A->nvec: number of vectors
    const int64_t j,                // vector to find, as j = Ah [k]
    int64_t *GB_RESTRICT pstart,    // start of vector: Ap [k]
    int64_t *GB_RESTRICT pend       // end of vector: Ap [k+1]
)
{
    if (A_is_hyper)
    {
        // to search the whole Ah list, use on input:
        // pleft = 0 ; pright = nvec-1 ;
        bool found ;
        GB_BINARY_SEARCH (j, Ah, (*pleft), pright, found) ;
        if (found)
        { 
            // j appears in the hyperlist at Ah [pleft]
            // k = (*pleft)
            (*pstart) = Ap [(*pleft)] ;
            (*pend)   = Ap [(*pleft)+1] ;
        }
        else
        { 
            // j does not appear in the hyperlist Ah
            // k = -1
            (*pstart) = -1 ;
            (*pend)   = -1 ;
        }
        return (found) ;
    }
    else
    { 
        // A is not hypersparse; j always appears
        // k = j
        (*pstart) = Ap [j] ;
        (*pend)   = Ap [j+1] ;
        return (true) ;
    }
}


