SelectBPlusTree.h

// SelectBPlusTree.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2012

@import "Ceda/cxObject/MacroUtils.h"
@import "IPersistStore.h"

// Select between two alternative implementations
@def bool CEDA_USE_BTREE_WITH_TYPEOPS = true

@import "BPlusTree.h"
@import "CompareKeys.h"
@import "BPlusTree2.h"

namespace ceda
{

@if (CEDA_USE_BTREE_WITH_TYPEOPS)
{
    template <typename K>
    struct bplustreeset : bptreeset<K> {};

    template <typename K, typename V>
    struct bplustreemap : bptreemap<K,V> {};
}
@else
{
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    // xsetModelTraits

    /*
    For given K, xsetModelTraits<K>::BTree is a typename for the implementation of 
    the B+Tree chosen for xset<K> using the macros defined in BPlusTree.h
    */

    // Specialisations define a typedef named BTree, allowing for control over the 
    // implementation of the BTree for given K
    template <typename K>
    struct xsetModelTraits
    {
    };

    template <typename K>
    struct bplustreeset : btreeset< typename xsetModelTraits<K>::BTree >
    {
        bplustreeset()
        {
            // todo: We need a way to avoid this when the object is to be created for the purpose
            // of deserialisation.
            OnCreate(true);
        }
        
        BTree& GetUnderlyingBPlusTree() { return *Get(); }
        const BTree& GetUnderlyingBPlusTree() const { return *Get(); }
    };
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    // BPlusTreeModelTraits

    /*
    For given K,V, BPlusTreeModelTraits<K,V>::BTree is a typename for the implementation of 
    the B+Tree chosen for xmap<K,V> using the macros defined in BPlusTree.h
    */

    // Specialisations define a typedef named BTree, allowing for control over the 
    // implementation of the BTree for given K,V
    template <typename K, typename V>
    struct BPlusTreeModelTraits
    {
    };

    template <typename K, typename V>
    struct bplustreemap : btreemap< typename BPlusTreeModelTraits<K,V>::BTree >
    {
        bplustreemap()
        {
            // todo: We need a way to avoid this when the object is to be created for the purpose
            // of deserialisation.
            OnCreate(true);
        }
        ssize_t GetPayloadOffset() const
        {
            return BTree::GetPayloadOffset();
        }
    };
}

@def mImplement_xset(Key,bool bDefine,bool bImplement,bool bExport,bool bKeyMayHavePrefs, bool bDeclareKeysReachable) =
{
    @if (!CEDA_USE_BTREE_WITH_TYPEOPS)
    {
        @def BTreeName = mToIdentifier(`BPlusTree<Key,void>`)

        mImplementBplusTree(bDefine,bImplement,bExport,BTreeName,Key,void,CompareKeys,
            20,20,
            true,
            bKeyMayHavePrefs,bDeclareKeysReachable,false,false,
            false,
            false)

        @if (bDefine)
        {
            template <>
            struct xsetModelTraits<Key>
            {
                typedef BTreeName BTree;
            };
        }
    }
}

@def mImplement_xmap(
    bool _bDefine,bool _bImplement, bool _bExport,
    Key,Payload,bool bKeyMayHavePrefs,bool bPayLoadMayHavePrefs) =
{
    @if (!CEDA_USE_BTREE_WITH_TYPEOPS)
    {
        @def BTreeName = mToIdentifier(`BPlusTree<Key,Payload>`)
     
        mImplementBplusTree(_bDefine, _bImplement, _bExport,BTreeName,Key,Payload,CompareKeys,
            20,20,
            true,
            bKeyMayHavePrefs,bKeyMayHavePrefs,
            bPayLoadMayHavePrefs,bPayLoadMayHavePrefs,
            true,
            false)
     
        @if (_bDefine)
        {
            template <>
            struct BPlusTreeModelTraits<Key,Payload>
            {
                typedef BTreeName BTree;
            };
        }
    }
}


///////////////////////////////////////////////////////////////////////////////////////////////////
// BTreeIterator

/*
Used to implement a IBiDirIterator on a B+Tree
*/

template <typename const_iterator>
class BTreeIterator
{
public:
    BTreeIterator(const const_iterator& i) :
        m_it(i)
    {
    }
    
    // Implementation of IBiDirIterator
    void Close()
    { 
        delete this; 
    }
    const void* GetElement()
    {
        return m_it.can_dereference() ? &(*m_it) : NULL;
    }
    void Next()
    {
        ++m_it;
    }
    void Prev()
    {
        --m_it;
    }

private:
    const_iterator m_it;
};

///////////////////////////////////////////////////////////////////////////////////////////////////
// KeyType

/*
Allows for implementation of IKeyType using the given key type
*/

template <typename _Key>
class KeyType
{
public:
    // Implementation of IKeyType

    // Write the value of the variable at 'addr' to the given archive
    static void SerialiseVariable(Archive& ar, const void* addr)
    {
        ar << * (_Key*) addr;
    }

    // Read the value of the variable from the given archive
    static void DeserialiseVariable(InputArchive& ar, void* addr)
    {
        ar >> * (_Key*) addr;
    }

    static void SkipVariable(InputArchive& ar)
    {
        _Key tmp;
        ar >> tmp;
    }
};

} // namespace ceda