⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hashtable.c

📁 labwindow 编程的toolbox例程。
💻 C
📖 第 1 页 / 共 2 页
字号:
//-------------------------------------------------------------------------------------------------
// National Instruments - LabWindows/CVI
// New for version 8.5
//
// This example demonstrates how to use the Hash Table API found in the Programmer's Toolbox. 
// It allows you to create hash tables with various key and value types. As you add/remove 
// key-value pairs, you can monitor the table size, load, and item distribution throughout the
// buckets. An intensity graph provides a visual indicator of how the hash function distributes
// the keys throughout the buckets. You can also see how the resize policy affects the table's
// size and load as elements are added or removed.
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// Include files
//-------------------------------------------------------------------------------------------------
#include <cvirte.h>     
#include <userint.h>
#include <toolbox.h>
#include "hashtable.h"

//-------------------------------------------------------------------------------------------------
// Macros
//-------------------------------------------------------------------------------------------------
#ifdef errChk
#undef errChk
#endif
#define errChk(fCall) do { if ((error = (fCall)) < 0) goto Error; } while (0)
#define handleError do { if (error < 0 && error != kErrorAlreadyHandled) { MessagePopup("Error", GetGeneralErrorString(error)); error = kErrorAlreadyHandled; } } while (0)

//-------------------------------------------------------------------------------------------------
// Constants
//-------------------------------------------------------------------------------------------------
static const unsigned int   kExpectedOccupancy      = 10;
static const int            kErrorAlreadyHandled    = UIEErrorLimit - 1;

//-------------------------------------------------------------------------------------------------
// Global variables
//-------------------------------------------------------------------------------------------------
static int                  gPanel;
static HashTableType        gHashTable          = NULL;
static int                  gKeyType,
                            gValType,
                            gKeySize,
                            gValSize;
static ColorMapEntry        gColorMap[2];

//-------------------------------------------------------------------------------------------------
// Forward declarations
//-------------------------------------------------------------------------------------------------
static int SetKeyAndValueGlobals(void);
static int UpdateDistributionGraph(void);
static int UpdateCtrlDimming(void);
static int UpdateCtrlsAccordingToTableDefaults(void);
static int UpdateCtrlsAccordingToKeyValueTypes(void);
static int GetKeyFromCtrl(void **key);
static int GetValueFromCtrl(void **val);

//-------------------------------------------------------------------------------------------------
// Module entry-point
//-------------------------------------------------------------------------------------------------
int main (int argc, char *argv[])
{
    if (InitCVIRTE (0, argv, 0) == 0)
        return -1;  /* out of memory */
    if ((gPanel = LoadPanel (0, "hashtable.uir", PANEL)) < 0)
        return -1;
    DisplayPanel (gPanel);
    RunUserInterface ();
    DiscardPanel (gPanel);
    return 0;
}

/// HIFN    Callback function for the "Create" button
int CVICALLBACK CreateTable (int gPanel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    int error   = 0;
    
    switch (event)
    {
        case EVENT_COMMIT:
            errChk (SetKeyAndValueGlobals());
            
            errChk (HashTableCreate(kExpectedOccupancy,
                                    (gKeyType == VAL_STRING) ? C_STRING_KEY : FIXED_SIZE_KEY,
                                    gKeySize,
                                    gValSize,
                                    &gHashTable));
            
            errChk (UpdateCtrlsAccordingToTableDefaults());
            errChk (UpdateCtrlsAccordingToKeyValueTypes());
            errChk (UpdateCtrlDimming());
            break;
    }
Error:
    handleError;
    return 0;
}

/// HIFN    Callback function for the "Dispose" button
int CVICALLBACK DisposeTable (int gPanel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    int error   = 0;
    
    switch (event)
    {
        case EVENT_COMMIT:
            errChk (HashTableDispose(gHashTable));
            gHashTable = NULL;
            errChk (UpdateCtrlDimming());
            break;
    }
Error:
    handleError;
    return 0;
}

