//
//  File:   hzSSR.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.
//
/*
**  SSR: Small Strings Allocation and Management Regime
**
**  The primary objective of SSR is to reduce memory allocation overheads for small strings and string-like entities, which are expected to have large populations. Unlike a general
**  memory allocation regime which can make no assumptions about the entities allocated, a regime for strings can exploit the following aspects:-
**
**      - Strings do not need to be aligned to 4 or 8 byte boundaries.
**      - Strings are always null-terminated
**      - Instances of the various string and string-like classes, carry the size of the string with them. This negates the need for the regime to hold size information.
*/
#ifndef hzSSR_h
#define hzSSR_h
#include <string.h>
#include "hzErrcode.h"
#include "hzLock.h"
#define SSR_BLOC_MASK   0xffff0000  //  Bits 1 to 15 inclusive for block part of address
#define SSR_BLOC_SPACE  65536       //  Total size of the string space blocks in multiples of 8 bytes
/*
**  Definitions
*/
struct  _ssrFLE
{
    //  The slot is used as an entry in a free list. Upon string space allocation, slots are either advanced or removed from the free list. The space occupied by the slot is then
    //  used as string space.
    uchar       m_Blank[4] ;    //  m_Blank[0] is set to 0xff on item deletion
    uint32_t    m_fleNext ;     //  Pointer to next free slot
} ;
struct  _ssrBloc
{
    //  Small string space superblock
    uint32_t    m_blkSelf ;                 //  Address of block
    //uint32_t  m_Resv ;                    //  Reserved for now
    uint32_t    m_Usage ;                   //  Space used (so position of free space)
    //uint16_t  m_nItems ;                  //  Number of total items
    //uint16_t  m_nFree ;                   //  Total volume of deleted items
    //uint16_t  m_nDead ;                   //  Number of deleted items
    uint64_t    m_Space[SSR_BLOC_SPACE] ;   //  Areas for string spaces
    _ssrBloc    (void)
    {
        m_blkSelf = 0 ;
        m_Usage = 0 ;   //m_nItems = m_nFree = m_nDead = 0 ;
    }
} ;
class   hzSSR   //_ssrRegime
{
public:
    //  Blocks
    hzArray <_ssrBloc*> m_Super ;
    //_ssrBloc* m_Super[64] ;       //  Max of 4096 string value 512K superblocks
    _ssrBloc*   m_pTopBlock ;       //  Latest small string space superblock (only one from which new string spaces can be allocated)
    uint64_t    m_nAllocNew ;       //  Total number of new allocations
    uint64_t    m_nAllocOld ;       //  Total number of allocations from free list
    uint64_t    m_nReleases ;       //  Total number of releases
    //  Locks
    hzLockRWD   m_lockItem[64] ;    //  String allocation locks
    hzLockRWD   m_lockSbloc ;       //  Lock for allocating superblocks
    hzLockRWD   m_lockOsize ;       //  Lock for allocating/freeing of oversize strings
    //  Freelists (depends on size)
    uint32_t    m_flistItem[64] ;   //  Freelists for string spaces of sizes 8 to 256 bytes
    uint32_t    m_flistPopl[64] ;   //  Population of the string space freelists
    //uint32_t  m_nBloc ;           //  Superblock population
    uint32_t    m_nLive ;           //  Live string population
    hzSSR   (void)
    {
        m_pTopBlock = 0 ;
        //m_nBloc = 0 ;
        m_nAllocNew = m_nAllocOld = m_nReleases = 0 ;
        //m_nBloc = 
        m_nLive = 0 ;
        //memset(m_Super, 0, 64 * sizeof(_ssrBloc*)) ;
        memset(m_flistItem, 0, 64 * sizeof(uint32_t)) ;
        memset(m_flistPopl, 0, 64 * sizeof(uint32_t)) ;
    }
    //  Memory operations
    uchar*      Xlate   (uint32_t ssrAddr) ;
    uint32_t    Alloc   (uint32_t nSize) ;
    hzEcode     Free    (uint32_t strAddr, uint32_t nSize) ;
    //  Integrity Report
    void    Report  (hzChain& report) ;
} ;
#endif  //  hzString_h