From 8808689fe340bec6e90ab13dd502292b0579cf1f Mon Sep 17 00:00:00 2001 From: Michael Krelin Date: Sat, 08 Dec 2012 21:19:17 +0000 Subject: initial osx port Signed-off-by: Michael Krelin --- (limited to 'shared-code/BTreendex.h') diff --git a/shared-code/BTreendex.h b/shared-code/BTreendex.h deleted file mode 100644 index 88109ab..0000000 --- a/shared-code/BTreendex.h +++ b/dev/null @@ -1,595 +0,0 @@ -#ifndef __BTREENDEX_H -#define __BTREENDEX_H - -#include "Dynamide.h" - -namespace Klever { - -template -class CBTreendex : public CObject { -public: - typedef LONG CBTPageRef; - struct CBTRecordRef { - CBTPageRef m_Page; - INT m_Offset; - CBTRecordRef(CBTPageRef page=-1,INT offset=-1) : m_Page(page), m_Offset(offset) {} - }; - class CBTRecord : public CObject { - public: - CBTPageRef m_ptrLeft; - CBTPageRef m_ptrRight; - key m_Key; - value m_Value; - CBTRecord() : m_ptrLeft(-1), m_ptrRight(-1) {} - CBTRecord(key& _key,value& _value,CBTPageRef left=-1,CBTPageRef right=-1) : m_Key(_key), m_Value(_value), m_ptrLeft(left), m_ptrRight(right) {} - CBTRecord(CBTRecord& r) : m_Key(r.m_Key), m_Value(r.m_Value), m_ptrLeft(r.m_ptrLeft), m_ptrRight(r.m_ptrRight) {} - - CBTRecord& operator=(CBTRecord& r) {m_Key=r.m_Key, m_Value=r.m_Value, m_ptrLeft=r.m_ptrLeft, m_ptrRight=r.m_ptrRight;return *this;} - - void Serialize(CArchive& ar) { - if(ar.IsStoring()){ - ar << m_ptrLeft; - ar << m_ptrRight; - }else{ - ar >> m_ptrLeft; - ar >> m_ptrRight; - } - SerializeElements(ar,&m_Key,1); - SerializeElements(ar,&m_Value,1); - } - }; - class CBTPage : public CArray { - public: - void Serialize(CArchive& ar) { - int nCount = -1; - if(ar.IsStoring()){ - nCount = GetSize(); - ar << nCount; - }else{ - nCount = 0; - ar >> nCount; - RemoveAll(); - SetSize(nCount); - } - for(int tmp=0;tmp CBTDyna; - typedef CBTDyna::CDynaFile CBTDynaFile; - typedef CArray CBTRStack; - - CBTDyna m_BT; - struct _btCrap { - BOOL m_bRootSet; - CBTPageRef m_Root; - } *m_BTCrap; - BOOL m_bRO; - CBTRStack m_btStack; - CBTPage m_stackTop; - - CBTreendex() {} - ~CBTreendex() { Close(); } - BOOL Attach(CFile* file,BOOL bAutodelete) { - m_bRO = FALSE; - if(!m_BT.Attach(file,bAutodelete)) - return FALSE; - return Attach(); - } - BOOL Open(LPCTSTR file,BOOL bReadOnly) { - if(!m_BT.Open(file,bReadOnly)) - return FALSE; - m_bRO = bReadOnly; - return Attach(); - } - BOOL Create(LPCTSTR file) { - try{ - CFile* f = new CFile(file,CFile::modeCreate|CFile::modeReadWrite|CFile::shareDenyRead|CFile::shareDenyWrite|CFile::typeBinary); - ASSERT(f); - return Attach(f,TRUE); - }catch(CException* e){ - e->Delete(); - return FALSE; - } - } - BOOL Attach() { - ASSERT(m_BT.IsOpened()); - m_BTCrap = (_btCrap*)m_BT.m_FB.crap; - if(!m_BTCrap->m_bRootSet){ - m_BTCrap->m_Root = AllocatePage(); - if(m_BTCrap->m_Root<0) - return FALSE; - m_BTCrap->m_bRootSet = TRUE; - m_BT.Write1stBlock(); - } - return TRUE; - } - BOOL Close() { - m_BT.Close(); - return TRUE; - } - BOOL IsOpened() { - return m_BT.IsOpened(); - } - - BOOL Lookup(key& _key,value& value) { - if(!IsOpened()) - return FALSE; - ASSERT(m_BTCrap->m_bRootSet); - if(!SeekToPage(_key)) - return FALSE; - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - if(rr.m_Offset<0) - return FALSE; - ASSERT(rr.m_Offsetm_bRootSet); - if(!SeekToPage(_key)) - return FALSE; - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - CBTRecord nuRecord(_key,_value); - if(rr.m_Offset<0){ - if(m_stackTop.GetSize()) - nuRecord.m_ptrLeft = m_stackTop[m_stackTop.GetUpperBound()].m_ptrRight; - }else if(rr.m_Offset==0){ - nuRecord.m_ptrRight = m_stackTop[0].m_ptrLeft; - }else{ - nuRecord.m_ptrLeft = m_stackTop[rr.m_Offset-1].m_ptrRight; - nuRecord.m_ptrRight = m_stackTop[rr.m_Offset].m_ptrLeft; - } -// ASSERT(rr.m_Offset==0 || (m_stackTop[rr.m_Offset-1].m_Key<_key && m_stackTop[rr.m_Offset-1].m_ptrRight<0)); -// ASSERT(rr.m_Offset<0 || m_stackTop[rr.m_Offset].m_Key>=_key && m_stackTop[rr.m_Offset].m_ptrLeft<0); - if(rr.m_Offset>=0 && m_stackTop[rr.m_Offset].m_Key==_key){ - // Exact match found - just replace. - m_stackTop[rr.m_Offset].m_Value = _value; - if(!SavePage(rr.m_Page,m_stackTop)) - return FALSE; - return TRUE; - } - // Split the page and propagate the split if needed.. - // Insert new element at rr.m_Offset.. - BOOL nuisnew = TRUE; - for(int sp=m_btStack.GetUpperBound();sp>=0;sp--){ - CBTPageRef opr = m_btStack[sp].m_Page; - int iAt = m_btStack[sp].m_Offset; - CBTPage op; - VERIFY(LoadPage(opr,op)); - if(iAt<0) - iAt = op.GetSize(); - else{ - if(op[iAt].m_Key nuRecord.m_Key); - } - op.InsertAt(iAt,nuRecord); - if(iAt>0) - op[iAt-1].m_ptrRight=nuRecord.m_ptrLeft; - if(iAt=0); - CBTPage np; - ASSERT(LoadPage(npr,np)); - ASSERT(!np.GetSize()); - nuRecord = op[treeOrder]; - if(iAt==treeOrder){ - // We're inserting central element! - drop out the stack top if this is still new one - for(int tmp=0;tmp=0); - CBTPage nurpa; - ASSERT(LoadPage(nuroot,nurpa)); - ASSERT(!nurpa.GetSize()); - nurpa.Add(nuRecord); - VERIFY(SavePage(nuroot,nurpa)); - m_btStack.InsertAt(0,CBTRecordRef(nuroot,0)); - m_BTCrap->m_Root = nuroot; - m_BT.Write1stBlock(); - return TRUE; - } - BOOL Delete(key& _key) { - if(!IsOpened()) - return FALSE; - ASSERT(m_BTCrap->m_bRootSet); - value _value; - if(!Lookup(_key,_value)) - return FALSE; - // Found key, check if it's a leaf - { - CBTRecordRef* rr = &m_btStack[m_btStack.GetUpperBound()]; - int rrIdx = m_btStack.GetUpperBound(); - if(m_stackTop[rr->m_Offset].m_ptrLeft>=0){ - ASSERT(m_stackTop[rr->m_Offset].m_ptrRight>=0); - // It isn't - scan for the _next_ key and do dirty deeds - m_btStack.Add(CBTRecordRef(m_stackTop[rr->m_Offset].m_ptrRight,0)); - for(;;){ - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - if(!LoadPage(rr.m_Page,m_stackTop)) - return FALSE; - if(m_stackTop[0].m_ptrLeft<0) - break; - m_btStack.Add(CBTRecordRef(m_stackTop[0].m_ptrLeft,0)); - } - // We have a leaf node here, replace victim with the first element and kill it. - CBTPage uppage; - rr = &m_btStack[rrIdx]; - if(!LoadPage(rr->m_Page,uppage)) - return FALSE; - uppage[rr->m_Offset].m_Key=m_stackTop[0].m_Key; uppage[rr->m_Offset].m_Value=m_stackTop[0].m_Value; - m_stackTop.RemoveAt(0); - if(!(SavePage(rr->m_Page,uppage) && SavePage(m_btStack[m_btStack.GetUpperBound()].m_Page,m_stackTop))) - return FALSE; - }else{ - ASSERT(m_stackTop[rr->m_Offset].m_ptrRight<0); - m_stackTop.RemoveAt(rr->m_Offset); - if(!SavePage(rr->m_Page,m_stackTop)) - return FALSE; - } - } - // We have a page to check for underflow at the top of the stack now. - for(;;){ - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - if(!LoadPage(rr.m_Page,m_stackTop)) - return FALSE; - if(m_stackTop.GetSize()>=treeOrder || m_btStack.GetSize()==1) - return TRUE; - CBTRecordRef& rr1 = m_btStack[m_btStack.GetUpperBound()-1]; - CBTPage daddy; - if(!LoadPage(rr1.m_Page,daddy)) - return FALSE; - CBTPageRef nPage = daddy[rr1.m_Offset].m_ptrRight; - BOOL bRight=TRUE; - if(nPage<0 || nPage==rr.m_Page){ - nPage = daddy[rr1.m_Offset].m_ptrLeft; - bRight = FALSE; - } - ASSERT(nPage>=0 && nPage!=rr.m_Page); - CBTPage neighbor; - if(!LoadPage(nPage,neighbor)) - return FALSE; - // Here we have possibly two cases: - // 1. Neighboring page can share some data with use, then do share and leave - // 2. Neighboring page is of treeorder in size, then merge and propagate - if(neighbor.GetSize()>treeOrder){ - TRACE0("Redistributing..\n"); - // Borrow some data from there. - int toBorrow = neighbor.GetSize()-treeOrder; - toBorrow=toBorrow/2+1; - ASSERT(toBorrow); - if(bRight) - m_stackTop.Add(CBTRecord(daddy[rr1.m_Offset].m_Key,daddy[rr1.m_Offset].m_Value,m_stackTop[m_stackTop.GetUpperBound()].m_ptrRight,neighbor[0].m_ptrLeft)); - else - m_stackTop.InsertAt(0,CBTRecord(daddy[rr1.m_Offset].m_Key,daddy[rr1.m_Offset].m_Value,neighbor[neighbor.GetUpperBound()].m_ptrRight,m_stackTop[0].m_ptrLeft)); - for(toBorrow--;toBorrow;toBorrow--){ - if(bRight){ - m_stackTop.Add(neighbor[0]); - neighbor.RemoveAt(0); - }else{ - m_stackTop.InsertAt(0,neighbor[neighbor.GetUpperBound()]); - neighbor.RemoveAt(neighbor.GetUpperBound()); - } - } - daddy[rr1.m_Offset].m_Key = neighbor[bRight?0:neighbor.GetUpperBound()].m_Key; daddy[rr1.m_Offset].m_Value = neighbor[bRight?0:neighbor.GetUpperBound()].m_Value; - neighbor.RemoveAt(bRight?0:neighbor.GetUpperBound()); - if(!(SavePage(rr1.m_Page,daddy) && SavePage(nPage,neighbor) && SavePage(rr.m_Page,m_stackTop))) - return FALSE; - rr.m_Offset = -1; // *** Point to the next?? - return TRUE; - } - TRACE0("Merging..\n"); - // We need to merge pages here.. - // We will merge them at stacktop, then we'll discard neighbor guy.. - if(bRight) - m_stackTop.Add(CBTRecord(daddy[rr1.m_Offset].m_Key,daddy[rr1.m_Offset].m_Value,m_stackTop[m_stackTop.GetUpperBound()].m_ptrRight,neighbor[0].m_ptrLeft)); - else - m_stackTop.InsertAt(0,CBTRecord(daddy[rr1.m_Offset].m_Key,daddy[rr1.m_Offset].m_Value,neighbor[neighbor.GetUpperBound()].m_ptrRight,m_stackTop[0].m_ptrLeft)); - if(bRight){ - while(neighbor.GetSize()){ - m_stackTop.Add(neighbor[0]); - neighbor.RemoveAt(0); - } - }else{ - while(neighbor.GetSize()){ - m_stackTop.InsertAt(0,neighbor[neighbor.GetUpperBound()]); - neighbor.RemoveAt(neighbor.GetUpperBound()); - } - } - if(rr1.m_Offset>0) - daddy[rr1.m_Offset-1].m_ptrRight=rr.m_Page; - if(rr1.m_Offsetm_bRootSet); - m_btStack.RemoveAll(); - m_btStack.Add(CBTRecordRef(m_BTCrap->m_Root,-1)); - for(;;){ - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - if(!LoadPage(rr.m_Page,m_stackTop)) - return FALSE; - if(!m_stackTop.GetSize()){ - ASSERT(m_btStack.GetSize()==1); - return FALSE; - } - rr.m_Offset = 0; - if(m_stackTop[rr.m_Offset].m_ptrLeft<0) - return TRUE; - m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset].m_ptrLeft,-1)); - } - } - BOOL GoLast() { - if(!IsOpened()) - return FALSE; - ASSERT(m_BTCrap->m_bRootSet); - m_btStack.RemoveAll(); - m_btStack.Add(CBTRecordRef(m_BTCrap->m_Root,-1)); - for(;;){ - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - if(!LoadPage(rr.m_Page,m_stackTop)) - return FALSE; - if(!m_stackTop.GetSize()){ - ASSERT(m_btStack.GetSize()==1); - return FALSE; - } - rr.m_Offset = m_stackTop.GetUpperBound(); - if(m_stackTop[rr.m_Offset].m_ptrRight<0) - return TRUE; - m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset++].m_ptrRight,-1)); - } - } - BOOL GoNext() { - if(!IsOpened()) - return FALSE; - if(!(m_btStack.GetSize() && m_btStack[m_btStack.GetUpperBound()].m_Offset>=0)) - return FALSE; - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - if(!LoadPage(rr.m_Page,m_stackTop)) - return FALSE; - ASSERT(rr.m_Offset=0){ - // Advance pointer in this page and dive into subtree - // going left and left until we have nowhere to go. -// TRACE1("Dive into page %lu",m_stackTop[rr.m_Offset].m_ptrRight); - m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset++].m_ptrRight,0)); - for(;;){ - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - ASSERT(rr.m_Offset==0); - if(!LoadPage(rr.m_Page,m_stackTop)) - return FALSE; - if(m_stackTop[rr.m_Offset].m_ptrLeft<0) - break; -// TRACE1(", %lu",m_stackTop[rr.m_Offset].m_ptrLeft); - m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset].m_ptrLeft,0)); - } -// TRACE0("\n"); - return TRUE; - }else if(rr.m_Offset=0)) - return FALSE; - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - if(!LoadPage(rr.m_Page,m_stackTop)) - return FALSE; - ASSERT(rr.m_Offset=0){ - // Dive in and go right and right from the rightmost until - // we have nowhere to go. - m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset].m_ptrLeft,-1)); - for(;;){ - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - if(!LoadPage(rr.m_Page,m_stackTop)) - return FALSE; - rr.m_Offset = m_stackTop.GetUpperBound(); - if(m_stackTop[rr.m_Offset].m_ptrRight<0) - return TRUE; - m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset++].m_ptrRight,-1)); - } - return TRUE; - }else if(rr.m_Offset>0){ - rr.m_Offset--; - return TRUE; - } - // We're at the leftmost element in page - go up and left until we're - // done or we have data. - m_btStack.RemoveAt(m_btStack.GetUpperBound()); - while(m_btStack.GetSize()){ - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - if(!LoadPage(rr.m_Page,m_stackTop)) - return FALSE; - rr.m_Offset--; - if(rr.m_Offset>=0) - return TRUE; - m_btStack.RemoveAt(m_btStack.GetUpperBound()); - } - // No more data - we were at the first element in tree. - return FALSE; - } - BOOL GetThis(key& _key,value& _value) { - if(!IsOpened()) - return FALSE; - // *** MORE CHECKING - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - if(!LoadPage(rr.m_Page,m_stackTop)) - return FALSE; - _key = m_stackTop[rr.m_Offset].m_Key; - _value = m_stackTop[rr.m_Offset].m_Value; - return TRUE; - } - - BOOL SeekToPage(const key& _key) { - ASSERT(IsOpened()); - ASSERT(m_BTCrap->m_bRootSet); - m_btStack.RemoveAll(); - m_btStack.Add(CBTRecordRef(m_BTCrap->m_Root,-1)); - for(;;){ - CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()]; - if(!LoadPage(rr.m_Page,m_stackTop)) - return FALSE; - ASSERT(m_stackTop.GetSize() || !m_btStack.GetUpperBound()); - if(!m_stackTop.GetSize()){ - rr.m_Offset=-1; - return TRUE; - } - for(rr.m_Offset=0;rr.m_OffsetDelete(); - rv = FALSE; - } - delete pageFile; - return rv; - } - BOOL SavePage(CBTPageRef ref,CBTPage& page) { - CFile* pageFile = m_BT.OpenFile(ref); - if(!pageFile) - return FALSE; - BOOL rv = TRUE; - try{ - CArchive ar(pageFile,CArchive::store); - page.Serialize(ar); - ar.Close(); - }catch(CException* e){ - e->Delete(); - rv = FALSE; - } - delete pageFile; - return rv; - } - CBTPageRef AllocatePage() { - CBTDynaFile* pageFile = m_BT.CreateFile(); - if(!pageFile) - return -1; - CBTPage nothing; - CBTPageRef rv = pageFile->GetFile(); - try{ - CArchive ar(pageFile,CArchive::store); - nothing.Serialize(ar); - ar.Close(); - }catch(CException* e){ - e->Delete(); - rv = -1; - } - delete pageFile; - return rv; - } - BOOL DeallocatePage(CBTPageRef ref) { - return m_BT.DeleteFile(ref); - } - -}; - -}; - -#endif // __BTREENDEX_H -- cgit v0.9.0.2