/// HIFN    Callback function for the "Insert" button
int CVICALLBACK Insert (int gPanel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    int             error       = 0;
    void            *key        = NULL,
                    *value      = NULL;
    unsigned int    size,
                    buckets;
    double          load;
                
    switch (event)
    {
        case EVENT_COMMIT:
            errChk (GetKeyFromCtrl(&key));
            errChk (GetValueFromCtrl(&value));
            errChk (HashTableInsertItem(gHashTable, key, value));
            errChk (HashTableGetAttribute(gHashTable, ATTR_HT_SIZE,         &size));
            errChk (HashTableGetAttribute(gHashTable, ATTR_HT_NUM_BUCKETS,  &buckets));
            errChk (HashTableGetAttribute(gHashTable, ATTR_HT_LOAD,         &load));
            errChk (SetCtrlVal(gPanel, PANEL_SIZE,      size));
            errChk (SetCtrlVal(gPanel, PANEL_BUCKETS,   buckets));
            errChk (SetCtrlVal(gPanel, PANEL_LOAD,      load));
            errChk (UpdateDistributionGraph());
            break;
    }
Error:
    if (key)
        free(key);
    if (value)
        free(value);
    handleError;
    return 0;
}

/// HIFN    Callback function for the "Remove" button
int CVICALLBACK Remove (int gPanel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    int             error       = 0;
    void            *key        = NULL;
    unsigned int    size,
                    buckets;
    double          load;
                
    switch (event)
    {
        case EVENT_COMMIT:
            errChk (GetKeyFromCtrl(&key));
            errChk (HashTableRemoveItem(gHashTable, key, NULL, 0));
            errChk (HashTableGetAttribute(gHashTable, ATTR_HT_SIZE,         &size));
            errChk (HashTableGetAttribute(gHashTable, ATTR_HT_NUM_BUCKETS,  &buckets));
            errChk (HashTableGetAttribute(gHashTable, ATTR_HT_LOAD,         &load));
            errChk (SetCtrlVal(gPanel, PANEL_SIZE,      size));
            errChk (SetCtrlVal(gPanel, PANEL_BUCKETS,   buckets));
            errChk (SetCtrlVal(gPanel, PANEL_LOAD,      load));
            errChk (UpdateDistributionGraph());
            break;
    }
Error:
    if (key)
        free(key);
    handleError;
    return 0;
}

/// HIFN    Callback function for the "Find" button
int CVICALLBACK Find (int gPanel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    int         error           = 0,
                found;
    void        *key            = NULL;
    
    switch (event)
    {
        case EVENT_COMMIT:
            errChk (GetKeyFromCtrl(&key));
            errChk (HashTableFindItem(gHashTable, key, &found));
            MessagePopup("Find Key", found ? "Found" : "Not Found");
            break;
    }
Error:
    if (key)
        free(key);
    handleError;
    return 0;
}

