//
//  File:   hzIntset.h
//
//  Legal Notice: This file is part of the HadronZoo C++ Class Library.
//
//  Copyright 2025 HadronZoo Project (http://www.hadronzoo.com)
//
//  The HadronZoo C++ Class Library is free software: You can redistribute it, and/or modify it under the terms of the GNU Lesser General Public License, as published by the Free
//  Software Foundation, either version 3 of the License, or any later version.
//
//  The HadronZoo C++ Class Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
//  A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public License along with the HadronZoo C++ Class Library. If not, see http://www.gnu.org/licenses.
//
#ifndef hzIntset_h
#define hzIntset_h
/*
**  Other includes
*/
#include "hzBasedefs.h"
#include "hzTmplVect.h"
/*
**  Idset class
*/
class   _idsNode ;  //  Defined in hzIntset.cpp
class   hzIntset
{
    //  Category:   Index
    //
    //  hzIntset holds a set of 32-bit unsigned integers. hzIntset instances are known as idsets because the hzIntset class is extensively used in the HDB, as container of HDB data
    //  object and datum ids.
    //
    //  hzIntset can be configured to be persistent or volatile. In the HDB, persistent idsets are used in repositories and indexes, while volatile idsets are used for holding and
    //  processing search results.
    //
    //  Volatile idsets are fully memory resident, which simplifies matters considerably. Depending on the population, the memory resident component either has the form of a single
    //  segment, or a map of segments.
    //
    //  Persistent idsets also have a memory resident component. It is of limited size, is backed by a delta file, and has the primary objective of forestalling whole block writes.
    //  Due to the 4K block size and the compactness of idsets, a single block will typically contain thousands of ids. It makes no sense to write out a whole block each time an id
    //  is added or deleted.
    struct  _idset_ca
    {
        //  Bitmap internal structure to facilitate soft copy
        void*       m_pData ;       //  Data area pointer: to either a single _idsNode, or to a vector of _idsNode pointers
        uint16_t    m_bVect ;       //  1 if a vector is used, 0 if single _idsNode
        uint16_t    m_nCopies ;     //  Copy count
        uint32_t    m_nPop ;        //  Total idset popuation
        _idset_ca   (void)
        {
            m_pData = 0 ;
            m_bVect = 0 ;
            m_nPop = 0 ;
            m_nCopies = 0 ;
        }
    } ;
    _idset_ca*  mx ;        //  Internal instance
    _idsNode*   _findNode   (uint32_t nId) const ;
    //  Prevent copy constructor
    hzIntset    (const hzIntset& op)    {}
public:
    hzIntset    (void) ;
    ~hzIntset   (void) ;
    uint32_t    Count       (void) const    { return mx ? mx->m_nPop : 0 ; }
    uint32_t    NoNodes     (void) const ;  //  { return mx ? mx->m_pNodes.Count() : 0 ; }
    void        Clear       (void) ;
    uint32_t    Insert      (uint32_t nId) ;
    hzEcode     Delete      (uint32_t nId) ;
    uint32_t    Fetch       (hzVect<uint32_t>& Result, uint32_t nStart, uint32_t nReq) const ;
    //  Assignment
    hzIntset&   operator=   (const hzIntset& op) ;
    //  Boolean operators
    hzIntset&   operator|=  (const hzIntset& op) ;
    hzIntset&   operator&=  (const hzIntset& op) ;
    //  Get operators
    bool        operator[]  (uint32_t docId) const ;
    //  Diagnostics
    void    Show    (hzChain& C) const ;
    //  Stream operators
    friend  std::istream&   operator>>  (std::istream& is, hzIntset& ids) ;
    friend  std::ostream&   operator<<  (std::ostream& os, const hzIntset& ids) ;
} ;
/*
**  Idset Prototypes
*/
uint32_t    CountBits   (const void* pvBuffer, uint32_t nNoBytes) ;
void        SetBits     (char* pBitbuf, uint32_t nOset, bool bValue) ;
bool        GetBits     (const char* pBitbuf, uint32_t nOset) ;
#endif  //  hzIntset_h