Click here to Skip to main content
15,891,734 members
Articles / Desktop Programming / MFC

Ultimate FastMaps!

Rate me:
Please Sign up or sign in to vote.
3.73/5 (7 votes)
19 Jan 2000 153.3K   1.1K   35  
A fully featured map class that uses balanced trees to store and retrieve data quickly by key
// wrdcodoc.cpp : implementation of the CWrdcountDoc class
//

#include "stdafx.h"
#include "wrdcount.h"

#include "wrdcodoc.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CWrdcountDoc

IMPLEMENT_DYNCREATE(CWrdcountDoc, CDocument)

#define new DEBUG_NEW

BEGIN_MESSAGE_MAP(CWrdcountDoc, CDocument)
    //{{AFX_MSG_MAP(CWrdcountDoc)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CWrdcountDoc construction/destruction
    
static BOOL gblAllocFail = FALSE;

CWrdcountDoc::CWrdcountDoc()
{
    m_curFile = "";
    m_parseTime = 0;
    m_totalWords = 0;
    m_prodTime = 0;
    m_prodUnique = 0;
    m_mfcTime = 0;
    m_mfcUnique = 0;
    m_baseParse = FALSE;
    m_baseParsed = FALSE;
    m_prodParse = FALSE;
    m_prodParsed = FALSE;
    m_mfcParse = FALSE;
    m_mfcParsed = FALSE;

    #ifdef USE_TEMPLATED_STREAMS
        m_tmpTime = 0;
        m_tmpUnique = 0;
        m_tmpParse = FALSE;
        m_tmpParsed = FALSE;
    #endif
}

CWrdcountDoc::~CWrdcountDoc()
{
    #ifdef USE_TEMPLATED_STREAMS
        m_tmpMap.clear();
    #endif
}

// define exit pointer type:
typedef void (*wordRtn)(const char*, void*);

// null word-exit routine for base timing test.
void null(const char* string, void* mapPtr)
{
}

// word-exit for use with CtStringToULong
void prodAdd(const char* string, void* mapPtr)
{
    CtStringToULong* tree = (CtStringToULong*)mapPtr;
    long cnt = 1;
    POSITION pos = tree->Find(string);
    if (pos)
    {
        cnt += tree->GetData(pos);
        tree->SetData(pos, cnt);
    }
    else
        gblAllocFail = !tree->Set(string, cnt);
}

// word-exit for use with CMapStringToPtr
void mfcMapAdd(const char* string, void* mapPtr)
{
    CMapStringToPtr* map = (CMapStringToPtr*)mapPtr;
    long cnt;
    if (!map->Lookup(string, (void*&)cnt))
        cnt = 0;
    cnt++;
    map->SetAt(string, (void*)cnt);
}

#ifdef USE_TEMPLATED_STREAMS
    // word-exit for use with TemplStrToInt
    void tmpMapAdd(const char* string, void* mapPtr)
    {
        TemplStrToInt* map = (TemplStrToInt*)mapPtr;
        TemplStrToInt::iterator pos;
        pos = map->find(string);
        if (pos != map->end())
            (*pos).second += 1;
        else
            map->insert(TemplStrToInt::value_type(string, 1));
    }
#endif

// parse and call exit for each word; a word is any series
// of alphanumeric characters starting with an alpha and
// delimited by anything not alphanumeric, and less than 256
// bytes in length.
long parse(NQ ifstream* strm, wordRtn exit, void* mapPtr, long& total)
{
    strm->clear();
    strm->seekg(0);
    long start = ::GetTickCount();
    char word[256] = "";
    int ix = 0;
    char c;
    while (strm->good())
    {
        c = strm->get();
        if (ix == 0 && !isalpha(c))
            continue;
        if (ix < sizeof(word)-1 && isalnum(c))
            word[ix++] = c;
        else if (ix)
        {
            word[ix] = 0;
            exit(word, mapPtr);
            if (gblAllocFail)
                return 0;
            total++;
            ix = 0;
        }
    }
    return ::GetTickCount() - start;
}

BOOL CWrdcountDoc::OnOpenDocument( const char* pszPathName )
{
    gblAllocFail = FALSE;
    if (m_strm.is_open())
    {
        m_strm.close();
        m_strm.clear();
    }
    m_curFile = "";
    m_strm.open(pszPathName);
    if (!m_strm.is_open())
    {
        AfxMessageBox("Open failed for specified file.");
        return FALSE;
    }
    if (!m_strm.good())
    {
        AfxMessageBox("Open succeeded but flags did not clear.");
        return FALSE;
    }
    m_curFile = pszPathName;
    m_baseParse = FALSE;
    m_baseParsed = FALSE;
    m_prodParse = FALSE;
    m_prodParsed = FALSE;
    m_mfcParse = FALSE;
    m_mfcParsed = FALSE;

    #ifdef USE_TEMPLATED_STREAMS
        m_tmpParse = FALSE;
        m_tmpParsed = FALSE;
    #endif
    
    // compute "base", time for just the parsing.
    m_parseTime = 0;
    m_totalWords = 0;
    m_baseParse = TRUE;
    UpdateAllViews(0);
    m_parseTime = parse(&m_strm, null, 0, m_totalWords);
    m_baseParse = FALSE;
    m_baseParsed = TRUE;
    UpdateAllViews(0);
    
    // compute time to count using CtStringToULong
    long dummy;
    m_prodParse = TRUE;
    UpdateAllViews(0);
    m_fastMap.RemoveAll();
    m_prodTime = parse(&m_strm, prodAdd, &m_fastMap, dummy);
    m_prodTime -= m_parseTime;
	if(0 > m_prodTime)
		m_prodTime = 0;
    m_prodUnique = m_fastMap.GetCount();
    m_prodParse = FALSE;
    if (gblAllocFail)
    {
        m_fastMap.RemoveAll();
        UpdateAllViews(0);
        AfxMessageBox("Storage allocation failure ( CtStringToULong ), try a smaller file.");
        return FALSE;
    }
    m_prodParsed = TRUE;
    UpdateAllViews(0);
    
    // compute time to count using CMapStringToPtr
    m_mfcParse = TRUE;
    UpdateAllViews(0);
    m_mfcMap.RemoveAll();
    TRY
    {
        m_mfcTime = parse(&m_strm, mfcMapAdd, &m_mfcMap, dummy);
    }
    CATCH (CMemoryException, e)
    {
        gblAllocFail = TRUE;
    }
    END_CATCH
    m_mfcTime -= m_parseTime;
	if(0 > m_mfcTime)
		m_mfcTime = 0;
    m_mfcUnique = m_mfcMap.GetCount();
    m_mfcParse = FALSE;
    if (gblAllocFail)
    {
        m_mfcMap.RemoveAll();
        UpdateAllViews(0);
        AfxMessageBox("Storage allocation failure ( CMapStringToPtr ), try a smaller file.");
        return FALSE;
    }
    m_mfcParsed = TRUE;
    UpdateAllViews(0);

    #ifdef USE_TEMPLATED_STREAMS
        // compute time to count using TemplStrToInt
        m_tmpParse = TRUE;
        UpdateAllViews(0);
        m_tmpMap.clear();
        TRY
        {
            m_tmpTime = parse(&m_strm, tmpMapAdd, &m_tmpMap, dummy);
        }
        CATCH (CMemoryException, e)
        {
            gblAllocFail = TRUE;
        }
        END_CATCH
        m_tmpTime -= m_parseTime;
		if(0 > m_tmpTime)
			m_tmpTime = 0;
        m_tmpUnique = m_tmpMap.size();
        m_tmpParse = FALSE;
        if (gblAllocFail)
        {
            m_tmpMap.clear();
            UpdateAllViews(0);
            AfxMessageBox("Storage allocation failure ( STL map<string,int> ), try a smaller file.");
            return FALSE;
        }
        m_tmpParsed = TRUE;
        UpdateAllViews(0);
    #endif
    
    return TRUE;
}

void CWrdcountDoc::OnCloseDocument( )
{
    if (m_strm.is_open())
        m_strm.close();
    m_curFile = "";
    SetModifiedFlag(FALSE);
    CDocument::OnCloseDocument();
}

/////////////////////////////////////////////////////////////////////////////
// CWrdcountDoc serialization

void CWrdcountDoc::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
    }
    else
    {
    }
}

/////////////////////////////////////////////////////////////////////////////
// CWrdcountDoc diagnostics

#ifdef _DEBUG
void CWrdcountDoc::AssertValid() const
{
    CDocument::AssertValid();
}

void CWrdcountDoc::Dump(CDumpContext& dc) const
{
    CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CWrdcountDoc commands

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
Since 1992 Dundas Data Visualization has been helping companies all over the world visualize their data. Dundas products have a global reputation of being the highest quality, and are all designed, built and tested to meet the strictest requirements that developers and business managers demand.

Our showcase product is Dundas Dashboard, an easy-to-integrate digital dashboard software solution. Dundas Dashboard allows for the rapid and collaborative development of performance dashboards, helping companies leverage their business intelligence (BI) solutions.

Our web-based dashboard software comes with wizard interfaces, and a unique Dundas DashFlowTM process, allowing for the simultaneous development of an executive dashboard by business analysts, IT staff and database administrators. It also uses premier charts, maps, gauges and graph controls, letting end-users visualize their data as required.

Dundas also offers superb, world class consulting services for those companies that do not have the in-house expertise to implement their data visualization projects.

The quality of our products in conjunction with our unmatched technical support, numerous awards and years of experience reflect Dundas Data Visualization's commitment to being the best!
This is a Organisation

3 members

Comments and Discussions