/// HIFN    Callback function for the "Enumerate Table Contents" button
int CVICALLBACK Enumerate (int gPanel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    int                 error       = 0;
    HashTableIterator   iter;
    void                *key        = NULL,
                        *value      = NULL;
    char                *stringKey  = NULL,
                        numericKey[8];
    unsigned int        i,
                    size;
    
    switch (event)
    {
        case EVENT_COMMIT:
            // Hide the control to unnecessary draws and flickering
            errChk (SetCtrlAttribute(gPanel, PANEL_ENUM_TABLE, ATTR_VISIBLE, 0));
            
            errChk (DeleteTableRows(gPanel, PANEL_ENUM_TABLE, 1, -1));
            errChk (HashTableGetAttribute(gHashTable, ATTR_HT_SIZE, &size));
            errChk (InsertTableRows(gPanel, PANEL_ENUM_TABLE, -1, size, VAL_USE_MASTER_CELL_TYPE));
            
            if (gKeyType != VAL_STRING)
            {
                nullChk (key = malloc(gKeySize));
                size = gKeySize;
            }
            nullChk (value = malloc(gValSize));
            
            for (error = HashTableIteratorCreate(gHashTable, &iter), i = 1;
                 error >= 0 && error != HASH_TABLE_END;
                 error = HashTableIteratorAdvance(gHashTable, iter), ++i)
            {
                if (gKeyType == VAL_STRING)
                {
                    if (key)
                        free(key);
                    errChk (size = HashTableIteratorGetItem(gHashTable, iter, NULL, 0, NULL, 0));
                    nullChk (key = malloc(size));
                }
                errChk (HashTableIteratorGetItem(gHashTable, iter, key, size, value, gValSize));
                
                switch (gKeyType)
                {
                    case VAL_STRING:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(1, i), ATTR_CTRL_VAL, (char *)key));
                        break;
                    case VAL_CHAR:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(1, i), ATTR_CTRL_VAL, *(char *)key));
                        break;
                    case VAL_UNSIGNED_CHAR:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(1, i), ATTR_CTRL_VAL, *(unsigned char *)key));
                        break;
                    case VAL_INTEGER:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(1, i), ATTR_CTRL_VAL, *(int *)key));
                        break;
                    case VAL_UNSIGNED_INTEGER:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(1, i), ATTR_CTRL_VAL, *(unsigned int *)key));
                        break;
                    case VAL_64BIT_INTEGER:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(1, i), ATTR_CTRL_VAL, *(__int64 *)key));
                        break;
                    case VAL_UNSIGNED_64BIT_INTEGER:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(1, i), ATTR_CTRL_VAL, *(unsigned __int64 *)key));
                        break;
                    case VAL_FLOAT:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(1, i), ATTR_CTRL_VAL, *(float *)key));
                        break;
                    case VAL_DOUBLE:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(1, i), ATTR_CTRL_VAL, *(double *)key));
                        break;
                }
                switch (gValType)
                {
                    case VAL_STRING:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(2, i), ATTR_CTRL_VAL, (char *)value));
                        break;
                    case VAL_CHAR:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(2, i), ATTR_CTRL_VAL, *(char *)value));
                        break;
                    case VAL_UNSIGNED_CHAR:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(2, i), ATTR_CTRL_VAL, *(unsigned char *)value));
                        break;
                    case VAL_INTEGER:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(2, i), ATTR_CTRL_VAL, *(int *)value));
                        break;
                    case VAL_UNSIGNED_INTEGER:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(2, i), ATTR_CTRL_VAL, *(unsigned int *)value));
                        break;
                    case VAL_64BIT_INTEGER:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(2, i), ATTR_CTRL_VAL, *(__int64 *)value));
                        break;
                    case VAL_UNSIGNED_64BIT_INTEGER:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(2, i), ATTR_CTRL_VAL, *(unsigned __int64 *)value));
                        break;
                    case VAL_FLOAT:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(2, i), ATTR_CTRL_VAL, *(float *)value));
                        break;
                    case VAL_DOUBLE:
                        errChk (SetTableCellAttribute(gPanel, PANEL_ENUM_TABLE, MakePoint(2, i), ATTR_CTRL_VAL, *(double *)value));
                        break;
                }
            }
            HashTableIteratorDispose(gHashTable, iter);
            break;
    }
Error:
    if (event == EVENT_COMMIT)
        SetCtrlAttribute(gPanel, PANEL_ENUM_TABLE, ATTR_VISIBLE, 1);
    handleError;
    return 0;
}

/// HIFN    Callback function for the grow policy checkbox
int CVICALLBACK ToggleGrowLoad (int gPanel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    int     error   = 0,
            enable;
    double  load;
                
    switch (event)
    {
        case EVENT_COMMIT:
            errChk (GetCtrlVal(gPanel, PANEL_GROW_ENABLE, &enable));
            if (enable)
            {
                errChk (GetCtrlVal(gPanel, PANEL_GROW_LOAD, &load));
            }
            else
            {
                load = VAL_DO_NOT_GROW;
            }
            errChk (HashTableSetAttribute(gHashTable, ATTR_HT_GROW_LOAD, load));
            errChk (SetCtrlAttribute(gPanel, PANEL_GROW_LOAD, ATTR_DIMMED, !enable));
            errChk (UpdateDistributionGraph());
            break;
    }
Error:
    handleError;
    return 0;
}

/// HIFN    Callback function for the shrink policy checkbox
int CVICALLBACK ToggleShrinkLoad (int gPanel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    int     error   = 0,
            enable;
    double  load;
                
    switch (event)
    {
        case EVENT_COMMIT:
            errChk (GetCtrlVal(gPanel, PANEL_SHRINK_ENABLE, &enable));
            if (enable)
            {
                errChk (GetCtrlVal(gPanel, PANEL_SHRINK_LOAD, &load));
            }
            else
            {
                load = VAL_DO_NOT_SHRINK;
            }
            errChk (HashTableSetAttribute(gHashTable, ATTR_HT_SHRINK_LOAD, load));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -