[llvm-commits] [test-suite] r46435 [4/4] - /test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/
Chris Lattner
sabre at nondot.org
Sun Jan 27 21:23:40 PST 2008
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/delete.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/delete.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/delete.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/delete.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,140 @@
+
+/*
+ * Name: delete
+ * Input: root node of index, root
+ * search index key, searchKey
+ * search non-key list, searchNonKey
+ * Output: updated node, node
+ * Return: DELETE_SUCCESS, or
+ * DELETE_INVALID_KEY_SEARCH_VALUE,
+ * DELETE_INVALID_NON_KEY_SEARCH_VALUE
+ * Description: The routine searches the current index and removes all data
+ * objects which are consistent with the search input values,
+ * key and non-key. The routine makes use of the recursive
+ * routine deleteEntry() to perform the actual search and
+ * removal of data objects in the index. The deleteEntry()
+ * routine will also remove empty nodes from the index all the
+ * way up to the root node. After the return from
+ * deleteEntry(), two checks need to be made. The first checks
+ * to see if the current root node level is not a LEAF and the
+ * list of entries for the root node is empty, i.e., NULL.
+ * This case indicates that the input search values completely
+ * removed every data object in the index and thus all nodes
+ * except the root node. For this case, the level for the root
+ * is reset to the LEAF level and the updated root node is
+ * returned. The second case checks to see if the root node
+ * has only one entry in its list. The R-Tree is required to
+ * replace any root node with only one child with the child
+ * node, unless the root is a LEAF node.
+ * Calls: deleteEntry()
+ * errorMessage()
+ * validIndexKey()
+ * validAttributes()
+ * System: free()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for free() and NULL definitions */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "dataObject.h" /* for DataAttribute definition */
+#include "index.h" /* for IndexNode and IndexEntry definitions */
+#include "indexKey.h" /* for IndexKey definition */
+#include "delete.h" /* for delete() return codes */
+
+/*
+ * Function prototypes
+ */
+extern Boolean validIndexKey( IndexKey *key );
+extern Boolean validAttributes( DataAttribute *attributes );
+extern void deleteEntry( IndexNode *node, IndexKey *searchKey,
+ DataAttribute *searchNonKey, Boolean *adjustmentFlag );
+
+Int delete( IndexNode **root, /* root node of index */
+ IndexKey *searchKey, /* index key search values */
+ DataAttribute *searchNonKey ) /* non-key search values */
+{ /* beginning of delete() */
+ Boolean adjustmentFlag; /* place-holder for deleteEntry routine */
+
+ static Char name[] = "delete";
+
+ assert( root );
+ assert( *root );
+ assert( searchKey );
+ assert( LEAF >= 0 );
+
+ /*
+ * Check validity of search values
+ */
+ if ( validIndexKey( searchKey ) == FALSE ) {
+ errorMessage( "invalid index key search values", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( DELETE_INVALID_KEY_SEARCH_VALUE );
+ } /* end validity check of key values */
+ else if ( validAttributes( searchNonKey ) == FALSE ) {
+ errorMessage( "invalid non-key search values", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( DELETE_INVALID_NON_KEY_SEARCH_VALUE );
+ } /* end validity check of non-key values */
+
+ /*
+ * Call deleteEntry routine for root node which will recursively process
+ * the entire index. Note that the adjustment flag is passed to
+ * deleteEntry but its not needed for the root node since adjustments would
+ * be made to the parent which the root node does not have.
+ */
+ deleteEntry( *root, searchKey, searchNonKey, &adjustmentFlag );
+
+ /*
+ * Check case where level of the root node is not LEAF and there are no
+ * entries residing on root node, i.e., entries == NULL. This indicates
+ * that the input search values completely removed all of the data objects
+ * referenced by the index, which will also remove all index nodes and
+ * entries in the index except for the root node. Because there are no
+ * more objects in the index, simply set the current level of the root node
+ * to be the LEAF level and continue.
+ */
+ if ( (*root)->level > LEAF && (*root)->entries == NULL ) {
+ (*root)->level = LEAF;
+ }
+
+ /*
+ * If there is at least one entry on the current root node (root->entries
+ * != NULL), but there is only one entry ((root->entries)->next == NULL),
+ * then replace the root node with the only child unless the root node is a
+ * LEAF node. This behavior is required by the R-Tree definition. The old
+ * root node is deleted, but the entries is first set to EMPTY/NULL. This
+ * prevents the deleteIndexNode() routine from removing the child entry
+ * which has become the new root.
+ */
+ while ( (*root)->level != LEAF && /* current root not LEAF */
+ (*root)->entries != NULL && /* at least one child entry */
+ ((*root)->entries)->next == NULL ) { /* only one child entry */
+ IndexNode *temp; /* placeholder for old root to delete */
+
+ temp = (*root); /* save old root for removal */
+ *root = ((*root)->entries)->child.node; /* replace root with child */
+ /* which is referenced by */
+ /* entries */
+ free( temp->entries ); /* delete old entry which */
+ /* referenced old root's */
+ /* child which is now the */
+ /* new root. */
+ temp->entries = NULL; /* Need to set the value to */
+ /* NULL which will prevent */
+ /* the next step from */
+ /* deleting the entire index */
+ deleteIndexNode( temp ); /* delete old root node */
+ } /* end of loop for checking number of entries <= 1 */
+
+ return ( DELETE_SUCCESS );
+} /* end delete() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/delete.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/delete.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/delete.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/delete.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,42 @@
+
+/*
+ * DIS Data Management: delete
+ *
+ * This header file contains the return codes for the delete routine
+ * and the function prototype. There are two different failure modes for
+ * the routine. The first indicates that the search index key passed as
+ * input to the routine is invalid. The second indicates that the
+ * attribute code specifying which non-key attribute to search on is
+ * invalid (too small or too large).
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_DELETE_H
+#define DIS_DELETE_H
+
+#include "dataObject.h" /* for DataAttribute definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "index.h" /* for IndexNode definition */
+#include "indexKey.h" /* for IndexKey definition */
+
+/*
+ * Return Codes
+ */
+#define DELETE_SUCCESS 0
+#define DELETE_INVALID_KEY_SEARCH_VALUE 1
+#define DELETE_INVALID_NON_KEY_SEARCH_VALUE 2
+
+/*
+ * Function prototype
+ */
+extern Int delete( IndexNode **root, IndexKey *searchKey,
+ DataAttribute *searchNonKey );
+
+#endif /* DIS_DELETE_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteDataObject.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteDataObject.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteDataObject.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteDataObject.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,78 @@
+
+/*
+ * Name: deleteDataObject
+ * Input: DataObject to delete
+ * Output: none
+ * Return: void
+ * Description: Routine deletes given data object, including all non-key
+ * character sequences.
+ * Calls:
+ * System: assert()
+ * free()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ * 23Jun99 Matthew Rivas Added initializer to numberOfAttributes to prevent
+ * warning message during compilation
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for free() and NULL definitions */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "dataObject.h" /* for DataObject and DataObjectType definitions */
+
+void deleteDataObject( DataObject * dataObject ) /* object to delete */
+{ /* beginning of deleteDataObject() */
+ Int i; /* looping index for attributes */
+ Int numberOfAttributes; /* number of attributes specified by object type */
+
+ assert( dataObject );
+ assert( !( dataObject->type != SMALL && \
+ dataObject->type != MEDIUM && \
+ dataObject->type != LARGE ) );
+ assert( MIN_ATTRIBUTE_CODE < NUM_OF_KEY_ATTRIBUTES );
+ assert( MIN_ATTRIBUTE_CODE < MAX_ATTRIBUTE_CODE );
+ assert( MAX_ATTRIBUTE_CODE < NUM_OF_LARGE_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_SMALL_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_MEDIUM_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_LARGE_ATTRIBUTES );
+
+ /*
+ * Determine number of attributes to delete based on type
+ */
+ numberOfAttributes = 0;
+ if ( dataObject->type == SMALL ) {
+ numberOfAttributes = NUM_OF_SMALL_ATTRIBUTES;
+ } /* end if ( dataObjectType == SMALL ) */
+ else if ( dataObject->type == MEDIUM ) {
+ numberOfAttributes = NUM_OF_MEDIUM_ATTRIBUTES;
+ } /* end if ( dataObjectType == MEDIUM ) */
+ else if ( dataObject->type == LARGE ) {
+ numberOfAttributes = NUM_OF_LARGE_ATTRIBUTES;
+ } /* end if ( dataObjectType == LARGE ) */
+
+ /*
+ * Delete the object's non-key attribute values. The number of values is
+ * based on the data object type.
+ */
+ for ( i = NUM_OF_KEY_ATTRIBUTES; i < numberOfAttributes; i++ ) {
+ if ( dataObject->attributes[ i ].value.nonKey != NULL ) {
+ free( dataObject->attributes[ i ].value.nonKey );
+ } /* end of if ( dataObject->attributes[ i ].nonKey != NULL ) */
+ } /* end of loop for i */
+
+ /*
+ * Delete data object
+ */
+ free( dataObject->attributes );
+ free( dataObject );
+ dataObject = NULL;
+
+ return;
+} /* end of deleteDataObject() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteEntry.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteEntry.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteEntry.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteEntry.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,271 @@
+
+/*
+ * Name: deleteEntry
+ * Input: node of index, node
+ * search index key, searchKey
+ * search non-key list, searchNonKey
+ * Output: update index node, node
+ * boolean key adjustment flag, adjustmentFlag
+ * Return: void
+ * Description: The routine recursively descends index on each branch which
+ * is consistent with the input search key values. At the leaf
+ * level, the routine removes all data objects which are
+ * consistent with both the input search key and non-key
+ * values. The routine also removes empty nodes from the
+ * index. The search over the index is performed in the same
+ * manner as the query() routine which checks only the key
+ * values for entries/branches at non-leaf nodes and both key
+ * and non-key values for leaf nodes. An adjustment flag is
+ * used to tell upper level nodes that a change has occurred in
+ * lower nodes. If the flag is not set on return, no change
+ * occurred, i.e., no data objects or nodes removed, and no
+ * adjustments for the key or entry list need to be made. If
+ * the flag is set on return, a change did occur and either the
+ * index key needs to be changed or the node may need to be
+ * removed.
+ * Calls: consistentKey()
+ * consistentNonKey()
+ * deleteEntry()
+ * deleteIndexEntry()
+ * keysUnion()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for free() and NULL definitions */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "dataObject.h" /* for DataAttribute definition */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "index.h" /* for IndexNode and IndexEntry definitions */
+#include "indexKey.h" /* for IndexKey definition */
+
+/*
+ * Function prototypes
+ */
+extern Boolean consistentKey( IndexKey *A, IndexKey *B );
+extern Boolean consistentNonKey( Char *A, Char *B );
+extern void keysUnion( IndexEntry *I, IndexKey *U );
+
+void deleteEntry( IndexNode *node, /* current node of index */
+ IndexKey *searchKey, /* index key search values */
+ DataAttribute *searchNonKey, /* non-key search values */
+ Boolean *adjustmentFlag ) /* flag to adjust keys */
+{ /* beginning of deleteEntry() */
+
+ assert( node );
+ assert( searchKey );
+ assert( adjustmentFlag );
+
+ /*
+ * Set key adjustment flag to FALSE until adjustment is necessary through a
+ * delete or return flag.
+ */
+ *adjustmentFlag = FALSE;
+
+ /*
+ * The routine is applied recursively so the current node may or may not be
+ * a leaf node. If it is a leaf node, the child referenced by the entries
+ * residing on the node are data objects. If it is not a leaf node, the
+ * child referenced by the entries are other nodes. So if the current
+ * level is not a leaf, recursively call the deleteEntry routine on each
+ * consistent entry.
+ */
+ if ( node->level > LEAF ) {
+ IndexEntry *entry; /* temp entry for looping through list */
+ IndexEntry *prevEntry; /* previous entry for re-linking after delete */
+
+ /*
+ * Loop through each entry on current node and call deleteEntry() for
+ * each consistent child node. Note that only the key values are
+ * available for consistency checks at any level greater than the LEAF
+ * level.
+ */
+ prevEntry = NULL; /* no previous entry for head of list */
+ entry = node->entries; /* set current entry to head of list */
+ while ( entry != NULL ) { /* loop through entries */
+ if ( consistentKey( &entry->key, searchKey ) == TRUE ) {
+ Boolean tempAdjustFlag; /* flag to indicate adjustment in */
+ /* child node */
+
+ deleteEntry( entry->child.node, searchKey, searchNonKey,
+ &tempAdjustFlag );
+
+ /*
+ * After a return from the recursive deleteEntry call, the
+ * index beneath this node is in one of three states: (1) No
+ * entries were removed, thus no key adjustment is required,
+ * (2) Some entries of the node were removed, but some are left
+ * so need a key adjustment, and (3) All entries of the node
+ * were removed, so no key adjustment (adjust what?) and
+ * remove the entry (which also removes the empty node). The
+ * first condition (1) does not cause any actions so there is
+ * no check. The second(2) and third(3) conditions do require
+ * actions, so they are checked and appropriate actions taken.
+ */
+ if ( (entry->child.node)->entries == NULL ) { /* (3) */
+ IndexEntry *nextEntry; /* temp storage for delete */
+
+ nextEntry = entry->next; /* save entry for re-linking */
+ deleteIndexEntry( entry, /* delete current entry */
+ node->level );
+ entry = nextEntry; /* reset current entry */
+
+ *adjustmentFlag = TRUE; /* set adjustment flag */
+
+ /*
+ * If the deleted entry was not the head of the list, need
+ * to re-link the list, so set the prevEntry's next pointer
+ * to current entry. If the deleted entry was the head of
+ * the list, set the node->entries field to the current
+ * entry. This allows the list to show as EMPTY if
+ * necessary on return.
+ */
+ if ( prevEntry != NULL ) {
+ prevEntry->next = entry;
+ } /* end of if prevEntry != NULL */
+ else {
+ node->entries = entry;
+ } /* end of if prevEntry == NULL */
+ } /* end of if entry->child.node.entries == NULL */
+ else if ( tempAdjustFlag == TRUE ) { /* (2) */
+ keysUnion( (entry->child.node)->entries, &(entry->key) );
+ *adjustmentFlag = TRUE; /* set adjustment flag */
+
+ /*
+ * Loop to next entry and set previous entry.
+ */
+ prevEntry = entry;
+ entry = entry->next;
+ } /* end of tempAdjustFlag == TRUE */
+ else {
+ /*
+ * Loop to next entry and set previous entry.
+ */
+ prevEntry = entry;
+ entry = entry->next;
+ } /* end of tempAdjustFlag == TRUE */
+ } /* end of branch which is consistent */
+ else {
+ /*
+ * Loop to next entry and set previous entry.
+ */
+ prevEntry = entry;
+ entry = entry->next;
+ } /* end of branch which is not consistent */
+ } /* end of loop for entry */
+ } /* end of if ( node->level > LEAF ) */
+ else {
+ IndexEntry *entry; /* temp entry for looping through list */
+ IndexEntry *prevEntry; /* previous entry for re-linking after delete */
+
+ /*
+ * Loop through each entry on current LEAF node and delete each data
+ * object/entry which is consistent with the input search values. The
+ * first consistency check is made on the key value. If the key values
+ * are consistent, then the data object is checked for its non-key
+ * values. A temporary upperBound value is set to prevent out-of-range
+ * checks on the three types of data objects.
+ */
+ prevEntry = NULL; /* no previous entry for head of list */
+ entry = node->entries; /* set current entry to head of list */
+ while ( entry != NULL ) { /* loop through entries */
+ if ( consistentKey( &entry->key, searchKey ) == TRUE ) {
+ DataAttribute *temp; /* attribute for list loop */
+ DataObject *object; /* allows easier reading */
+ Int upperBound; /* prevents out-of-range */
+ Boolean acceptanceFlag; /* flag to output object */
+
+ object = entry->child.dataObject; /* convenience */
+
+ upperBound = 0; /* set upperBound */
+ if ( object->type == SMALL ) { /* to prevent */
+ upperBound = NUM_OF_SMALL_ATTRIBUTES; /* out-of-range */
+ } /* end of type == SMALL */ /* errors when */
+ else if ( object->type == MEDIUM ) { /* checking non- */
+ upperBound = NUM_OF_MEDIUM_ATTRIBUTES; /* key attributes */
+ } /* end of type == MEDIUM */
+ else if ( object->type == LARGE ) {
+ upperBound = NUM_OF_LARGE_ATTRIBUTES;
+ } /* end of type == LARGE */
+
+ /*
+ * The loop checks each value of the non-key search list and
+ * compares that value for that specific attribute code to the
+ * value stored in the data object. If all of the attributes
+ * are consistent, the flag is set to TRUE at the end of the
+ * loop. If any of the attributes are not consistent, the flag
+ * is set to FALSE and the loop exits and the next entry is
+ * checked.
+ */
+ acceptanceFlag = TRUE;
+ temp = searchNonKey;
+ while ( temp != NULL && acceptanceFlag == TRUE ) {
+ if ( temp->code < upperBound ) {
+ acceptanceFlag = consistentNonKey(
+ object->attributes[ temp->code ].value.nonKey,
+ temp->attribute.value.nonKey );
+ } /* end of code < upperBound */
+ temp = temp->next;
+ } /* end of loop through non-key search value list */
+
+ /*
+ * If the acceptance flag is set, the data object should be
+ * removed. If a data object is removed, the adjustment flag is
+ * set which notifies the routine calling deleteEntry() for
+ * this node that something happened at this level which causes
+ * a node removal or key adjustment. Care must be taken to
+ * properly re-link the node.entries list.
+ */
+ if ( acceptanceFlag == FALSE ) {
+ /*
+ * Loop to next entry and set previous entry.
+ */
+ prevEntry = entry;
+ entry = entry->next;
+ } /* end of acceptanceFlag == TRUE */
+ else {
+ IndexEntry *nextEntry; /* next entry in list */
+
+ nextEntry = entry->next; /* save entry for re-linking */
+ deleteIndexEntry( entry, /* delete current entry */
+ LEAF );
+ entry = nextEntry; /* reset current entry */
+ *adjustmentFlag = TRUE; /* set adjustment flag */
+
+ /*
+ * If the deleted entry was not the head of the list, need
+ * to re-link the list, so set the prevEntry's next pointer
+ * to current entry. If the deleted entry was the head of
+ * the list, set the node->entries field to the current
+ * entry. This allows the list to show as EMPTY if
+ * necessary on return.
+ */
+ if ( prevEntry != NULL ) {
+ prevEntry->next = entry;
+ } /* end of if prevEntry != NULL */
+ else {
+ node->entries = entry;
+ } /* end of if prevEntry == NULL */
+ } /* end of acceptanceFlag == FALSE */
+ } /* end of if consistentKey == TRUE */
+ else {
+ /*
+ * Loop to next entry and set previous entry.
+ */
+ prevEntry = entry;
+ entry = entry->next;
+ } /* end of if consistentKey == FALSE */
+ } /* end of loop for entry */
+ } /* end of if ( node->level == LEAF ) */
+
+ return;
+} /* end deleteEntry() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteIndexEntry.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteIndexEntry.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteIndexEntry.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteIndexEntry.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,70 @@
+/*
+ * Name: deleteIndexEntry
+ * Input: IndexEntry to delete
+ * level where entry resides
+ * Output: none
+ * Return: void
+ * Description: Routine deletes input index entry.
+ * Calls: deleteDataObject()
+ * deleteIndexNode()
+ * errorMessage()
+ * System: assert()
+ * free()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for free() and NULL definitions */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "index.h" /* for IndexEntry definition */
+
+void deleteIndexEntry( IndexEntry * entry, /* entry to delete */
+ Int level ) /* level of entry */
+{ /* beginning of deleteIndexEntry() */
+ static Char name[] = "deleteIndexEntry";
+
+ assert( entry );
+ assert( level >= LEAF );
+
+ /*
+ * If level is greater than a leaf, then child is a node. Assert
+ * that the child exists and then delete child.
+ */
+ if ( level > LEAF ) {
+ assert( entry->child.node ); /* assert that child exits */
+ deleteIndexNode( entry->child.node ); /* delete node child */
+ } /* end of if ( level > LEAF ) */
+ /*
+ * If level is a leaf, then child is a data object. Assert that
+ * the child exists and then delete the child.
+ */
+ else if ( level == LEAF ) {
+ assert( entry->child.dataObject ); /* assert child exits */
+ deleteDataObject( entry->child.dataObject ); /* delete object child */
+ } /* end of if ( level == LEAF ) */
+ /*
+ * Else, don't know what child is since level is negative which is
+ * undefined.
+ */
+ else {
+ errorMessage( "invalid level", REPLACE );
+ errorMessage( name, PREPEND );
+ } /* end of else */
+
+ /*
+ * Delete entry
+ */
+ free( entry );
+ entry = NULL;
+
+ return;
+} /* end of deleteIndexEntry() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteIndexNode.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteIndexNode.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteIndexNode.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/deleteIndexNode.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,61 @@
+/*
+ * Name: deleteIndexNode
+ * Input: IndexNode to delete
+ * Output: none
+ * Return: void
+ * Description: Routine deletes input node. Recursively descends all
+ * children of node to allow deletion of branches.
+ * Calls: deleteIndexEntry()
+ * System: free()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() debug check */
+#include <stdlib.h> /* for NULL and free() definitions */
+#include "index.h" /* for IndexNode definitions */
+
+void deleteIndexNode( IndexNode * node ) /* node to delete */
+{ /* beginning of deleteIndexNode() */
+ IndexEntry * entry; /* entry used for looping */
+
+ assert( node );
+
+ /*
+ * Delete the entries which reside on the node
+ */
+ entry = node->entries;
+ while ( entry != NULL ) {
+ IndexEntry * temp;
+
+ /*
+ * For each entry, save next entry in list for next
+ * loop, assert that the level of the current node
+ * is a valid value, i.e., >= LEAF level, and delete
+ * entry. After deletion, setup entry value for
+ * next loop.
+ */
+ temp = entry->next;
+
+ assert( node->level >= LEAF );
+
+ deleteIndexEntry( entry, node->level );
+
+ entry = temp;
+ } /* end while ( entry != NULL ) */
+
+ /*
+ * Delete node
+ */
+ free( node );
+ node = NULL;
+
+ return;
+} /* end of deleteIndexNode() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/errorMessage.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/errorMessage.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/errorMessage.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/errorMessage.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,138 @@
+
+/*
+ * File Name: errorMessage.c
+ * Purpose: Routines to provide error messaging for the baseline
+ * application.
+ *
+ * Revision History:
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <stdlib.h> /* for NULL definition */
+#include <stdio.h> /* for fprintf() and fflush() definitions */
+#include <string.h> /* for strlen(), strcpy(), strcat() definitions */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "errorMessage.h" /* for PREPEND and REPLACE definitions */
+
+/*
+ * Static definition of error buffer string
+ */
+#define ERROR_BUFFER_LENGTH 1023
+
+static Char errorBuffer[ ERROR_BUFFER_LENGTH + 1 ] = "\0";
+
+/*
+ * Name: errorMessage
+ * Input: message string
+ * flag to prepend to current buffer
+ * Output: none
+ * Return: void
+ * Description: The routine places an error message into a buffer for
+ * (possible) later display/flushing. The first argument is
+ * the message to add to buffer and the second argument is an
+ * integer flag on whether to prepend the message to the
+ * current buffer contents (PREPEND), or ignore the current
+ * contents and replace the buffer with the input message
+ * (REPLACE).
+ * Calls:
+ * System: fprintf()
+ * strlen()
+ * strcat()
+ * strcpy()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+void errorMessage( Char *message, /* message to prepend */
+ Boolean prepend )/* flag to clear buffer */
+{ /* beginning of errorMessage() */
+ /*
+ * If prepend flag is not set, replace current buffer with input message.
+ * If prepend flag is set, then check if adding message to current buffer
+ * will exceed maximum. If it does exceed limit, flush output.
+ * Otherwise, pre-pend message to current buffer.
+ */
+ if ( prepend == REPLACE ) {
+ /*
+ * Check if message is too large for buffer
+ */
+ if ( strlen( message ) > ERROR_BUFFER_LENGTH ) {
+ /*
+ * Message is too large for buffer. Flush message immediately.
+ */
+ fprintf( stderr, "Error Message Too Large for Buffer: flushing\n" );
+ fprintf( stderr, "unconnected: %s\n", message );
+ } /* end of if strlen( message ) > ERROR_BUFFER_LENGTH */
+ else {
+ strcpy( errorBuffer, message );
+ } /* end of if strlen( message ) <= ERROR_BUFFER_LENGTH */
+ } /* end of prepend = REPLACE */
+ else {
+ /*
+ * Check if buffer is large enough
+ */
+ if ( strlen( errorBuffer ) + strlen( message ) > ERROR_BUFFER_LENGTH ) {
+ /*
+ * Current buffer plus message is too large. Flush everything.
+ */
+ fprintf( stderr, "Error Message Buffer full: flushing\n" );
+ fprintf( stderr, "unconnected: %s: %s\n", message, errorBuffer );
+
+ errorMessage( "unconnected", REPLACE );
+ } /* end of if strlen( errorBuffer + message ) > ERROR_BUFFER_LENGTH */
+ else {
+ /*
+ * Pre-pend message to current buffer
+ */
+ Char tempBuffer[ ERROR_BUFFER_LENGTH + 1 ];
+
+ strcpy( tempBuffer, message );
+ strcat( tempBuffer, ": " );
+ strcat( tempBuffer, errorBuffer );
+ strcpy( errorBuffer, tempBuffer );
+ } /* end of if strlen( errorBuffer + message ) <= ERROR_BUFFER_LENGTH */
+ } /* end of prepend == PREPEND */
+
+ return;
+} /* end of errorMessage() */
+
+/*
+ * Name: flushErrorMessage
+ * Input: none
+ * Output: none
+ * Return: void
+ * Description:
+ * Calls:
+ * System: fprintf()
+ * Author: M.L.Rivas
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+void flushErrorMessage( void )
+{ /* beginning of flushErrorMessage() */
+ /*
+ * Place current error Buffer in stderr stream
+ */
+ if ( strlen( errorBuffer ) > 0 ) {
+ fprintf( stderr, "%s\n", errorBuffer );
+ fflush( stderr );
+ } /* end of if strlen( errorBuffer ) > 0 */
+
+ return;
+} /* end of flushErrorMessage() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/errorMessage.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/errorMessage.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/errorMessage.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/errorMessage.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,31 @@
+
+/*
+ * DIS Data Management Error Message
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_ERROR_MESSAGE_H
+#define DIS_ERROR_MESSAGE_H
+
+#include "dataManagement.h"
+
+/*
+ * Message prepend or replace values
+ */
+#define PREPEND TRUE
+#define REPLACE FALSE
+
+/*
+ * Function Prototypes
+ */
+extern void errorMessage( Char * message, Boolean prepend );
+extern void flushErrorMessage( void );
+
+#endif /* DIS_ERROR_MESSAGE_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getDeleteCommand.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getDeleteCommand.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getDeleteCommand.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getDeleteCommand.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,220 @@
+
+/*
+ * Name: getDeleteCommand
+ * Input: FILE pointer
+ * Output: index key
+ * list of non-key data attributes
+ * Return: GET_DELETE_SUCCESS, or
+ * GET_DELETE_IO_ERROR,
+ * GET_DELETE_EARLY_EOI,
+ * GET_DELETE_INVALID_CODE_ERROR,
+ * GET_DELETE_ALLOCATION_ERROR
+ * Description: The routine reads a Delete command from input stream via
+ * FILE pointer. Assumes that the current stream pointer
+ * position is correct, and returns the file pointer open and
+ * the current position immediately after the command just
+ * read. The file pointer is expected to be at the beginning
+ * of the Delete command immediately after the command code.
+ * The Delete command consists of a list of attribute code and
+ * value pairs. An error occurs if any attribute code does
+ * not have an accompanying value, an attribute code is
+ * out-of-range as specified in the DIS Benchmark Suite: Data
+ * Management, or an I/O error occurs reading the values from
+ * the stream. For any error during the read, the routine
+ * will leave the current values of the command attribute list
+ * intact and clear the FILE pointer to the end of the current
+ * line.
+ *
+ * A Delete command is made up of a list of attribute code and
+ * value pairs. The total number of pairs can range from zero
+ * to the MAX_ATTRIBUTE_CODE. Each command is carriage return
+ * delimited, i.e., one line per command. So, to read a Delete
+ * command, read until the end-of-line indicator is
+ * encountered.
+ *
+ * It is possible to have a Delete command return an empty
+ * attribute list without producing an error. Since missing
+ * attributes are defaulted to "wild-card" values, this type
+ * of delete would logically remove the entire database. This
+ * type of delete is a valid Delete command as defined by the
+ * DIS Benchmark Suite: Data Management document.
+ * Calls: errorMessage()
+ * getInt()
+ * getKeyAttribute()
+ * getNonKeyAttribute()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for NULL */
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive data types */
+#include "dataObject.h" /* for DataAttribute definition */
+#include "indexKey.h" /* for IndexKey definition */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "getDeleteCommand.h" /* for getDeleteCommand() and return codes */
+#include "getInt.h" /* for getInt() and return code definitions */
+#include "getKeyAttribute.h" /* for prototype and return code definitions */
+#include "getNonKeyAttribute.h" /* for prototype and return code definitions */
+
+Int getDeleteCommand( FILE *file, /* file for reading */
+ IndexKey *searchKey, /* index key */
+ DataAttribute **searchNonKey ) /* list of attributes */
+{ /* begin getDeleteCommand() */
+ Int attributeCode; /* attribute code read from file */
+ Int returnCode; /* return code from various routines */
+
+ static Char name[] = "getDeleteCommand";
+
+ assert( file );
+ assert( searchKey );
+ assert( MIN_ATTRIBUTE_CODE < NUM_OF_KEY_ATTRIBUTES );
+ assert( MIN_ATTRIBUTE_CODE < MAX_ATTRIBUTE_CODE );
+ assert( MAX_ATTRIBUTE_CODE < NUM_OF_LARGE_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_SMALL_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_MEDIUM_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_LARGE_ATTRIBUTES );
+
+ /*
+ * Set the values for the index key and non-key list to wild-card values.
+ * The key values are float, and the wild-card is a hyper-cube of maximum
+ * volume. The non-key values are char, and the wild-card values are NULL
+ * with an empty list.
+ */
+ searchKey->lower.T = MINIMUM_VALUE_OF_FLOAT;
+ searchKey->lower.X = MINIMUM_VALUE_OF_FLOAT;
+ searchKey->lower.Y = MINIMUM_VALUE_OF_FLOAT;
+ searchKey->lower.Z = MINIMUM_VALUE_OF_FLOAT;
+ searchKey->upper.T = MAXIMUM_VALUE_OF_FLOAT;
+ searchKey->upper.X = MAXIMUM_VALUE_OF_FLOAT;
+ searchKey->upper.Y = MAXIMUM_VALUE_OF_FLOAT;
+ searchKey->upper.Z = MAXIMUM_VALUE_OF_FLOAT;
+
+ *searchNonKey = NULL;
+
+ /*
+ * A Delete command is made up of a list of attribute code and value pairs.
+ * The total number of pairs can range from zero to MAX_ATTRIBUTE_CODE.
+ * Each command is on a separate line, i.e., an end-of-line indicator is
+ * used to delimit commands. So, to read the Delete command, read
+ * code/value pairs until an end-of-line indicator.
+ */
+ returnCode = GET_INT_SUCCESS;
+ while ( returnCode != GET_INT_EOI ) {
+ /*
+ * Read the attribute code first and check return code. If a
+ * successful read, check range of code for error. If code is in
+ * range, check for key or non-key attribute. For key and non-key
+ * attributes, read in appropriate values.
+ */
+ returnCode = getInt( file, &attributeCode );
+ if ( returnCode == GET_INT_SUCCESS ) {
+ if ( attributeCode < MIN_ATTRIBUTE_CODE || /* check code range */
+ attributeCode > MAX_ATTRIBUTE_CODE ) {
+ errorMessage( "code out-of-range", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_DELETE_INVALID_CODE_ERROR );
+ } /* end of check for invalid code */
+ else if ( attributeCode < NUM_OF_KEY_ATTRIBUTES ) {
+ Float value;
+
+ returnCode = getKeyAttribute( file, &value );
+ if ( returnCode == GET_KEY_ATTRIBUTE_SUCCESS ) {
+ if ( attributeCode == LOWER_POINT_T ) {
+ searchKey->lower.T = value;
+ } /* end of LOWER_POINT_T */
+ else if ( attributeCode == LOWER_POINT_X ) {
+ searchKey->lower.X = value;
+ } /* end of LOWER_POINT_X */
+ else if ( attributeCode == LOWER_POINT_Y ) {
+ searchKey->lower.Y = value;
+ } /* end of LOWER_POINT_Y */
+ else if ( attributeCode == LOWER_POINT_Z ) {
+ searchKey->lower.Z = value;
+ } /* end of LOWER_POINT_Z */
+ else if ( attributeCode == UPPER_POINT_T ) {
+ searchKey->upper.T = value;
+ } /* end of UPPER_POINT_T */
+ else if ( attributeCode == UPPER_POINT_X ) {
+ searchKey->upper.X = value;
+ } /* end of UPPER_POINT_X */
+ else if ( attributeCode == UPPER_POINT_Y ) {
+ searchKey->upper.Y = value;
+ } /* end of UPPER_POINT_Y */
+ else if ( attributeCode == UPPER_POINT_Z ) {
+ searchKey->upper.Z = value;
+ } /* end of UPPER_POINT_Z */
+ } /* end of GET_KEY_ATTRIBUTE_SUCCESS */
+ else if ( returnCode == GET_KEY_ATTRIBUTE_EOI ) {
+ errorMessage( "improper format - early EOI", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_DELETE_EARLY_EOI );
+ } /* end returnCode == GET_KEY_ATTRIBUTE_GET_FLOAT_FAILURE */
+ else if ( returnCode == GET_KEY_ATTRIBUTE_GET_FLOAT_FAILURE ) {
+ errorMessage( "low-level I/O error", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_DELETE_IO_ERROR );
+ } /* end returnCode == GET_KEY_ATTRIBUTE_GET_FLOAT_FAILURE */
+ } /* end of key attribute */
+ else {
+ Char *value;
+
+ returnCode = getNonKeyAttribute( file, &value );
+ if ( returnCode == GET_NON_KEY_ATTRIBUTE_SUCCESS ) {
+ DataAttribute *newAttribute;
+
+ /*
+ * Allocate new DataAttribute, store values of attribute
+ * code and attribute string, and add new DataAttribute to
+ * output list.
+ */
+ newAttribute =
+ (DataAttribute *)malloc( sizeof( DataAttribute ) );
+ if ( newAttribute == NULL ) {
+ errorMessage( "allocation failure", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_DELETE_ALLOCATION_ERROR );
+ } /* end of if ( attribute == NULL ) */
+
+ newAttribute->code = attributeCode;
+ newAttribute->attribute.value.nonKey = value;
+
+ newAttribute->next = *searchNonKey;
+ *searchNonKey = newAttribute;
+ }
+ else if ( returnCode == GET_NON_KEY_ATTRIBUTE_EOI ){
+ errorMessage( "improper format - early EOI", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_DELETE_EARLY_EOI );
+ } /* end of if returnCode == GET_NON_KEY_ATTRIBUTE_EOI */
+ else if ( returnCode==GET_NON_KEY_ATTRIBUTE_ALLOCATION_FAILURE){
+ errorMessage( "allocation of non-key attribute", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_DELETE_ALLOCATION_ERROR );
+ } /* end of if ( returnCode == ALLOCATION_FAILURE ) */
+ } /* end of non-key attribute */
+ } /* end of if ( returnCode == GET_INT_SUCCESS ) */
+ else if ( returnCode == GET_INT_EOI ) {
+ /*
+ * empty
+ */
+ } /* end of if ( returnCode == GET_INT_EOI ) */
+ else if ( returnCode == GET_INT_RANGE_EXCEEDED ) {
+ return ( GET_DELETE_INVALID_CODE_ERROR );
+ } /* end of if ( error == GET_INT_RANGE_EXCEEDED ) */
+ else if ( returnCode == GET_INT_BAD_CONVERSION ) {
+ return ( GET_DELETE_INVALID_CODE_ERROR );
+ } /* end of if ( error == GET_INT_BAD_CONVERSION ) */
+ }
+
+ return ( GET_DELETE_SUCCESS );
+} /* end of getDeleteCommand() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getDeleteCommand.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getDeleteCommand.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getDeleteCommand.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getDeleteCommand.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,46 @@
+
+/*
+ * DIS Data Management: getDeleteCommand
+ *
+ * This header file defines the return codes for the getDeleteCommand
+ * function. Any file which uses the getDeleteCommand routine should
+ * include this header. The first code indicates success. The second
+ * code is the result of an I/O error at a lower-level read function. The
+ * third code indicates that an end-of-line or end-of-file indicator was
+ * read before insert command was finished. The fourth error is when an
+ * attribute code is unknown or invalid. The fifth error is an allocation
+ * error for the non-key attribute character strings.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_GET_DELETE_COMMAND_H
+#define DIS_GET_DELETE_COMMAND_H
+
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive data types */
+#include "dataObject.h" /* for DataAttribute definition */
+#include "indexKey.h" /* for IndexKey definition */
+
+/*
+ * Return codes
+ */
+#define GET_DELETE_SUCCESS 0
+#define GET_DELETE_IO_ERROR 1
+#define GET_DELETE_EARLY_EOI 2
+#define GET_DELETE_INVALID_CODE_ERROR 3
+#define GET_DELETE_ALLOCATION_ERROR 4
+
+/*
+ * Function Prototype
+ */
+extern Int getDeleteCommand( FILE *file, IndexKey *searchKey,
+ DataAttribute **searchNonKey );
+
+#endif /* DIS_GET_DELETE_COMMAND_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getFloat.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getFloat.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getFloat.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getFloat.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,97 @@
+
+/*
+ * Name: getFloat
+ * Input: FILE ptr
+ * Output: float value
+ * Return: GET_FLOAT_SUCCESS, or
+ * GET_FLOAT_EOL,
+ * GET_FLOAT_EOF,
+ * GET_FLOAT_GET_STRING_FAILURE
+ * Description: The routine reads a space delimited float from the
+ * current position of the FILE pointer. The routine uses
+ * getString() to obtain the character string representation
+ * of the float and then uses the system level strtod() to
+ * find the float value. Note that the getString() routine
+ * does not allow the read to cross an end-of-line indicator
+ * as opposed to the system routines which do. In the event
+ * of an error, the output value is set to an implausible
+ * amount, MINIMUM_VALUE_OF_FLOAT to indicate an error occurred
+ * along with an appropriate return code.
+ * Calls:
+ * System: strtod()
+ * strlen()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <errno.h> /* for extern errno definition */
+#include <stdlib.h> /* for NULL definition */
+#include <stdio.h> /* for FILE definition */
+#include <string.h> /* for strlen() definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "getFloat.h" /* for getFloat() return codes */
+
+extern int errno;
+
+/*
+ * Function prototype
+ */
+extern Char *getString( FILE *file );
+
+Int getFloat( FILE *file, /* FILE stream to read */
+ Float *value ) /* value to output */
+{ /* begin getFloat() */
+ Char *temp; /* temporary string used returned by getString() */
+ Char *endptr; /* residual string after conversion from string to Float */
+ Int returnCode; /* return code for this routine */
+
+ assert( file );
+ assert( value );
+
+ /*
+ * Use utility routine getString to read the string representation of the
+ * Float. Check return code of getString for success or errors. On
+ * successful read of string, use system routine strtod to convert string
+ * to float value. Check for errors returned from system call and range
+ * errors.
+ */
+ temp = getString( file );
+ if ( temp != NULL ) {
+ /*
+ * A valid string was read from the input and is stored in temp
+ */
+ *value = strtod( temp, &endptr );
+ if ( *value == 0.0 && strlen( endptr ) > 0 && errno == ERANGE ) {
+ *value = MINIMUM_VALUE_OF_FLOAT;
+ returnCode = GET_FLOAT_BAD_CONVERSION;
+ } /* end of strtod error check */
+ else {
+ if ( *value < MINIMUM_VALUE_OF_FLOAT ) {
+ *value = MINIMUM_VALUE_OF_FLOAT;
+ returnCode = GET_FLOAT_RANGE_EXCEEDED;
+ } /* end of value < MINIMUM_VALUE_OF_FLOAT */
+ else if ( *value > MAXIMUM_VALUE_OF_FLOAT ) {
+ *value = MAXIMUM_VALUE_OF_FLOAT;
+ returnCode = GET_FLOAT_RANGE_EXCEEDED;
+ } /* end of value > MAXIMUM_VALUE_OF_FLOAT */
+ else {
+ returnCode = GET_FLOAT_SUCCESS;
+ } /* end of else - SUCCESS */
+ } /* end of else strtod did not error */
+ } /* end if temp != NULL */
+ else {
+ *value = MINIMUM_VALUE_OF_FLOAT;
+ returnCode = GET_FLOAT_EOI;
+ } /* end if GET_STRING low-level I/O error */
+
+ return ( returnCode );
+} /* end of getFloat() */
+
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getFloat.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getFloat.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getFloat.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getFloat.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,38 @@
+
+/*
+ * DIS Data Management: getFloat
+ *
+ * This header file contains the return codes for the
+ * getInt routine. The routine reads a space-delimited integer from the
+ * input FILE stream, but does not cross an end-of-line indicator as the
+ * default system routines do.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_GET_FLOAT_H
+#define DIS_GET_FLOAT_H
+
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive type definitions */
+
+/*
+ * Return Codes
+ */
+#define GET_FLOAT_SUCCESS 0
+#define GET_FLOAT_EOI 1
+#define GET_FLOAT_RANGE_EXCEEDED 2
+#define GET_FLOAT_BAD_CONVERSION 3
+
+/*
+ * Function Prototype
+ */
+extern Int getFloat( FILE *file, Float *value );
+
+#endif /* DIS_GET_FLOAT_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInitCommand.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInitCommand.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInitCommand.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInitCommand.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,94 @@
+
+/*
+ * Name: getInitCommand
+ * Input: FILE pointer
+ * Output: integer fan
+ * Return: GET_INIT_SUCCESS, or
+ * GET_INIT_IO_ERROR,
+ * GET_INIT_EARLY_EOI,
+ * GET_INIT_INVALID_FAN
+ * Description: Reads an Initialization command from the input stream via
+ * FILE pointer. Assumes the current stream pointer is
+ * correct, and returns file pointer open and current position
+ * immediately after command just read. The file pointer is
+ * expected to be at the beginning of the Init command
+ * immediately after the command code. The final position of
+ * the file pointer is immediately after the command, but
+ * before the final end-of-line indicator. The Init command
+ * has a very different format than the other database commands
+ * and the routine, so the routine is very different than the
+ * other command input routines. Also, the command should only
+ * appear once and at the beginning of the file. The format is
+ * an integer value which specifies the fan or order of the
+ * index. The absence of the fan, an incorrect fan value (<
+ * MINIMUM_FAN_SIZE ), or any I/O fault causes an error to
+ * occur with the return of an approriate error code.
+ * Calls: clearLine()
+ * errorMessage()
+ * getInt()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive data types */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "getInt.h" /* for getInt() and return code definitions */
+#include "getInitCommand.h" /* for getInitCommand() return codes */
+
+/*
+ * Function prototypes
+ */
+extern void clearLine( FILE *file );
+
+Int getInitCommand( FILE *file, /* file for reading */
+ Int *fan ) /* output fan read */
+{ /* begin getInitCommand() */
+ Int returnCode; /* return code value from getInt() */
+
+ static Char name[] = "getInitCommand";
+
+ assert( file );
+ assert( fan );
+
+ /*
+ * Read the integer value for the fan checking for error return codes.
+ */
+ returnCode = getInt( file, fan );
+ if ( returnCode == GET_INT_SUCCESS ) {
+ if ( *fan < MINIMUM_FAN_SIZE ) {
+ errorMessage( "invalid fan specified", REPLACE );
+ errorMessage( name, PREPEND );
+ returnCode = GET_INIT_INVALID_FAN;
+ } /* end of if ( *fan < MINIMUM_FAN_SIZE ) */
+ else {
+ returnCode = GET_INIT_SUCCESS;
+ } /* end of if ( *fan >= MINIMUM_FAN_SIZE ) */
+ } /* end of if returnCode == SUCCESS ) */
+ else if ( returnCode == GET_INT_EOI ) {
+ errorMessage( "improper format - early EOI", REPLACE );
+ errorMessage( name, PREPEND );
+ returnCode = GET_INIT_EARLY_EOI;
+ } /* end of if ( returnCode == GET_INT_EOI ) */
+ else if ( returnCode == GET_INT_RANGE_EXCEEDED ) {
+ errorMessage( "invalid fan specified", REPLACE );
+ errorMessage( name, PREPEND );
+ returnCode = GET_INIT_INVALID_FAN;
+ } /* end of if ( returnCode == GET_INT_GET_STRING_FAILURE ) */
+ else if ( returnCode == GET_INT_BAD_CONVERSION ) {
+ errorMessage( "improper format - fan must be an integer", REPLACE );
+ errorMessage( name, PREPEND );
+ returnCode = GET_INIT_IO_ERROR;
+ } /* end of if ( returnCode == GET_INT_GET_STRING_FAILURE ) */
+
+ return ( returnCode );
+} /* end of getInitCommand() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInitCommand.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInitCommand.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInitCommand.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInitCommand.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,41 @@
+
+/*
+ * DIS Data Management: getInitCommand
+ *
+ * This header file defines the return codes for the getInitCommand
+ * function. Any file which uses the getInitCommand routine should
+ * include this header. The first code indicates success. The second
+ * code is the result of an I/O error at a lower-level read function. The
+ * third code indicates that an end-of-line or end-of-file indicator was
+ * read before the init command was finished. The fourth error is when
+ * the fan size read was invalid (too large or too small).
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_GET_INIT_COMMAND_H
+#define DIS_GET_INIT_COMMAND_H
+
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive data types */
+
+/*
+ * Return codes
+ */
+#define GET_INIT_SUCCESS 0
+#define GET_INIT_IO_ERROR 1
+#define GET_INIT_EARLY_EOI 2
+#define GET_INIT_INVALID_FAN 3
+
+/*
+ * Function Prototype
+ */
+extern Int getInitCommand( FILE *file, Int *fan );
+
+#endif /* DIS_GET_INIT_COMMAND_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInsertCommand.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInsertCommand.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInsertCommand.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInsertCommand.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,206 @@
+
+/*
+ * Name: getInsertCommand
+ * Input: FILE pointer
+ * Output: data object
+ * Return: GET_INSERT_SUCCESS, or
+ * GET_INSERT_IO_ERROR
+ * GET_INSERT_EARLY_EOI
+ * GET_INSERT_UNKNOWN_DATA_OBJECT_TYPE
+ * GET_INSERT_ALLOCATION_ERROR
+ * Description: Reads an Insert command from the input stream via FILE
+ * pointer. Assumes the current stream pointer is correct,
+ * and returns file pointer open and current position
+ * immediately after command just read. The file pointer is
+ * expected to be at the beginning of the Insert command
+ * immediately after the command code. The Insert command
+ * consists of the data object type identifier and a complete
+ * listing of the attributes (key and non-key) for the
+ * object. Each command is carrriage return delimited, i.e.,
+ * one line per command. The command is read by first reading
+ * the type, allocating the correct amount of memory for that
+ * type, setting a local variable to determine how many
+ * attributes need to be read, and then processing the line.
+ * An error occurs if the object is of an unknown type, any
+ * of the attributes are missing, or a memory allocation
+ * failure for the non-key attribute character sequencyes.
+ * For any error during the read (missing attributes, bad
+ * conversions, etc.), the routine will leave the current
+ * values of the command attribute list intact, clear the
+ * current line, and return the error code. The output of the
+ * routine is the data object which is ready to be inserted
+ * into the index.
+ * Calls: clearLine()
+ * errorMessage()
+ * getInt()
+ * getKeyAttribute()
+ * getNonKeyAttribute()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive data types */
+#include "dataObject.h" /* for DataObject definition */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "getInt.h" /* for getInt() and return code definitions */
+#include "getKeyAttribute.h" /* for prototype and return code definitions */
+#include "getInsertCommand.h" /* for getInsertCommand() return codes */
+#include "getNonKeyAttribute.h" /* for prototype and return code definitions */
+
+Int getInsertCommand( FILE *file, /* file for reading */
+ DataObject **dataObject ) /* data object */
+{ /* begin getInsertCommand() */
+ Int i; /* looping index variable for attributes */
+ Int returnCode; /* return code from various routines */
+ Int dataObjectType; /* data object type read from file */
+ Int numberOfAttributes; /* number of attributes to read from file and */
+ /* based on data object type */
+
+ static Char name[] = "getInsertCommand";
+
+ assert( file );
+ assert( dataObject );
+ assert( MIN_ATTRIBUTE_CODE < NUM_OF_KEY_ATTRIBUTES );
+ assert( MIN_ATTRIBUTE_CODE < MAX_ATTRIBUTE_CODE );
+ assert( MAX_ATTRIBUTE_CODE < NUM_OF_LARGE_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_SMALL_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_MEDIUM_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_LARGE_ATTRIBUTES );
+
+ /*
+ * The first parameter to read is the type of data object identifier. The
+ * value is one of three types: SMALL, MEDIUM, or LARGE. The value is
+ * read and the return code is checked. An early EOF marker or low-level
+ * error causes an error message to be inserted in buffer, clears the
+ * line, and returns with the appropriate error code. If all error checks
+ * pass, the value read determines the creation of the data object and
+ * sets the local variable, numberOfAttributes, to be used later when
+ * processing the line. If the type is unknown, that also causes an error
+ * message, clears the line, and returns.
+ */
+ returnCode = getInt( file, &dataObjectType );
+ if ( returnCode == GET_INT_SUCCESS ) {
+ /*
+ * empty
+ */
+ }
+ else if ( returnCode == GET_INT_EOI ) {
+ errorMessage( "improper format - early EOI", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_INSERT_EARLY_EOI );
+ } /* end of if ( returnCode == GET_INT_EOI ) */
+ else if ( returnCode == GET_INT_RANGE_EXCEEDED ) {
+ errorMessage( "unknown data object type", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_INSERT_IO_ERROR );
+ } /* end of if ( returnCode == GET_INT_GET_STRING_FAILURE ) */
+ else if ( returnCode == GET_INT_BAD_CONVERSION) {
+ errorMessage( "improper format - type must be an integer", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_INSERT_IO_ERROR );
+ } /* end of if ( returnCode == GET_INT_GET_STRING_FAILURE ) */
+
+ /*
+ * Create proper data object from type and store number of attributes
+ */
+ if ( dataObjectType == SMALL ) {
+ *dataObject = createDataObject( SMALL );
+ numberOfAttributes = NUM_OF_SMALL_ATTRIBUTES;
+ } /* end of if ( dataObjectType == SMALL ) */
+ else if ( dataObjectType == MEDIUM ) {
+ *dataObject = createDataObject( MEDIUM );
+ numberOfAttributes = NUM_OF_MEDIUM_ATTRIBUTES;
+ } /* end of if ( dataObjectType == MEDIUM ) */
+ else if ( dataObjectType == LARGE ) {
+ *dataObject = createDataObject( LARGE );
+ numberOfAttributes = NUM_OF_LARGE_ATTRIBUTES;
+ } /* end of if ( dataObjectType == LARGE ) */
+ else {
+ /*
+ * Done: unknown data object type
+ */
+ errorMessage( "unknown data object type", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_INSERT_UNKNOWN_DATA_OBJECT_TYPE );
+ } /* end of data object type branches */
+
+ /*
+ * Check memory allocation error for data object
+ */
+ if ( *dataObject == NULL ) {
+ errorMessage( "allocation failure", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_INSERT_ALLOCATION_ERROR );
+ } /* end of if ( *dataObject == NULL ) */
+
+ /*
+ * The attributes for the data object are specified to be in the "proper"
+ * order, i.e., by the attribute code in the DIS Benchmark Suite:Data
+ * Management document. This means that the first NUM_OF_KEY_ATTRIBUTE
+ * values are key values (floats). A fixed loop reads these values. Each
+ * read is followed by a check for error conditions where each error
+ * condition causes a return with appropriate error code.
+ */
+ for ( i = MIN_ATTRIBUTE_CODE; i < NUM_OF_KEY_ATTRIBUTES; i++ ) {
+ Float temp;
+
+ returnCode = getKeyAttribute( file, &temp );
+ if ( returnCode == GET_KEY_ATTRIBUTE_SUCCESS ) {
+ (*dataObject)->attributes[ i ].value.key = temp;
+ } /* end of if returnCode == GET_KEY_ATTRIBUTE_SUCCESS */
+ else if ( returnCode == GET_KEY_ATTRIBUTE_EOI ) {
+ errorMessage( "improper format - early EOI", REPLACE );
+ errorMessage( name, PREPEND );
+ (*dataObject)->attributes[ i ].value.key = MINIMUM_VALUE_OF_FLOAT;
+ return ( GET_INSERT_EARLY_EOI );
+ } /* end of if returnCode == GET_KEY_ATTRIBUTE_EOI */
+ else if ( returnCode == GET_KEY_ATTRIBUTE_GET_FLOAT_FAILURE ) {
+ errorMessage( "low-level I/O error", REPLACE );
+ errorMessage( name, PREPEND );
+ (*dataObject)->attributes[ i ].value.key = MINIMUM_VALUE_OF_FLOAT;
+ return ( GET_INSERT_IO_ERROR );
+ } /* end of if returnCode == GET_KEY_ATTRIBUTE_GET_FLOAT_FAILURE */
+ } /* end of loop for key attributes */
+
+ /*
+ * The next series of attributes are non-key values (character sequences).
+ * The number of strings to read is determined by the local variable
+ * numberOfAttributes which is determined by the data object type
+ * specifier read at the beginning of the line. A fixed loop reads the
+ * correct number of strings. Each read is followed by a check for error
+ * conditions where each error condition causes a return with appropriate
+ * error code.
+ */
+ for ( i = NUM_OF_KEY_ATTRIBUTES; i < numberOfAttributes; i++ ) {
+ Char *temp;
+
+ returnCode = getNonKeyAttribute( file, &temp );
+ if ( returnCode == GET_NON_KEY_ATTRIBUTE_SUCCESS ) {
+ (*dataObject)->attributes[ i ].value.nonKey = temp;
+ } /* end of if ( returnCode == GET_STRING_SUCCESS ) */
+ else if ( returnCode == GET_NON_KEY_ATTRIBUTE_EOI ) {
+ errorMessage( "improper format - early EOI", REPLACE );
+ errorMessage( name, PREPEND );
+ (*dataObject)->attributes[ i ].value.nonKey = NULL;
+ return ( GET_INSERT_EARLY_EOI );
+ } /* end of returnCode == GET_NON_KEY_ATTRIBUTE_EOI */
+ else if ( returnCode == GET_NON_KEY_ATTRIBUTE_ALLOCATION_FAILURE ) {
+ errorMessage( "allocation failure for non-key attribute", REPLACE );
+ errorMessage( name, PREPEND );
+ (*dataObject)->attributes[ i ].value.nonKey = NULL;
+ return ( GET_INSERT_ALLOCATION_ERROR );
+ } /* end of returnCode == GET_NON_KEY_ATTRIBUTE_ALLOCATION_FAILURE */
+ } /* end of loop for non-key attributes */
+
+ return ( GET_INSERT_SUCCESS );
+} /* end of getInsertCommand() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInsertCommand.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInsertCommand.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInsertCommand.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInsertCommand.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,45 @@
+
+/*
+ * DIS Data Management: getInsertCommand
+ *
+ * This header file defines the return codes for the getInsertCommand
+ * function. Any file which uses the getInsertCommand routine should
+ * include this header. The first code indicates success. The second
+ * code is the result of an I/O error at a lower-level read function. The
+ * third code indicates that an end-of-line or end-of-file indicator was
+ * read before insert command was finished. The fourth error is when the
+ * data object type specifier, which is part of the insert command, is of
+ * an unknown type. The fifth error is an allocation error for the
+ * non-key attribute character strings.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_GET_INSERT_COMMAND_H
+#define DIS_GET_INSERT_COMMAND_H
+
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive data types */
+#include "dataObject.h" /* for DataObject definition */
+
+/*
+ * Return codes
+ */
+#define GET_INSERT_SUCCESS 0
+#define GET_INSERT_IO_ERROR 1
+#define GET_INSERT_EARLY_EOI 2
+#define GET_INSERT_UNKNOWN_DATA_OBJECT_TYPE 3
+#define GET_INSERT_ALLOCATION_ERROR 4
+
+/*
+ * Function Prototype
+ */
+extern Int getInsertCommand( FILE *file, DataObject **dataObject );
+
+#endif /* DIS_GET_INSERT_COMMAND_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInt.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInt.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInt.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInt.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,95 @@
+
+/*
+ * Name: getInt
+ * Input: FILE ptr
+ * Output: integer value read
+ * Return: GET_INT_SUCCESS, or
+ * GET_INT_GET_STRING_FAILURE
+ * Description: The routine reads a space delimited integer from the
+ * current position of the FILE pointer. The routine uses
+ * getString() to obtain the character string representation
+ * of the integer and then uses the system level strtol() to
+ * find the integer value. Note that the getString() routine
+ * does not allow the read to cross an end-of-line indicator
+ * as opposed to the system routines which do. In the event
+ * of an error, the output value is set to an implausible
+ * amount, MINIMUM_VALUE_OF_INT, to indicate an error occurred
+ * along with an appropriate return code.
+ * Calls:
+ * System:
+ * strlen()
+ * strtol()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <errno.h> /* for extern errno definition */
+#include <stdlib.h> /* for NULL definition */
+#include <stdio.h> /* for FILE definition */
+#include <string.h> /* for strlen() definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "getInt.h" /* for getInt() return codes */
+
+extern int errno;
+
+/*
+ * Function prototype
+ */
+extern Char *getString( FILE *file );
+
+Int getInt( FILE *file, /* FILE stream to read */
+ Int *value ) /* value to output */
+{ /* begin getInt() */
+ Char *temp; /* temporary string returned by getString() */
+ Char *endptr; /* residual from conversion from string to int */
+ Int returnCode; /* return code for this routine */
+
+ assert( file );
+ assert( value );
+
+ /*
+ * Use utility routine getString to read the string representation of the
+ * Int. Check return code of getString for success or errors. On
+ * successful read of string, use system routine strtod to convert string
+ * to integer value. Check for errors returned from system call and range
+ * errors.
+ */
+ temp = getString( file );
+ if ( temp != NULL ) {
+ /*
+ * A valid string was read from the input and is reference by temp
+ */
+ *value = strtol( temp, &endptr, 0 );
+ if ( *value == 0 && strlen( endptr ) > 0 && errno == ERANGE ) {
+ *value = MINIMUM_VALUE_OF_INT;
+ returnCode = GET_INT_BAD_CONVERSION;
+ } /* end of strtol error check */
+ else {
+ if ( *value < MINIMUM_VALUE_OF_INT ) {
+ *value = MINIMUM_VALUE_OF_INT;
+ returnCode = GET_INT_RANGE_EXCEEDED;
+ } /* end of value < MINIMUM_VALUE_OF_INT */
+ else if ( *value > MAXIMUM_VALUE_OF_INT ) {
+ *value = MAXIMUM_VALUE_OF_INT;
+ returnCode = GET_INT_RANGE_EXCEEDED;
+ } /* end of value > MAXIMUM_VALUE_OF_INT */
+ else {
+ returnCode = GET_INT_SUCCESS;
+ } /* end of else - SUCCESS */
+ } /* end of else strtol did not error */
+ } /* end if temp != NULL */
+ else {
+ *value = MINIMUM_VALUE_OF_INT;
+ returnCode = GET_INT_EOI;
+ } /* end if GET_STRING end-of-input */
+
+ return ( returnCode );
+} /* end of getInt() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInt.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInt.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInt.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getInt.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,38 @@
+
+/*
+ * DIS Data Management: getInt
+ *
+ * This header file contains the return codes for the
+ * getInt routine. The routine reads a space-delimited integer from the
+ * input FILE stream, but does not cross an end-of-line indicator as the
+ * default system routines do.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_GET_INT_H
+#define DIS_GET_INT_H
+
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive data types */
+
+/*
+ * Return Codes
+ */
+#define GET_INT_SUCCESS 0
+#define GET_INT_EOI 1
+#define GET_INT_RANGE_EXCEEDED 2
+#define GET_INT_BAD_CONVERSION 3
+
+/*
+ * Function Prototype
+ */
+extern Int getInt( FILE *file, Int *value );
+
+#endif /* DIS_GET_INT_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getKeyAttribute.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getKeyAttribute.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getKeyAttribute.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getKeyAttribute.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,67 @@
+
+/*
+ * Name: getNonKeyAttribute
+ * Input: FILE ptr
+ * Output: character string handle
+ * Return: GET_NON_KEY_ATTRIBUTE_SUCCESS, or
+ * GET_NON_KEY_ATTRIBUTE_ALLOCATION_FAILURE,
+ * GET_NON_KEY_ATTRIBUTE_GET_STRING_FAILURE
+ * Description: Reads a non-key attribute from the current position of the
+ * file pointer. A non-key attribute is defined to be a
+ * white-space delimited string. The read will not cross an
+ * end-of-line indicated by a new line '\n' or carriage return
+ * '\r'. The routine is a match for the getNonKeyAttribute()
+ * routine and simply calls the getFloat() routine to read the
+ * key value from the file.
+ * Calls: errorMessage()
+ * getFloat()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "getFloat.h" /* for getFloat() and return code definitions */
+#include "getKeyAttribute.h" /* for getKeyAttribute() return codes */
+
+Int getKeyAttribute( FILE *file, /* input stream to get string from */
+ Float *value ) /* pointer to float storage */
+{ /* begin getKeyAttribute() */
+ Int returnCode; /* return code for this routine */
+
+ static Char name[] = "getKeyAttribute";
+
+ assert( file );
+ assert( value );
+
+ /*
+ * Read string using special utility getString(). Check for error during
+ * read. If no error, allocate memory and copy over contents of value
+ * returned.
+ */
+ returnCode = getFloat( file, value );
+ if ( returnCode == GET_FLOAT_SUCCESS ) {
+ returnCode = GET_KEY_ATTRIBUTE_SUCCESS;
+ }
+ else if ( returnCode == GET_FLOAT_EOI ) {
+ errorMessage( name, PREPEND );
+ returnCode = GET_KEY_ATTRIBUTE_EOI;
+ }
+ else if ( returnCode == GET_FLOAT_RANGE_EXCEEDED ||
+ returnCode == GET_FLOAT_BAD_CONVERSION ) {
+ errorMessage( name, PREPEND );
+ returnCode = GET_KEY_ATTRIBUTE_GET_FLOAT_FAILURE;
+ }
+
+ return ( returnCode );
+} /* end of getKeyAttribute() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getKeyAttribute.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getKeyAttribute.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getKeyAttribute.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getKeyAttribute.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,37 @@
+
+/*
+ * DIS Data Management: getKeyAttribute
+ *
+ * This header file contains the return codes for the getKeyAttribute
+ * routine. The routine reads a key attribute from the input FILE
+ * stream which is defined to be a space-delimited float, but does not
+ * cross an end-of-line indicator as the default system routines do.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_GET_KEY_ATTRIBUTE_H
+#define DIS_GET_KEY_ATTRIBUTE_H
+
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive type definitions */
+
+/*
+ * Return Codes
+ */
+#define GET_KEY_ATTRIBUTE_SUCCESS 0
+#define GET_KEY_ATTRIBUTE_EOI 1
+#define GET_KEY_ATTRIBUTE_GET_FLOAT_FAILURE 2
+
+/*
+ * Function Prototype
+ */
+extern Int getKeyAttribute( FILE *file, Float *value );
+
+#endif /* DIS_GET_KEY_ATTRIBUTE_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNextCommandCode.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNextCommandCode.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNextCommandCode.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNextCommandCode.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,102 @@
+
+/*
+ * Name: getNextCommandCode
+ * Input: FILE pointer
+ * Output: command code
+ * Return: GET_NEXT_COMMAND_CODE_SUCCESS, or
+ * GET_NEXT_COMMAND_CODE_IO_ERROR,
+ * GET_NEXT_COMMAND_CODE_INVALID_COMMAND
+ * Description: Reads next command code from file and returns the command
+ * value. The file input is assumed to be a DIS Benchmark
+ * Suite: Data Management data set file where each line of the
+ * file is a separate command to read. There are five valid
+ * values for the command code which correspond to the
+ * database commands (Insert, Query, Delete, and Init) and a
+ * NONE type which indicates that the data file is "empty",
+ * i.e., all of the commands in the file have been processed.
+ * A command code of NONE does not indicate an error condition
+ * which would be returned by an error flag.
+ * Calls: errorMessage()
+ * getInt()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive data types */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "getNextCommandCode.h" /* for getNextCommandCode() return codes */
+#include "getInt.h" /* for getInt() and return code definitions */
+
+Int getNextCommandCode( FILE *file, /* file for reading */
+ CommandType *commandCode ) /* code of next command */
+{ /* begin getNextCommandCode() */
+ Int returnCode;
+ Int command;
+
+ static Char name[] = "getNextCommandCode";
+
+ assert( file );
+ assert( commandCode );
+
+ /*
+ * Read integer value from FILE and check for errors. If an early
+ * end-of-line or low-level getString failure occurred, return error
+ * code. If EOF is returned, assume that the file is done and return code
+ * of appropriate value. If valid command is read, place value in code
+ * and return success. If an unknown command is read, place INVALID value
+ * in command code, clear line of unknown data, and return error.
+ */
+ returnCode = getInt( file, &command );
+ if ( returnCode == GET_INT_SUCCESS ) {
+ if ( command == INIT ) {
+ *commandCode = INIT;
+ returnCode = GET_NEXT_COMMAND_CODE_SUCCESS;
+ } /* end of if ( command == INIT ) */
+ else if ( command == INSERT ) {
+ *commandCode = INSERT;
+ returnCode = GET_NEXT_COMMAND_CODE_SUCCESS;
+ } /* end of if ( command == INSERT ) */
+ else if ( command == QUERY ) {
+ *commandCode = QUERY;
+ returnCode = GET_NEXT_COMMAND_CODE_SUCCESS;
+ } /* end of if ( command == QUERY ) */
+ else if ( command == DELETE ) {
+ *commandCode = DELETE;
+ returnCode = GET_NEXT_COMMAND_CODE_SUCCESS;
+ } /* end of if ( command == DELETE ) */
+ else {
+ errorMessage( "unknown command code", REPLACE );
+ errorMessage( name, PREPEND );
+ *commandCode = INVALID;
+ returnCode = GET_NEXT_COMMAND_CODE_INVALID_COMMAND;
+ } /* end of command code branches */
+ } /* end of if ( returnCode == GET_INT_SUCCESS ) */
+ else if ( returnCode == GET_INT_EOI ) {
+ *commandCode = NONE;
+ returnCode = GET_NEXT_COMMAND_CODE_SUCCESS;
+ } /* end of if ( returnCode == GET_INT_EOI ) */
+ else if ( returnCode == GET_INT_RANGE_EXCEEDED ) {
+ errorMessage( "unknown command code", REPLACE );
+ errorMessage( name, PREPEND );
+ *commandCode = INVALID;
+ returnCode = GET_NEXT_COMMAND_CODE_INVALID_COMMAND;
+ } /* end of if ( returnCode == GET_INT_EOF ) */
+ else if ( returnCode == GET_INT_BAD_CONVERSION ) {
+ errorMessage( "improper format - code must be an integer", REPLACE );
+ errorMessage( name, PREPEND );
+ *commandCode = INVALID;
+ returnCode = GET_NEXT_COMMAND_CODE_INVALID_COMMAND;
+ } /* end of if ( returnCode == GET_INT_EOF ) */
+
+ return ( returnCode );
+} /* end of getNextCommandCode() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNextCommandCode.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNextCommandCode.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNextCommandCode.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNextCommandCode.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,51 @@
+
+/*
+ * DIS Data Management: getNextCommandCode
+ *
+ * This header file defines the command types for each of the
+ * database commands, and the return codes for the routine are provided
+ * as #define's.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_GET_NEXT_COMMAND_CODE_H
+#define DIS_GET_NEXT_COMMAND_CODE_H
+
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive data types */
+
+/*
+ * Command Types
+ * - values defined by DIS Benchmark Suite Specification
+ * - used during input of index commands
+ * - includes a value for NONE indicating data set finished
+ */
+typedef enum {
+ INIT = 0,
+ INSERT = 1,
+ QUERY = 2,
+ DELETE = 3,
+ NONE = 4, /* termination specifier, i.e., no command left */
+ INVALID = 5 /* placeholder for invalid command */
+} CommandType;
+
+/*
+ * Return codes
+ */
+#define GET_NEXT_COMMAND_CODE_SUCCESS 0
+#define GET_NEXT_COMMAND_CODE_IO_ERROR 1
+#define GET_NEXT_COMMAND_CODE_INVALID_COMMAND 2
+
+/*
+ * Function Prototype
+ */
+extern Int getNextCommandCode( FILE *file, CommandType *commandCode );
+
+#endif /* DIS_GET_NEXT_COMMAND_CODE_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNonKeyAttribute.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNonKeyAttribute.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNonKeyAttribute.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNonKeyAttribute.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,84 @@
+
+/*
+ * Name: getNonKeyAttribute
+ * Input: FILE ptr
+ * Output: character string handle
+ * Return: GET_NON_KEY_ATTRIBUTE_SUCCESS, or
+ * GET_NON_KEY_ATTRIBUTE_ALLOCATION_FAILURE,
+ * GET_NON_KEY_ATTRIBUTE_GET_STRING_FAILURE
+ * Description: Reads a non-key attribute from the current position of the
+ * file pointer. A non-key attribute is defined to be a
+ * white-space delimited string. The read will not cross an
+ * end-of-line indicated by a new line '\n' or carriage return
+ * '\r'. The primary reason for the routine is to copy over the
+ * results from getString() out of the static buffer to new
+ * memory allocated for the attribute.
+ * Calls: errorMessage()
+ * getString()
+ * System: malloc()
+ * strcpy()
+ * strlen()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for malloc() and NULL definitions */
+#include <stdio.h> /* for FILE definition */
+#include <string.h> /* for strcpy() and strlen() definitions */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "dataObject.h" /* for MAX_SIZE_OF_NON_KEY_ATTRIBUTE */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "getNonKeyAttribute.h" /* for getNonKeyAttribute() return codes */
+
+/*
+ * Function prototype
+ */
+extern Char *getString( FILE *file );
+
+Int getNonKeyAttribute( FILE *file, /* input stream to get string from */
+ Char **value ) /* handle to unallocated string */
+{ /* begin getNonKeyAttribute() */
+ Char *temp; /* value returned from getString() */
+ Int returnCode; /* return code for this routine */
+
+ static Char name[] = "getNonKeyAttribute";
+
+ assert( file );
+ assert( value );
+
+ /*
+ * Read string using special utility getString(). Check for error during
+ * read. If no error, allocate memory and copy over contents of value
+ * returned.
+ */
+ temp = getString( file );
+ if ( temp == NULL ) {
+ errorMessage( name, PREPEND );
+ *value = NULL;
+ returnCode = GET_NON_KEY_ATTRIBUTE_EOI;
+ } /* end of if *value == NULL */
+ else {
+ assert( strlen( temp ) < MAX_SIZE_OF_NON_KEY_ATTRIBUTE );
+
+ *value = malloc( strlen( temp ) + 1 ); /* allocate memory */
+ if ( *value == NULL ) { /* check for error */
+ errorMessage( "allocation failure", REPLACE );
+ errorMessage( name, PREPEND );
+ returnCode = GET_NON_KEY_ATTRIBUTE_ALLOCATION_FAILURE;
+ } /* end of value == NULL */
+ else { /* copy over string */
+ strcpy( *value, temp );
+ returnCode = GET_NON_KEY_ATTRIBUTE_SUCCESS;
+ } /* end of else - value != NULL */
+ } /* end of if temp != NULL */
+
+ return ( returnCode );
+} /* end of getNonKeyAttribute() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNonKeyAttribute.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNonKeyAttribute.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNonKeyAttribute.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getNonKeyAttribute.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,37 @@
+
+/*
+ * DIS Data Management: getNonKeyAttribute
+ *
+ * This header file contains the return codes for the getNonKeyAttribute
+ * routine. The routine reads a non-key attribute from the input FILE
+ * stream which is defined to be a space-delimited string, but does not
+ * cross an end-of-line indicator as the default system routines do.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_GET_NON_KEY_ATTRIBUTE_H
+#define DIS_GET_NON_KEY_ATTRIBUTE_H
+
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive type definitions */
+
+/*
+ * Return Codes
+ */
+#define GET_NON_KEY_ATTRIBUTE_SUCCESS 0
+#define GET_NON_KEY_ATTRIBUTE_ALLOCATION_FAILURE 1
+#define GET_NON_KEY_ATTRIBUTE_EOI 2
+
+/*
+ * Function Prototype
+ */
+extern Int getNonKeyAttribute( FILE *file, Char **value );
+
+#endif /* DIS_GET_NON_KEY_ATTRIBUTE_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getQueryCommand.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getQueryCommand.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getQueryCommand.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getQueryCommand.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,222 @@
+
+/*
+ * Name: getQueryCommand
+ * Input: FILE pointer
+ * Output: index key
+ * list of non-key data attributes
+ * Return: GET_QUERY_SUCCESS, or
+ * GET_QUERY_IO_ERROR,
+ * GET_QUERY_EARLY_EOI,
+ * GET_QUERY_INVALID_CODE_ERROR,
+ * GET_QUERY_ALLOCATION_ERROR
+ * Description: The routine reads a Query command from input stream via
+ * FILE pointer. Assumes that the current stream pointer
+ * position is correct, and returns the file pointer open and
+ * the current position immediately after the command just
+ * read. The file pointer is expected to be at the beginning
+ * of the Query command immediately after the command code.
+ * The Query command consists of a list of attribute code and
+ * value pairs. An error occurs if any attribute code does
+ * not have an accompanying value, an attribute code is
+ * out-of-range as specified in the DIS Benchmark Suite: Data
+ * Management, or an I/O error occurs reading the values from
+ * the stream. For any error during the read, the routine
+ * will leave the current values of the command attribute list
+ * intact and clear the FILE pointer to the end of the current
+ * line.
+ *
+ * A Query command is made up of a list of attribute code and
+ * value pairs. The total number of pairs can range from zero
+ * to the MAX_ATTRIBUTE_CODE. Each command is carriage return
+ * delimited, i.e., one line per command. So, to read a Query
+ * command, read until the end-of-line indicator is
+ * encountered.
+ *
+ * It is possible to have a Query command return an empty
+ * attribute list without producing an error. Since missing
+ * attributes are defaulted to "wild-card" values, this type
+ * of query would logically return the entire database. This
+ * type of query is a valid Query command as defined by the
+ * DIS Benchmark Suite: Data Management document.
+ * Calls: errorMessage()
+ * getInt()
+ * getKeyAttribute()
+ * getNonKeyAttribute()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for NULL */
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive data types */
+#include "dataObject.h" /* for DataAttribute definition */
+#include "indexKey.h" /* for IndexKey definition */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "getInt.h" /* for getInt() and return code definitions */
+#include "getFloat.h" /* for getFloat() and return code definitions */
+#include "getKeyAttribute.h" /* for prototype and return code definitions */
+#include "getNonKeyAttribute.h" /* for prototype and return code definitions */
+#include "getQueryCommand.h" /* for getQueryCommand() return codes */
+
+Int getQueryCommand( FILE *file, /* file for reading */
+ IndexKey *searchKey, /* index key */
+ DataAttribute **searchNonKey ) /* list of attributes */
+{ /* begin getQueryCommand() */
+ Int attributeCode; /* attribute code read from file */
+ Int returnCode; /* return code from various routines */
+
+ static Char name[] = "getQueryCommand";
+
+ assert( file );
+ assert( searchKey );
+ assert( MIN_ATTRIBUTE_CODE < NUM_OF_KEY_ATTRIBUTES );
+ assert( MIN_ATTRIBUTE_CODE < MAX_ATTRIBUTE_CODE );
+ assert( MAX_ATTRIBUTE_CODE < NUM_OF_LARGE_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_SMALL_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_MEDIUM_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_LARGE_ATTRIBUTES );
+
+ /*
+ * Set the values for the index key and non-key list to wild-card values.
+ * The key values are float, and the wild-card is a hyper-cube of maximum
+ * volume. The non-key values are char, and the wild-card values are NULL
+ * with an empty list.
+ */
+ searchKey->lower.T = MINIMUM_VALUE_OF_FLOAT;
+ searchKey->lower.X = MINIMUM_VALUE_OF_FLOAT;
+ searchKey->lower.Y = MINIMUM_VALUE_OF_FLOAT;
+ searchKey->lower.Z = MINIMUM_VALUE_OF_FLOAT;
+ searchKey->upper.T = MAXIMUM_VALUE_OF_FLOAT;
+ searchKey->upper.X = MAXIMUM_VALUE_OF_FLOAT;
+ searchKey->upper.Y = MAXIMUM_VALUE_OF_FLOAT;
+ searchKey->upper.Z = MAXIMUM_VALUE_OF_FLOAT;
+
+ *searchNonKey = NULL;
+
+ /*
+ * A Query command is made up of a list of attribute code and value pairs.
+ * The total number of pairs can range from zero to MAX_ATTRIBUTE_CODE.
+ * Each command is on a separate line, i.e., an end-of-line indicator is
+ * used to delimit commands. So, to read the Query command, read
+ * code/value pairs until an end-of-line indicator.
+ */
+ returnCode = GET_INT_SUCCESS;
+ while ( returnCode != GET_INT_EOI ) {
+ /*
+ * Read the attribute code first and check return code. If a
+ * successful read, check range of code for error. If code is in
+ * range, check for key or non-key attribute. For key attribute, read
+ * in float value. For non-key attribute, read in character string.
+ * For each type of read, check for errors.
+ */
+ returnCode = getInt( file, &attributeCode );
+ if ( returnCode == GET_INT_SUCCESS ) {
+ if ( attributeCode < MIN_ATTRIBUTE_CODE || /* check code range */
+ attributeCode > MAX_ATTRIBUTE_CODE ) {
+ errorMessage( "code out-of-range", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_QUERY_INVALID_CODE_ERROR );
+ } /* end of check for invalid code */
+ else if ( attributeCode < NUM_OF_KEY_ATTRIBUTES ) {
+ Float value;
+
+ returnCode = getKeyAttribute( file, &value );
+ if ( returnCode == GET_KEY_ATTRIBUTE_SUCCESS ) {
+ if ( attributeCode == LOWER_POINT_T ) {
+ searchKey->lower.T = value;
+ } /* end of LOWER_POINT_T */
+ else if ( attributeCode == LOWER_POINT_X ) {
+ searchKey->lower.X = value;
+ } /* end of LOWER_POINT_X */
+ else if ( attributeCode == LOWER_POINT_Y ) {
+ searchKey->lower.Y = value;
+ } /* end of LOWER_POINT_Y */
+ else if ( attributeCode == LOWER_POINT_Z ) {
+ searchKey->lower.Z = value;
+ } /* end of LOWER_POINT_Z */
+ else if ( attributeCode == UPPER_POINT_T ) {
+ searchKey->upper.T = value;
+ } /* end of UPPER_POINT_T */
+ else if ( attributeCode == UPPER_POINT_X ) {
+ searchKey->upper.X = value;
+ } /* end of UPPER_POINT_X */
+ else if ( attributeCode == UPPER_POINT_Y ) {
+ searchKey->upper.Y = value;
+ } /* end of UPPER_POINT_Y */
+ else if ( attributeCode == UPPER_POINT_Z ) {
+ searchKey->upper.Z = value;
+ } /* end of UPPER_POINT_Z */
+ } /* end of GET_KEY_ATTRIBUTE_SUCCESS */
+ else if ( returnCode == GET_KEY_ATTRIBUTE_EOI ) {
+ errorMessage( "improper format - early EOI", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_QUERY_EARLY_EOI );
+ } /* end returnCode == GET_KEY_ATTRIBUTE_GET_FLOAT_FAILURE */
+ else if ( returnCode == GET_KEY_ATTRIBUTE_GET_FLOAT_FAILURE ) {
+ errorMessage( "low-level I/O error", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_QUERY_IO_ERROR );
+ } /* end returnCode == GET_KEY_ATTRIBUTE_GET_FLOAT_FAILURE */
+ } /* end of key attribute */
+ else {
+ Char *value;
+
+ returnCode = getNonKeyAttribute( file, &value );
+ if ( returnCode == GET_NON_KEY_ATTRIBUTE_SUCCESS ) {
+ DataAttribute *newAttribute;
+
+ /*
+ * Allocate new DataAttribute, store values of attribute
+ * code and attribute string, and add new DataAttribute to
+ * output list.
+ */
+ newAttribute =
+ (DataAttribute *)malloc( sizeof( DataAttribute ) );
+ if ( newAttribute == NULL ) {
+ errorMessage( "allocation failure", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_QUERY_ALLOCATION_ERROR );
+ } /* end of if ( attribute == NULL ) */
+
+ newAttribute->code = attributeCode;
+ newAttribute->attribute.value.nonKey = value;
+
+ newAttribute->next = *searchNonKey;
+ *searchNonKey = newAttribute;
+ }
+ else if ( returnCode == GET_NON_KEY_ATTRIBUTE_EOI ){
+ errorMessage( "improper format - early EOI", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_QUERY_EARLY_EOI );
+ } /* end of if returnCode == GET_NON_KEY_ATTRIBUTE_EOI */
+ else if ( returnCode==GET_NON_KEY_ATTRIBUTE_ALLOCATION_FAILURE){
+ errorMessage( "allocation of non-key attribute", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( GET_QUERY_ALLOCATION_ERROR );
+ } /* end of if ( returnCode == ALLOCATION_FAILURE ) */
+ } /* end of non-key attribute */
+ } /* end of if ( returnCode == GET_INT_SUCCESS ) */
+ else if ( returnCode == GET_INT_EOI ) {
+ /*
+ * empty
+ */
+ } /* end of if ( returnCode == GET_INT_EOI ) */
+ else if ( returnCode == GET_INT_RANGE_EXCEEDED ) {
+ return ( GET_QUERY_INVALID_CODE_ERROR );
+ } /* end of if ( error == GET_INT_RANGE_EXCEEDED ) */
+ else if ( returnCode == GET_INT_BAD_CONVERSION ) {
+ return ( GET_QUERY_INVALID_CODE_ERROR );
+ } /* end of if ( error == GET_INT_BAD_CONVERSION ) */
+ }
+
+ return ( GET_QUERY_SUCCESS );
+} /* end of getQueryCommand() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getQueryCommand.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getQueryCommand.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getQueryCommand.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getQueryCommand.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,46 @@
+
+/*
+ * DIS Data Management: getQueryCommand
+ *
+ * This header file defines the return codes for the getQueryCommand
+ * function. Any file which uses the getQueryCommand routine should
+ * include this header. The first code indicates success. The second
+ * code is the result of an I/O error at a lower-level read function. The
+ * third code indicates that an end-of-line or end-of-file indicator was
+ * read before insert command was finished. The fourth error is when an
+ * attribute code is unknown or invalid. The fifth error is an allocation
+ * error for the non-key attribute character strings.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_GET_QUERY_COMMAND_H
+#define DIS_GET_QUERY_COMMAND_H
+
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive data types */
+#include "dataObject.h" /* for DataAttribute definition */
+#include "indexKey.h" /* for IndexKey definition */
+
+/*
+ * Return codes
+ */
+#define GET_QUERY_SUCCESS 0
+#define GET_QUERY_IO_ERROR 1
+#define GET_QUERY_EARLY_EOI 2
+#define GET_QUERY_INVALID_CODE_ERROR 3
+#define GET_QUERY_ALLOCATION_ERROR 4
+
+/*
+ * Function Prototype
+ */
+extern Int getQueryCommand( FILE *file, IndexKey *searchKey,
+ DataAttribute **searchNonKey );
+
+#endif /* DIS_GET_QUERY_COMMAND_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getString.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getString.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getString.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/getString.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,138 @@
+
+/*
+ * Name: getString
+ * Input: FILE ptr
+ * Output: character string pointer
+ * Return: Char pointer to string read, or
+ * NULL if error
+ * Description: Reads a white-space delimited string from the current
+ * position of the file pointer. The read will not cross an
+ * end-of-line indicated by a new line '\n' or carriage return
+ * '\r'. If an end-of-line indicator is read before a string
+ * is encountered, the indicator is put back onto the stream
+ * and an error code is returned. The maximum length of a
+ * string is set at 1024 as defined by the DIS Benchmark
+ * Suite: Data Management Bechmark, for a non-key attribute.
+ * The length will also work for integers and floats which use
+ * this routine for reading. The routine returns a pointer to
+ * its internal static buffer which holds the string just read.
+ * If an error occurs during the read, a NULL is returned.
+ * Calls: errorMessage()
+ * System: fgetc()
+ * isspace()
+ * strlen()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <ctype.h> /* for isspace() definition */
+#include <stdlib.h> /* for NULL definition */
+#include <stdio.h> /* for FILE definition */
+#include <string.h> /* for strlen() definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "errorMessage.h" /* for errorMessage() definition */
+
+/*
+ * Maximum length of buffer for temporary storage of string
+ */
+#define MAXIMUM_BUFFER_LENGTH 1024
+
+Char *getString( FILE *file ) /* input stream to get string from */
+{ /* begin getString() */
+ Int nextChar; /* next character read from stream */
+ Int bufferLength; /* current length of static buffer */
+ /* static buffer for reading */
+ static Char buffer[ MAXIMUM_BUFFER_LENGTH + 1 ];
+
+ static Char name[] = "getString";
+
+ assert( file );
+
+ /*
+ * Skip all "whitespace" before the beginning of the string. Note that
+ * the carriage return, '\r', and new line, '\n', characters are not
+ * included as "whitespace" for this routine. After the loop which skips
+ * the "whitespace", a check is made to determine if the last character
+ * read indicates EOF. If so, an error is returned since no string value
+ * was read. Also, a check is made to see if the last character read is a
+ * new line or carriage return. If so, the last character is "put back"
+ * onto the stream and an error is returned since no string value was read.
+ * The value is "put back" since the next call to getString should also
+ * indicate that there are no string values left on this line.
+ */
+ nextChar = fgetc( file );
+ while ( nextChar != EOF &&
+ nextChar != '\n' &&
+ nextChar != '\r' &&
+ isspace( nextChar ) ) {
+ nextChar = fgetc( file );
+ } /* end of loop while ( !EOF || '\n', etc. ) */
+
+ if ( nextChar == EOF ) {
+ return ( NULL ); /* return output value of NULL */
+ } /* end of if ( nextChar == EOF ) */
+ else if ( nextChar == '\n' || nextChar == '\r' ) {
+ ungetc( nextChar, file ); /* "push" character back on stream */
+ return ( NULL ); /* return output value of NULL */
+ } /* end of if ( nextChar == '\n' || nextChar == '\r' ) */
+
+ /*
+ * Read string until next delimiter, i.e., a white space, or EOF. Add
+ * character to buffer and increase buffer length. Check length for
+ * overflow during loop. If overflow occurs, copy value in buffer to
+ * value and return with error flag. After loop, copy value of buffer to
+ * value allocating memory.
+ */
+ buffer[ 0 ] = nextChar;
+ bufferLength = 1;
+
+ nextChar = fgetc( file );
+ while ( nextChar != EOF && !isspace( nextChar ) ) {
+ if ( bufferLength >= MAXIMUM_BUFFER_LENGTH ) {
+ errorMessage( "maximum buffer length exceeded", REPLACE );
+ errorMessage( name, PREPEND );
+ flushErrorMessage();
+
+ buffer[ bufferLength + 1 ] = '\0'; /* terminate string */
+ return ( buffer ); /* return current buffer */
+ } /* end of if ( bufferLength >= MAXIMUM_BUFFER_LENGTH ) */
+
+ buffer[ bufferLength ] = (Char)nextChar;
+ bufferLength++;
+
+ nextChar = fgetc( file );
+ } /* end of loop for nextChar != EOF and !isspace */
+
+ buffer[ bufferLength ] = '\0'; /* terminate string */
+
+ /*
+ * The last character read from stream is an EOF, end-of-line indicator,
+ * or a white space character. Except for EOF, push all other characters
+ * back onto stream for the next read. The getString routine will NEVER
+ * read beyond the current line and will NOT remove the end-of-line
+ * character from the input stream. In case pushing the last character
+ * back onto the stream fails, delete the string and return error code.
+ */
+ if ( nextChar != EOF ) {
+ Int check;
+
+ check = ungetc( nextChar, file );
+ if ( check != nextChar || check == EOF ) {
+ errorMessage( "error pushing character back onto stream", REPLACE );
+ errorMessage( name, PREPEND );
+ flushErrorMessage();
+
+ return ( NULL ); /* return current buffer */
+ } /* end of if check != nextChar || check == EOF */
+ } /* end of if ( nextChar != EOF ) */
+
+ return ( buffer );
+} /* end of getString() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/index.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/index.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/index.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/index.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,99 @@
+
+/*
+ * DIS Data Management Index
+ *
+ * This file contains the index structures for the DIS R-Tree basline
+ * application. The two structures defined are for index entries and for
+ * index nodes.
+ *
+ * An index entry will reference either an index node or a
+ * data object. All entries which are in the index reside on an index
+ * node. An entry which resides on a leaf node (level = 0) references a
+ * data object, while an entry which resides on a non-leaf node (level > 0)
+ * references an index node. Since the entry may reference two different
+ * types of objects, the member is a union between the two types. The
+ * entry contains an index key which is used for traversals of the index.
+ * For the R-Tree index, the index key is the hyper-cube which minimally
+ * encloses the object it references. If the child reference is a data
+ * object, the index key for the entry is the appropriate values of the
+ * data object. If the child reference is an index node, the index key of
+ * the entry is the bounding hyper-cube of all of the entries residing on
+ * that node. The final member of the index entry structure is a pointer
+ * to another index entry structure which gives linked-list behavior to
+ * entries.
+ *
+ * An index node is a container of a list of index entries. Each node
+ * contains an integer level value. Note that the leaf level is zero and
+ * the level increases as the tree is ascended, i.e., the root level is
+ * always greater than or equal to the leaf level. The number of entries
+ * in the list is always between one and the fan or order of the index.
+ * Note that the fan of the index is read at run-time, so a fixed array of
+ * entries is not permitted.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_INDEX_H
+#define DIS_INDEX_H
+
+#include "dataManagement.h" /* for basic data types */
+#include "dataObject.h" /* for data object definition */
+#include "indexKey.h" /* for index key definition */
+
+/*
+ * Index Node
+ * - contains a list of entries which reside on node
+ * - has a level specifier where all levels are greater than or equal to
+ * the LEAF level.
+ */
+typedef struct
+{
+ Int level; /* level where node resides in index */
+ struct IndexEntry *entries; /* list of entries on node */
+} IndexNode;
+
+/*
+ * Prototypes for routines which create, delete, and display IndexNode
+ * structures.
+ */
+
+extern IndexNode *createIndexNode( Int level );
+extern void deleteIndexNode( IndexNode * node );
+extern void outputIndexNode( IndexNode * node, Int indent );
+
+/*
+ * Index Entry
+ * - references a child object, either a data object or index node
+ * - has a key which "encloses" the child object
+ * - has a pointer to support single link-list capability
+ */
+struct IndexEntry
+{
+ union {
+ IndexNode *node;
+ DataObject *dataObject;
+ } child;
+
+ IndexKey key;
+
+ struct IndexEntry *next;
+};
+
+typedef struct IndexEntry IndexEntry;
+
+/*
+ * Prototypes for routines which create, delete, and display IndexEntry
+ * structures.
+ */
+
+extern IndexEntry *createIndexEntry( void );
+extern void deleteIndexEntry( IndexEntry * entry, Int level );
+extern void outputIndexEntry( IndexEntry * entry, Int level, Int indent );
+
+#endif /* DIS_INDEX_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/indexKey.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/indexKey.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/indexKey.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/indexKey.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,55 @@
+
+/*
+ * DIS Data Management Index Key
+ *
+ * Definitions of the index key used for the application. An index key is
+ * defined as two hyper-points representing the "upper" and "lower" points
+ * and defines a hyper-cube. Each hyper-point is four-dimensional with
+ * parameters T, X, Y, and Z. The index key is used to represent the key
+ * values of data objects and bounding boxes for the R-Tree index. A
+ * valid index key will lower hyper-point values less than or equal to the
+ * upper hyper-point values for all four values in a hyper-point.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_INDEX_KEY_H
+#define DIS_INDEX_KEY_H
+
+#include "dataManagement.h"
+
+/*
+ * Index Point structure
+ * - defines single point in hyper-space (4D)
+ * - used as bounding points for hyper-cubes which are the index key for
+ * the R-Tree algorithm.
+ */
+
+typedef struct {
+ Float T;
+ Float X;
+ Float Y;
+ Float Z;
+} IndexPoint;
+
+/*
+ * Index Key structure
+ * - represents the key for the R-Tree index
+ * - defines a hyper-cube by specifying the lower and upper hyper-points
+ * for the hyper-cube.
+ * - for a valid index key, all values of lower point MUST be less than or
+ * equal to the values for the upper point.
+ */
+
+typedef struct {
+ IndexPoint lower; /* lower point of hyper-cube */
+ IndexPoint upper; /* upper point of hyper-cube */
+} IndexKey;
+
+#endif /* DIS_INDEX_KEY_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/initMetricsData.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/initMetricsData.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/initMetricsData.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/initMetricsData.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,110 @@
+
+/*
+ * Name: initMetricsData
+ * Input: Metrics structure
+ * Output: none
+ * Return: void
+ * Description: This routine initializes the Metrics module by setting the
+ * appropriate values and/or flags for later metric collection.
+ * The timing information for total execution time, input time,
+ * and output time are set to the current system time returned
+ * as timing marks for later processing.
+ *
+ * The individual command metric data are also initialized to
+ * either logical values (number of commands, sum of command
+ * times, sum of squares of command times) or to "highly
+ * unlikely" values (worst, best, average, deviation) which
+ * should be easily noticed if output.
+ *
+ * The routine updateMetricsData() uses the value of the
+ * lastCommand field to determine which command metric to
+ * update. The first time through, there is no command so an
+ * initial value of NONE is placed in the field. The
+ * updateMetricsData() routine should interpret this value so as
+ * not to update any command metrics structure for that call.
+ * Calls: getTime()
+ * initTime()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "metrics.h" /* for Metrics definition */
+
+/*
+ * Function prototypes
+ */
+extern void initTime( void );
+extern Time getTime( void );
+
+void initMetricsData( Metrics *metrics ) /* metrics struct to initialize */
+{ /* begin initMetricsData() */
+ Time temp; /* variable used to find current time */
+
+ assert( metrics );
+
+ /*
+ * Initialize timer
+ */
+ initTime();
+
+ /*
+ * Setup timing marks for metric collection
+ */
+ temp = getTime();
+ metrics->totalTime = temp;
+ metrics->inputTime = temp;
+ metrics->outputTime = temp;
+
+ /*
+ * Set initial values for each command metric. The statistical values for
+ * the worst, best, average, and standard deviation values are set to
+ * "impossible" values which should be easily noticed if unchanged and
+ * output as a metric result.
+ */
+ metrics->insertCommandMetric.lastTimeMark = MINIMUM_VALUE_OF_TIME;
+ metrics->insertCommandMetric.numOfCommands = 0;
+ metrics->insertCommandMetric.sum = 0.0;
+ metrics->insertCommandMetric.sumSquares = 0.0;
+ metrics->insertCommandMetric.worst = MINIMUM_VALUE_OF_TIME;
+ metrics->insertCommandMetric.best = MAXIMUM_VALUE_OF_TIME;
+ metrics->insertCommandMetric.avg = MINIMUM_VALUE_OF_FLOAT;
+ metrics->insertCommandMetric.deviation = MINIMUM_VALUE_OF_FLOAT;
+
+ metrics->queryCommandMetric.lastTimeMark = MINIMUM_VALUE_OF_TIME;
+ metrics->queryCommandMetric.numOfCommands = 0;
+ metrics->queryCommandMetric.sum = 0.0;
+ metrics->queryCommandMetric.sumSquares = 0.0;
+ metrics->queryCommandMetric.worst = MINIMUM_VALUE_OF_TIME;
+ metrics->queryCommandMetric.best = MAXIMUM_VALUE_OF_TIME;
+ metrics->queryCommandMetric.avg = MINIMUM_VALUE_OF_FLOAT;
+ metrics->queryCommandMetric.deviation = MINIMUM_VALUE_OF_FLOAT;
+
+ metrics->deleteCommandMetric.lastTimeMark = MINIMUM_VALUE_OF_TIME;
+ metrics->deleteCommandMetric.numOfCommands = 0;
+ metrics->deleteCommandMetric.sum = 0.0;
+ metrics->deleteCommandMetric.sumSquares = 0.0;
+ metrics->deleteCommandMetric.worst = MINIMUM_VALUE_OF_TIME;
+ metrics->deleteCommandMetric.best = MAXIMUM_VALUE_OF_TIME;
+ metrics->deleteCommandMetric.avg = MINIMUM_VALUE_OF_FLOAT;
+ metrics->deleteCommandMetric.deviation = MINIMUM_VALUE_OF_FLOAT;
+
+ /*
+ * The routine updateMetricsData() expects the lastCommand field of the
+ * Metric structure to indicate which command metric should be updated.
+ * The value is set to INVALID for initialization, but should be set before
+ * the first call to updateMetricsData().
+ */
+ metrics->lastCommand = INVALID;
+
+ return;
+} /* end of initMetricsData() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insert.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insert.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insert.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insert.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,186 @@
+
+/*
+ * Name: insert
+ * Input: root node of index, root
+ * new index entry to place, entry
+ * fan or order of index, fan
+ * Output: updated node, node
+ * Return: INSERT_SUCCESS, or
+ * INSERT_INSERT_ENTRY_FAILURE_FATAL,
+ * INSERT_INSERT_ENTRY_FAILURE_NON_FATAL,
+ * INSERT_ALLOCATION_FAILURE
+ * Description: The insert routine places a data object into the index with
+ * the specified fan. The index is input as the root node and
+ * the root node is returned as the output. The insert method
+ * descends the tree until the LEAF level is reached. Note
+ * that the leaf level is zero and the level increases as the
+ * tree is ascended, i.e., the root level is always greater
+ * than or equal to the leaf level. The branch or node chosen
+ * for descent is determined by comparing the penalty for all
+ * possible branches and the new data object. The branch with
+ * the smallest or minimum penalty is chosen. Once the correct
+ * level is reached, a node is chosen on that level (in the
+ * same manner as a branch is chosen) and the new data object
+ * is placed on that node. Placement of the object may exceed
+ * the specified fan which causes the node to split. The node
+ * split separates or partitions the union of the old entries
+ * of the node and the new data object/entry into two groups.
+ * One group is placed back onto the old node, and the other
+ * group is placed onto the parent of the old node, i.e., a
+ * sibling node is created for the second group of partitioned
+ * entries. The addition of the sibling node to the parent may
+ * cause the parent to split, etc. This splitting may ascend
+ * to the root node which by definition has no parent and is a
+ * special case. When the root node is split, a new root is
+ * created which "grows" the index tree. The old root and the
+ * node split off of the old root are then placed onto the new
+ * root, and the new root is returned as the updated index.
+ *
+ * The insert() routine creates a new index entry for the data
+ * object. Then, the routine places the new entry into the
+ * index using the insertEntry() subroutine to recursively
+ * descend the index tree. The root node is used to begin the
+ * descent. If the root node splits, the insertEntry parameter
+ * will be non-NULL and the index tree "grows" by creating a
+ * new root and placing the old root and splitEntry parameter
+ * onto the new root. The primary difference between the
+ * insert() and insertEntry() routines is that insert() is used
+ * for the special case of the root node, while insertEntry()
+ * is for every other node. The reason the implementation uses
+ * both is because every node has a parent for splitEntry
+ * placements except the root node. This special case could be
+ * handled by a conditional check within a modified
+ * insertEntry() routine which would eliminate an "extra"
+ * subroutine since there would be no need for insert().
+ * However, then each node would need to be checked to see if
+ * it's the root and the extra links or parameters
+ * would unnecessarily complicate the source code.
+ * Calls: createIndexEntry()
+ * createIndexNode()
+ * errorMessage()
+ * insertEntry()
+ * keysUnion()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for NULL definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "dataObject.h" /* for DataObject definition */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "index.h" /* for IndexNode and IndexEntry definitions */
+#include "insertEntry.h" /* for insertEntry() and return code definitions */
+#include "insert.h" /* for insert() return codes */
+
+/*
+ * Function prototypes
+ */
+extern void keysUnion( IndexEntry *I, IndexKey *U );
+
+Int insert( IndexNode **root, /* root node of index */
+ DataObject *dataObject, /* object to insert into index */
+ Int fan ) /* fan or order of index */
+{ /* beginning of insert() */
+ IndexEntry *entry; /* entry created for data object */
+ IndexEntry *splitEntry; /* placeholder for splitEntry for insertEntry() */
+ Int returnCode; /* return code for insertEntry() */
+
+ static Char name[] = "insert";
+
+ assert( root );
+ assert( *root );
+ assert( dataObject );
+ assert( dataObject->attributes );
+ assert( MINIMUM_FAN_SIZE > 1 );
+ assert( fan >= MINIMUM_FAN_SIZE );
+
+ /*
+ * Create index entry for data object and set reference and index key to
+ * appropriate values.
+ */
+ entry = createIndexEntry();
+ if ( entry == NULL ) {
+ errorMessage( "can't create entry for new data object", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( INSERT_ALLOCATION_FAILURE );
+ } /* end of entry == NULL */
+ entry->child.dataObject = dataObject;
+ entry->key.lower.T = dataObject->attributes[ LOWER_POINT_T ].value.key;
+ entry->key.lower.X = dataObject->attributes[ LOWER_POINT_X ].value.key;
+ entry->key.lower.Y = dataObject->attributes[ LOWER_POINT_Y ].value.key;
+ entry->key.lower.Z = dataObject->attributes[ LOWER_POINT_Z ].value.key;
+ entry->key.upper.T = dataObject->attributes[ UPPER_POINT_T ].value.key;
+ entry->key.upper.X = dataObject->attributes[ UPPER_POINT_X ].value.key;
+ entry->key.upper.Y = dataObject->attributes[ UPPER_POINT_Y ].value.key;
+ entry->key.upper.Z = dataObject->attributes[ UPPER_POINT_Z ].value.key;
+
+ /*
+ * Place new entry into index using recursive routine insertEntry() which
+ * will descend the index until the leaf level. Check return code for
+ * success and error conditions. If successful insert, then check for
+ * splitting.
+ */
+ returnCode = insertEntry( *root, entry, LEAF, fan, &splitEntry );
+ if ( returnCode == INSERT_ENTRY_SUCCESS ) {
+ /*
+ * The new entry has been successfully inserted somewhere beneath
+ * the root node. If a split occurred, then splitEntry references a
+ * new sibling node. Since the root node has no parent, a new parent
+ * node is created which becomes the new root node. The old node and
+ * splitEntry are placed onto this new root.
+ */
+ if ( splitEntry != NULL ) { /* check for root splitting */
+ IndexNode *newRoot = NULL;
+
+ /*
+ * Create new root node and new entry which will reference old root
+ */
+ newRoot = createIndexNode( (*root)->level + 1 );
+ if ( newRoot == NULL ) {
+ errorMessage( "can't create new root node", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( INSERT_ALLOCATION_FAILURE );
+ } /* end of newRoot == NULL */
+
+ newRoot->entries = createIndexEntry();
+ if ( newRoot->entries == NULL ) {
+ errorMessage( "can't create entry for old root", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( INSERT_ALLOCATION_FAILURE );
+ } /* end of newRoot->entries == NULL */
+
+ /*
+ * Setup new entry for old root, which will also place old root
+ * onto new root node. Place splitEntry onto new root.
+ */
+ newRoot->entries->child.node = *root;
+ keysUnion( (*root)->entries, &(newRoot->entries->key) );
+ newRoot->entries->next = splitEntry;
+
+ /*
+ * Set root to updated value
+ */
+ *root = newRoot;
+ } /* end of if ( splitEntry != NULL ) */
+ } /* end of returnCode == INSERT_ENTRY_SUCCESS */
+ else if ( returnCode == INSERT_ENTRY_CHOOSE_ENTRY_FAILURE ) {
+ return ( INSERT_INSERT_ENTRY_FAILURE_NON_FATAL );
+ } /* end of returnCode == INSERT_ENTRY_CHOOSE_ENTRY_FAILURE */
+ else if ( returnCode == INSERT_ENTRY_SPLIT_NODE_FATAL ) {
+ return ( INSERT_INSERT_ENTRY_FAILURE_FATAL );
+ } /* end of returnCode == INSERT_ENTRY_SPLIT_NODE_FATAL */
+ else if ( returnCode == INSERT_ENTRY_SPLIT_NODE_NON_FATAL ) {
+ return ( INSERT_INSERT_ENTRY_FAILURE_NON_FATAL );
+ } /* end of returnCode == INSERT_ENTRY_SPLIT_NODE_NON_FATAL */
+
+ return ( INSERT_SUCCESS );
+} /* end insert() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insert.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insert.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insert.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insert.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,47 @@
+
+/*
+ * DIS Data Management: insert
+ *
+ * This header file contains the return codes for the insert routine
+ * and the function prototype. There are three different failure modes for
+ * the routine. The first two indicate that an error occurred during the
+ * insertEntry() recursive call chain. The error can be either FATAL
+ * indicating that the index was changed prior to the error which means the
+ * index can't be guaranteed to be in a valid state and should not be
+ * manipulated any further. The error can also be NON-FATAL indicating
+ * that the index was not changed prior to the error and can be guaranteed
+ * to be in a valid state and can be manipulated, i.e., with other
+ * commands. The final error condition indicates a memory allocation
+ * failure when attempting to "grow" the index tree because of root node
+ * splitting.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_INSERT_H
+#define DIS_INSERT_H
+
+#include "dataManagement.h" /* for primitive type definitions */
+#include "dataObject.h" /* for DataObject definition */
+#include "index.h" /* for IndexNode definition */
+
+/*
+ * Return Codes
+ */
+#define INSERT_SUCCESS 0
+#define INSERT_INSERT_ENTRY_FAILURE_FATAL 1
+#define INSERT_INSERT_ENTRY_FAILURE_NON_FATAL 2
+#define INSERT_ALLOCATION_FAILURE 3
+
+/*
+ * Function prototype
+ */
+extern Int insert( IndexNode **root, DataObject *dataObject, Int fan );
+
+#endif /* DIS_INSERT_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insertEntry.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insertEntry.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insertEntry.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insertEntry.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,239 @@
+
+/*
+ * Name: insertEntry
+ * Input: node to place new entry, node
+ * new index entry to place, entry
+ * level to place entry, level
+ * fan or order of index, fan
+ * Output: updated node, node
+ * Return: INSERT_ENTRY_SUCCESS, or
+ * INSERT_ENTRY_CHOOSE_ENTRY_FAILURE,
+ * INSERT_ENTRY_SPLIT_NODE_FATAL,
+ * INSERT_ENTRY_SPLIT_NODE_NON_FATAL
+ * Description: Inserts entry into index starting at provided input node and
+ * at the specified level. If the current node is not at the
+ * specified level, i.e., above, the method chooseEntry() is
+ * used to determine which branch or entry of the current node
+ * to use and the insertEntry() routine is recursively called
+ * on that branch. This continues until the specified level
+ * has been reached. At the specified level, the entry is
+ * placed onto the node which may cause splitting. If so, the
+ * splitNode() method is used for the split. After the return
+ * for a recursive call to insertEntry(), the index key for the
+ * child is adjusted to correctly enclose the lower branches.
+ * Calls: chooseEntry()
+ * errorMessage()
+ * insertEntry()
+ * keysUnion()
+ * splitNode()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for NULL definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "index.h" /* for IndexNode and IndexEntry definitions */
+#include "splitNode.h" /* for splitNode() and return code definitions */
+#include "insertEntry.h" /* for insertEntry() return codes */
+
+/*
+ * Function prototypes
+ */
+extern void keysUnion( IndexEntry *I, IndexKey *U );
+extern IndexEntry * chooseEntry( IndexNode *node, IndexEntry *entry );
+
+Int insertEntry( IndexNode *node, /* node to begin insertion */
+ IndexEntry *entry, /* entry to insert into index */
+ Int level, /* level to place entry */
+ Int fan, /* fan or order of index */
+ IndexEntry **splitEntry ) /* possible entry after split */
+{ /* beginning of insertEntry() */
+ Int returnCode; /* return code for various function calls */
+
+ static Char name[] = "insertEntry";
+
+ assert( node );
+ assert( entry );
+ assert( level >= LEAF );
+ assert( MINIMUM_FAN_SIZE > 1 );
+ assert( fan >= MINIMUM_FAN_SIZE );
+
+ /*
+ * If the current node is not at the specified level, then choose a
+ * branch/entry and descend until correct level is reached.
+ */
+ if ( node->level > level ) {
+ IndexEntry *chosen;
+
+ assert( node->entries != NULL );
+
+ /*
+ * Since the current node is "higher" than the specified level of
+ * insertion, a branch or entry is chosen to descend the index tree.
+ * Note that the only way for chooseEntry() to fail is if there are no
+ * entries residing on the current node, which indicates an invalid
+ * index since any node whose level is greater than the LEAF level must
+ * have at least one entry for a balanced index.
+ *
+ * After an entry is chosen, the insertEntry() routine is recursively
+ * called using the chosen entry as the new node for insertion. The
+ * return code for the insertEntry() routine is checked for success and
+ * the three types of errors. All errors are propogated up the
+ * recursive call chain until the original calling routine is notified.
+ */
+ chosen = chooseEntry( node, entry );
+ if ( chosen == NULL ) {
+ errorMessage( "can't choose entry on node", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( INSERT_ENTRY_CHOOSE_ENTRY_FAILURE );
+ }
+
+ returnCode = insertEntry( chosen->child.node, entry, level, fan,
+ splitEntry );
+ if ( returnCode == INSERT_ENTRY_SUCCESS ) {
+ /*
+ * The new entry has been successfully inserted somewhere beneath
+ * the current node. The index key is adjusted to correctly
+ * "enclose" the lower hyper-cubes and a check is made for node
+ * splitting. If a split occurred, then splitEntry references a
+ * new sibling node which should be placed onto the current node.
+ * This may also cause splitting and that entry should be passed to
+ * the calling process. Eventually, the splitting may reach the
+ * root node and the index may grow (index growth is handled in the
+ * insert() routine).
+ */
+ keysUnion( (chosen->child.node)->entries, &chosen->key );
+
+ if ( *splitEntry != NULL ) { /* check for node splitting */
+ IndexEntry *lastEntry = NULL;
+ IndexEntry *tempEntry = NULL;
+ Int numberOfEntries = 0;
+
+ /*
+ * Determine the number of entries which currently reside on
+ * the node. Also, save the last entry in the list for later
+ * insertion. They are done at the same time to prevent a
+ * second "loop" through the index entry list.
+ */
+ tempEntry = node->entries;
+ lastEntry = tempEntry;
+ while ( tempEntry != NULL ) {
+ numberOfEntries++;
+ lastEntry = tempEntry;
+ tempEntry = tempEntry->next;
+ } /* end of loop for tempEntry */
+
+ /*
+ * If there is room on the current node, add splitEntry to the
+ * entry list and set splitEntry to NULL to inform the calling
+ * process that no new splitting occurred. Otherwise, split
+ * the current node and set splitEntry to the appropriate
+ * value. Note that splitting is done via the splitNode()
+ * routine which may return an allocation error. Any error
+ * which occurs at a level greater than the LEAF level is a
+ * fatal error since the index has been altered before the
+ * error occurs. Since the index has been altered, no
+ * gaurantee can be made on the state of the index and a fatal
+ * error follows.
+ */
+ if ( numberOfEntries < fan ) { /* there is room on node */
+ lastEntry->next = *splitEntry;
+ *splitEntry = NULL;
+ } /* end of if ( numberOfEntries < fan ) */
+ else { /* no room on node - split */
+ returnCode = splitNode( node, *splitEntry, fan, &tempEntry);
+ if ( returnCode == SPLIT_NODE_SUCCESS ) {
+ *splitEntry = tempEntry;
+ } /* end if SPLIT_NODE_SUCCESS */
+ else if ( returnCode == SPLIT_NODE_ALLOCATION_FAILURE ) {
+ return ( INSERT_ENTRY_SPLIT_NODE_FATAL );
+ } /* end if SPLIT_NODE_ALLOCATION_FAILURE */
+ } /* end of numberOfEntries >= fan */
+ } /* end of if ( *splitEntry != NULL ) */
+ } /* end of returnCode == INSERT_ENTRY_SUCCESS */
+ else if ( returnCode == INSERT_ENTRY_CHOOSE_ENTRY_FAILURE ||
+ returnCode == INSERT_ENTRY_SPLIT_NODE_FATAL ||
+ returnCode == INSERT_ENTRY_SPLIT_NODE_NON_FATAL ) {
+ /*
+ * Any error which occurs during a recursive call to insertEntry()
+ * will be propogated back up the recursive call "chain" until the
+ * original calling process is informed.
+ */
+ return ( returnCode );
+ } /* end of returnCode == recursive call failure */
+ } /* end of if ( node->level > level ) */
+ else {
+ IndexEntry *lastEntry = NULL;
+ IndexEntry *tempEntry = NULL;
+ Int numberOfEntries = 0;
+
+ /*
+ * Determine the number of entries which currently reside on the node.
+ * Also, save the last entry in the list for later insertion. They are
+ * done at the same time to prevent a second "loop" through the index
+ * entry list.
+ */
+ tempEntry = node->entries;
+ lastEntry = tempEntry;
+ while ( tempEntry != NULL ) {
+ numberOfEntries++;
+ lastEntry = tempEntry;
+ tempEntry = tempEntry->next;
+ } /* end of loop for tempEntry */
+
+ /*
+ * If there is room on the current node, add splitEntry to the entry
+ * list and set splitEntry to NULL to inform the calling process that
+ * no new splitting occurred. Otherwise, split the current node and
+ * set splitEntry to the appropriate value. Note that splitting is
+ * done via the splitNode() routine which may return an allocation
+ * error. Any error which occurs at a level greater than the LEAF
+ * level is a fatal error since the index has been altered before the
+ * error occurs. Since the index has been altered, no gaurantee can be
+ * made on the state of the index and a fatal error follows. However,
+ * a splitNode() error which occurs for a LEAF node is non-fatal since
+ * the index is unchanged and its state can be gauranteed.
+ */
+ if ( numberOfEntries < fan ) { /* there is room on node */
+ /*
+ * Note that it's possible to have an empty node at the leaf level,
+ * i.e., the node is the root, so a check must be made to ensure
+ * that lastEntry is a valid reference.
+ */
+ if ( lastEntry == NULL ) {
+ node->entries = entry;
+ } /* end of lastEntry == NULL */
+ else {
+ lastEntry->next = entry;
+ } /* end of lastEntry != NULL */
+ *splitEntry = NULL;
+ } /* end of if ( numberOfEntries < fan ) */
+ else { /* no room on node - split */
+ returnCode = splitNode( node, entry, fan, splitEntry );
+ if ( returnCode == SPLIT_NODE_ALLOCATION_FAILURE ) {
+ if ( node->level == LEAF ) {
+ errorMessage( "can't split LEAF node", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( INSERT_ENTRY_SPLIT_NODE_NON_FATAL );
+ } /* end of if ( node->level == LEAF ) */
+ else {
+ errorMessage( "can't split non-LEAF node", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( INSERT_ENTRY_SPLIT_NODE_FATAL );
+ } /* end of if ( node->level != LEAF ) */
+ } /* end of SPLIT_NODE_ALLOCATION_FAILURE */
+ } /* end of if ( numberOfEntries >= fan ) */
+ } /* end of ( node->level == level ) */
+
+ return ( INSERT_ENTRY_SUCCESS );
+} /* end insertEntry() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insertEntry.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insertEntry.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insertEntry.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/insertEntry.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,47 @@
+
+/*
+ * DIS Data Management: insertEntry
+ *
+ * This header file contains the return codes for the insertEntry routine
+ * and the function prototype. There are three different failure modes for
+ * the routine. The first indicates that no entry on the current node was
+ * chosen for the insertion. This always indicates that the current node
+ * is empty of any entry and is an extremely rare debugging error. The
+ * second mode of failure indicates a fatal split node error. It is fatal
+ * since the index has been altered in some way before the error and, since
+ * no "undo" mechanism is implemented for the baseline application, the
+ * state of the index can't be gauranteed which produces a fatal error.
+ * The third mode of failure indicates a non-fatal split node error. It's
+ * not fatal since the index is unchanged and its current state can be
+ * assumed to be still valid.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_INSERT_ENTRY_H
+#define DIS_INSERT_ENTRY_H
+
+#include "dataManagement.h" /* for primitive type definitions */
+#include "index.h" /* for IndexNode and IndexEntry definitions */
+
+/*
+ * Return Codes
+ */
+#define INSERT_ENTRY_SUCCESS 0
+#define INSERT_ENTRY_CHOOSE_ENTRY_FAILURE 1
+#define INSERT_ENTRY_SPLIT_NODE_FATAL 2
+#define INSERT_ENTRY_SPLIT_NODE_NON_FATAL 3
+
+/*
+ * Function prototypes
+ */
+extern Int insertEntry( IndexNode *node, IndexEntry *entry, Int level, Int fan,
+ IndexEntry **splitEntry );
+
+#endif /* DIS_INSERT_ENTRY_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/keyUnion.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/keyUnion.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/keyUnion.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/keyUnion.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,133 @@
+
+/*
+ * File Name: keyUnion.c
+ * Purpose: Calculates the index key union of either a pair of index
+ * keys or a list of index entries. The routine which
+ * calculates the union of a list of index entries uses the
+ * routine which calculates the union of a pair of index keys.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for NULL definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "index.h" /* for IndexEntry definition */
+#include "indexKey.h" /* for IndexKey definition */
+
+/*
+ * Macro definitions for MAX and MIN for use of this file only.
+ */
+#define MAX( a, b ) ( (a) > (b) ? (a) : (b) )
+#define MIN( a, b ) ( (a) < (b) ? (a) : (b) )
+
+/*
+ *
+ * Name: keyUnion
+ * Input: index key, A
+ * index key, B
+ * Output: index key, U
+ * Return: void
+ * Description: Determines the union of two index keys. The union is
+ * defined as the minimal bounding index key which completely
+ * encloses the two input index keys, i.e., a "bounding-box".
+ * The "box" is found by simply determining the minimum and
+ * maximum values for each dimension of the index key. The
+ * values of the output key U do not require "past" values
+ * from A or B, so the pointers can be "reused", i.e., the
+ * routine can be called as keyUnion( A, B, B ) which will
+ * determine the key union of A and B and places the result
+ * in B.
+ * Calls:
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+void keyUnion( IndexKey *A, /* first entry for key union */
+ IndexKey *B, /* second entry for key union */
+ IndexKey *U ) /* union of entries A and B */
+{ /* beginning of keyUnion() */
+
+ assert( A );
+ assert( B );
+ assert( U );
+
+ /*
+ * Find max and min for each dimension of index keys
+ */
+ U->lower.T = MIN( A->lower.T, B->lower.T );
+ U->lower.X = MIN( A->lower.X, B->lower.X );
+ U->lower.Y = MIN( A->lower.Y, B->lower.Y );
+ U->lower.Z = MIN( A->lower.Z, B->lower.Z );
+ U->upper.T = MAX( A->upper.T, B->upper.T );
+ U->upper.X = MAX( A->upper.X, B->upper.X );
+ U->upper.Y = MAX( A->upper.Y, B->upper.Y );
+ U->upper.Z = MAX( A->upper.Z, B->upper.Z );
+
+ return;
+} /* end of keyUnion() */
+
+/*
+ *
+ * Name: keysUnion
+ * Input: index entry list, I
+ * Output: index key, U
+ * Return: void
+ * Description: Determines the union of the index keys of a list of index
+ * entries. The union is defined as the minimal bounding
+ * index key which completely encloses all of the input index
+ * keys, i.e., a "bounding-box". The "box" is found by simply
+ * determing the minimum and maximum values for each dimension
+ * of the index key.
+ * Calls:
+ * keyUnion()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+void keysUnion( IndexEntry *I, /* list of index entries */
+ IndexKey *U ) /* union of entries of I */
+{ /* beginning of keysUnion() */
+
+ assert( I );
+ assert( U );
+
+ /*
+ * Loop over entry list. Must set value of index key U to some value to
+ * prevent NaN or uninitialized memory issues. Setting it to the key of
+ * the first index entry is sufficient and saves one keyUnion calculation.
+ */
+ *U = I->key;
+ for ( I = I->next; I != NULL; I = I->next ) {
+ /*
+ * Expand hyper-cube bounding "box" by determining union of key of
+ * current index entry with current index key. This will always
+ * "expand" the box or leave it unaltered.
+ */
+ keyUnion( &(I->key), U, U );
+ } /* end of loop for I */
+
+ return;
+} /* end of keysUnion() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/main.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/main.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/main.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/main.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,454 @@
+
+/*
+ * Name: main
+ * Input: command-line arguments (argc, argv)
+ * Output: integer success or error code
+ * Return: DIS_DATA_MANAGEMENT_SUCCESS, or
+ * DIS_DATA_MANAGEMENT_ERROR
+ * Description: The is the main() routine for the DIS Data Management
+ * Benchmark baseline application. The application reads a
+ * data set from the specified input (default=stdin), displays
+ * the query command response to the specified output
+ * (default=stdout), and calculates and displays a set of
+ * metric calculations (default=stderr). The format for the
+ * input and output files is given in the DIS Benchmark Suite
+ * specification document. The application is made up of three
+ * modules: Database, Input & Output, and Metrics. A complete
+ * description of the modules and supporting routines are
+ * provided in the DIS Data Management Software Design document
+ * provided with the baseline source code. The routine has
+ * three main sections:
+ *
+ * (1) Initialization
+ * The three modules are initialized by opening files,
+ * creating the first root node, reading the fan from the
+ * input, and starting the metric timing.
+ * (2) Main Loop
+ * The main loop consists of the input data set being
+ * processed line by line where a single line represents a
+ * command to the database. The command is process as
+ * either an INSERT, QUERY, or DELETE. If no commands are
+ * left in the database, then a value of NONE is specified
+ * by the getNextCommandCode() routine and the main loop
+ * exits.
+ *
+ * (3) Exit
+ * The application exits by stopping the metric timing,
+ * calculating and displaying the statistical values,
+ * removing the memory allocated for the database index,
+ * and closing all files.
+ *
+ * Calls: clearLine()
+ * closeFiles()
+ * createIndexNode()
+ * delete();
+ * deleteIndexNode()
+ * errorMessage()
+ * flushErrorMessage()
+ * flushOutputBuffer()
+ * getDeleteCommand()
+ * getInitCommand()
+ * getInsertCommand()
+ * getNextCommandCode()
+ * getQueryCommand()
+ * getTime()
+ * initMetricsData()
+ * insert()
+ * openFiles()
+ * outputMetricsData()
+ * setMetricsData()
+ * query()
+ * updateMetricsData()
+ * System: free()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 28May99 Matthew Rivas Created
+ * 06Jul99 Matthew Rivas Modified return check for openFiles() routine to
+ * handle a usage request or error
+ * 12Jul99 Matthew Rivas Initialized input, output, and metric pointers
+ * to NULL before passing to openFiles() routine to
+ * prevent incorrect assertion
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <stdlib.h> /* for free() and NULL definitions */
+#include "dataObject.h" /* for DataObject definitions */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "delete.h" /* for delete() and return codes */
+#include "errorMessage.h" /* for errorMessage() definitions */
+#include "index.h" /* for IndexNode definition */
+#include "insert.h" /* for insert() and return codes */
+#include "getNextCommandCode.h" /* for getNextCommandCode definitions */
+#include "getInitCommand.h" /* for getInitCommand() and return codes */
+#include "getInsertCommand.h" /* for getInsertCommand() and return codes */
+#include "getDeleteCommand.h" /* for getDeleteCommand() and return codes */
+#include "getQueryCommand.h" /* for getQueryCommand() and return codes */
+#include "metrics.h" /* for Metrics definition */
+#include "openFiles.h" /* for openFiles() and return codes */
+#include "query.h" /* for query() and return codes */
+
+/*
+ * Exit status definitions
+ */
+#define DIS_DATA_MANAGEMENT_SUCCESS 0
+#define DIS_DATA_MANAGEMENT_ERROR -1
+
+/*
+ * Function prototypes
+ */
+extern void clearLine( FILE *file );
+extern void closeFiles( FILE *input, FILE *output, FILE *metrics );
+extern void flushOutputBuffer( void );
+extern void outputQuery( DataObject *dataObject );
+extern void initMetricsData( Metrics *metrics );
+extern void setMetricsData( Metrics *metrics, CommandType command );
+extern void updateMetricsData( Metrics *metrics );
+extern void outputMetricsData( FILE *file, Metrics *metrics );
+extern Time getTime( void );
+
+/*
+ * System Test Debug Prototypes
+ */
+extern Int countDataObjects( IndexNode *node );
+
+/*
+ * Main program
+ */
+int main( int argc, Char *argv[] )
+{ /* begin main() */
+ Int returnCode; /* generic return code for error processing */
+ CommandType command; /* current command read/processing */
+ FILE *input; /* input file */
+ FILE *output; /* output file */
+ FILE *metric; /* metrics file */
+ Metrics metrics; /* metrics data structure */
+ IndexNode *root; /* root node of index */
+ Int fan; /* fan or order of index - read from input */
+ Time tempTime; /* time for keeping I/O timing statistics */
+
+ /*
+ * Initialize Application
+ *
+ * (1) Initialize the Metrics module: this consists of calling the
+ * initMetricsData() routine to initialize the Metrics structure.
+ * (2) Initialize the Input & Output module: this consists of calling
+ * the openFiles() routine which opens the three files: input,
+ * output, and metrics and also calls the initOutputBuffer()
+ * routine to pass the output FILE ptr to the output buffer. If an
+ * error occurred for any of the files, notify user and exit. Note
+ * that the command-line arguments are passed directly to
+ * openFiles() for default overrides on the file names.
+ * (3) Initialize the Database module: this consists of creating the
+ * initial root node and reading the INIT command from the input
+ * file. If the root node can't be created or an error occurred
+ * during the reading of the INIT command, notify user and exit.
+ */
+
+ initMetricsData( &metrics ); /* (1) */
+
+ input = NULL;
+ output = NULL;
+ metric = NULL;
+ returnCode = openFiles( argc, argv, &input, &output, &metric ); /* (2) */
+ if ( returnCode != OPEN_FILES_SUCCESS ) {
+ /*
+ * Check for a usage request, i.e., "-h" in the command-line and
+ * exit successfully if so. Otherwise, flush error message and return
+ * with error.
+ */
+ if ( returnCode == OPEN_FILES_USAGE_REQUEST ) {
+ return ( DIS_DATA_MANAGEMENT_SUCCESS );
+ } /* end of returnCode == OPEN_FILES_USAGE_REQUEST */
+ else {
+ /*
+ * FATAL ERROR: can't proceed if unable to open files or incorrect
+ * usage
+ */
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+
+ return ( DIS_DATA_MANAGEMENT_ERROR );
+ } /* end of else */
+ }
+
+ root = createIndexNode( LEAF ); /* (3) */
+ if ( root == NULL ) {
+ /*
+ * FATAL ERROR: can't proceed if unable to create root node
+ */
+ errorMessage( "root node", PREPEND );
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+
+ return ( DIS_DATA_MANAGEMENT_ERROR );
+ }
+
+ returnCode = getNextCommandCode( input, &command );
+ if ( returnCode == GET_NEXT_COMMAND_CODE_SUCCESS ) {
+ if ( command == INIT ) {
+
+ tempTime = getTime(); /* start I/O timing of command */
+ returnCode = getInitCommand( input, &fan );
+ metrics.inputTime += ( getTime() - tempTime );
+
+ if ( returnCode != GET_INIT_SUCCESS ) {
+ errorMessage( "Can't read first command (INIT)", PREPEND );
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+
+ /*
+ * FATAL ERROR: must have fan parameter to continue
+ */
+ return ( DIS_DATA_MANAGEMENT_ERROR );
+ } /* end error checks for getInitCommand */
+ } /* end if command == INIT */
+ else {
+ errorMessage( "First command is not INIT command", REPLACE );
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+
+ /*
+ * FATAL ERROR: must have fan parameter to continue
+ */
+ return ( DIS_DATA_MANAGEMENT_ERROR );
+ } /* end command != INIT */
+ } /* end if returnCode == GET_NEXT_COMMAND_CODE_SUCCESS */
+ else if ( returnCode == GET_NEXT_COMMAND_CODE_IO_ERROR ||
+ returnCode == GET_NEXT_COMMAND_CODE_INVALID_COMMAND ) {
+ errorMessage( "Can't read first command (INIT)", PREPEND );
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+
+ /*
+ * FATAL ERROR: must have fan parameter to continue
+ */
+ return ( DIS_DATA_MANAGEMENT_ERROR );
+ } /* end return check for getNextCommandCode */
+ clearLine( input );
+
+ /*
+ * Main Loop
+ *
+ * The main loop of the DIS Data Management benchmark baseline
+ * application consists of getting the next command from the
+ * input stream and processing the command. Metric timing is
+ * done for each command processed. The query command response
+ * is also display/flushed through each loop. Extensive error
+ * checking is made during the loop. The following is a
+ * description of the main loop actions:
+ *
+ * (1) Get next command code from input stream
+ * (2) Start metric timing of command
+ * (3) Switch on command code
+ * (A) Insert
+ * (a) Get insert command from input stream: the
+ * insert command consists of a new data object
+ * to add to index.
+ * (b) Insert new data object into index: this may
+ * cause tree "growth", so the root node may be
+ * replaced or "updated" after call to insert().
+ * There is no response for the insert command.
+ * (B) Query
+ * (a) Get query command from input stream: the
+ * command consists of an index key and a list of
+ * non-key DataAttribute's. The memory for the
+ * non-key character strings will need to be
+ * freed after the query() call (see 3.B.c)
+ * (b) Query current index placing responses
+ * into output buffer via outputQuery()
+ * routine.
+ * (c) Free non-key DataAttribute character strings
+ * allocated during the getQueryCommand() call.
+ * (C) Delete
+ * (a) Get delete command from input stream: the
+ * command consists of an index key and a list of
+ * non-key DataAttribute's. The memory for the
+ * non-key character strings will need to be
+ * freed after the delete() call (see 3.C.c)
+ * (b) Delete entries in current index which are
+ * consistent with input search values. There is
+ * no response to the delete command.
+ * (c) Free non-key DataAttribute character strings
+ * allocated during the getDeleteCommand() call.
+ * (3) Stop metric timing for command
+ * (4) Flush output buffer of any query response
+ */
+
+ /*** VERSABENCH START ***/
+ while ( command != NONE ) {
+ returnCode = getNextCommandCode( input, &command );
+ if ( returnCode == GET_NEXT_COMMAND_CODE_SUCCESS ) {
+ setMetricsData( &metrics, command ); /* start timing */
+
+ if ( command == INSERT ) {
+ DataObject *dataObject;
+
+ tempTime = getTime(); /* start I/O timing of command */
+ returnCode = getInsertCommand( input, &dataObject );
+ metrics.inputTime += ( getTime() - tempTime );
+
+ if ( returnCode == GET_INSERT_SUCCESS ) {
+ returnCode = insert( &root, dataObject, fan );
+ if ( returnCode == INSERT_INSERT_ENTRY_FAILURE_FATAL ){
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+
+ /*
+ * FATAL ERROR:
+ */
+ return ( DIS_DATA_MANAGEMENT_ERROR );
+ } /* end code == INSERT_INSERT_ENTRY_FAILURE_FATAL */
+ else if (returnCode==INSERT_INSERT_ENTRY_FAILURE_NON_FATAL){
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+ } /* end code == INSERT_INSERT_ENTRY_FAILURE_NON_FATAL */
+ else if ( returnCode == INSERT_ALLOCATION_FAILURE ) {
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+
+ /*
+ * FATAL ERROR:
+ */
+ return ( DIS_DATA_MANAGEMENT_ERROR );
+ } /* end of if returnCode == INSERT_ALLOCATION_FAILURE */
+ } /* end of if ( returnCode == GET_INSERT_SUCCESS ) */
+ else {
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+ } /* end of returnCode != GET_INSERT_SUCCESS */
+ } /* end command == INSERT */
+ else if ( command == QUERY ) {
+ IndexKey searchKey;
+ DataAttribute *searchNonKey;
+ DataAttribute *temp;
+
+ tempTime = getTime(); /* start I/O timing of command */
+ returnCode = getQueryCommand( input, &searchKey, &searchNonKey);
+ metrics.inputTime += ( getTime() - tempTime );
+
+ if ( returnCode == GET_QUERY_SUCCESS ) {
+
+ returnCode = query( root, &searchKey, searchNonKey, TRUE,
+ outputQuery );
+ if ( returnCode == QUERY_INVALID_KEY_SEARCH_VALUE ||
+ returnCode == QUERY_INVALID_NON_KEY_SEARCH_VALUE ) {
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+ } /* end of if returnCode != QUERY_SUCCESS */
+ } /* end of if ( returnCode == GET_QUERY_SUCCESS ) */
+ else {
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+ } /* end of returnCode != GET_QUERY_SUCCESS */
+
+ /*
+ * Clean-up memory: the non-key search values read for the
+ * QUERY command allocates memory for each value. This memory
+ * needs to be deallocated before the list leaves scope.
+ */
+ temp = searchNonKey;
+ while ( temp != NULL ) {
+ DataAttribute *next;
+
+ next = temp->next;
+ free( temp->attribute.value.nonKey );
+ free( temp );
+ temp = next;
+ } /* end of loop over searchNonKey list using temp */
+ } /* end command == QUERY */
+ else if ( command == DELETE ) {
+ IndexKey searchKey;
+ DataAttribute *searchNonKey;
+ DataAttribute *temp;
+
+ tempTime = getTime(); /* start I/O timing of command */
+ returnCode = getDeleteCommand( input,&searchKey, &searchNonKey);
+ metrics.inputTime += ( getTime() - tempTime );
+
+ if ( returnCode == GET_DELETE_SUCCESS ) {
+ returnCode = delete( &root, &searchKey, searchNonKey );
+ if ( returnCode == DELETE_INVALID_KEY_SEARCH_VALUE ||
+ returnCode == DELETE_INVALID_NON_KEY_SEARCH_VALUE ) {
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+ } /* end of returnCode != DELETE_SUCCESS */
+ } /* end of if ( returnCode == GET_INSERT_SUCCESS ) */
+ else {
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+ } /* end of returnCode != GET_DELETE_SUCCESS */
+
+ /*
+ * Clean-up memory: the non-key search values read for the
+ * DELETE command allocates memory for each value. This memory
+ * needs to be deallocated before the list leaves scope.
+ */
+ temp = searchNonKey;
+ while ( temp != NULL ) {
+ DataAttribute *next;
+
+ next = temp->next;
+ free( temp->attribute.value.nonKey );
+ free( temp );
+ temp = next;
+ } /* end of loop over searchNonKey list using temp */
+ } /* end command == DELETE */
+ else if ( command == INIT ) {
+ errorMessage( "Additional INIT command read", REPLACE );
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+ } /* end command == INIT */
+ else if ( command == INVALID ) {
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+ } /* end command == INVALID */
+
+ updateMetricsData( &metrics ); /* stop timing */
+
+ tempTime = getTime(); /* start output timing of command */
+ flushOutputBuffer();
+ metrics.outputTime += ( getTime() - tempTime );
+
+ } /* end of returnCode == GET_NEXT_COMMAND_CODE_SUCCESS */
+ else if ( returnCode == GET_NEXT_COMMAND_CODE_IO_ERROR ) {
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+ return ( DIS_DATA_MANAGEMENT_ERROR );
+ } /* else low-level I/O error for getNextCommandCode */
+ else if ( returnCode == GET_NEXT_COMMAND_CODE_INVALID_COMMAND ) {
+ errorMessage( argv[ 0 ], PREPEND );
+ flushErrorMessage();
+ } /* end return check for getNextCommandCode */
+
+ clearLine( input );
+ } /* end main loop */
+
+ /*** VERSABENCH END ***/
+
+ /*
+ * Exit Application
+ *
+ * (1) Exit the Metrics module: this consists of calling the
+ * outputMetricsData() routine to calculate and display the
+ * statistical metric values.
+ * (2) Exit the Database module: this consists of deleting the
+ * index root node which will recursively delete all nodes,
+ * entries, and data objects currently in the index.
+ * (3) Exit the Input & Output module: this consists of closing
+ * the three files used during the program execution. Note
+ * that the three files may point to stdin, stdout, and
+ * stderr, but no error occurs for closing these files.
+ */
+ /* outputMetricsData( metric, &metrics ); */
+
+ deleteIndexNode( root );
+
+ closeFiles( input, output, metric );
+
+ exit ( DIS_DATA_MANAGEMENT_SUCCESS );
+} /* end of main() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/metrics.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/metrics.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/metrics.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/metrics.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,97 @@
+
+/*
+ * DIS Data Management Metrics
+ *
+ * This header file contains the type definition for the timing
+ * variable and metric structures used by the DIS Data Management
+ * benchmark. The metric structures consist of a single overall
+ * structure and individual command metric structures.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_METRICS_H
+#define DIS_METRICS_H
+
+#include "dataManagement.h" /* for primitive type definitions */
+#include "getNextCommandCode.h" /* for CommandType enumeration */
+
+/*
+ * Time value used by DIS Data Management benchmark
+ * - value represents milliseconds since program start
+ */
+typedef long int Time;
+
+/*
+ * Double value used for statistic calculations
+ */
+typedef double Double;
+
+/*
+ * Command Metric structure
+ * - metric structure for individual command metric statistics
+ * - each command should have a separate structure
+ * - structure members naturally separate into two groups:
+ * (1) Internal use members which should only be altered by
+ * metric routines.
+ * (2) External use members which provide statistic values
+ * - Note that the typedef Time could be changed to a structure
+ * for different systems and/or timing methods. This change
+ * should not require a change of this structure definition.
+ */
+typedef struct
+{
+ /*
+ * Internal use members
+ */
+ Time lastTimeMark; /* timing mark for command duration calc */
+ Int numOfCommands; /* number of commands (for average) */
+ Double sum; /* sum of separate command times */
+ Double sumSquares; /* sum of the squares of command times */
+
+ /*
+ * External use members
+ */
+ Time worst; /* worst time recorded for this command */
+ Time best; /* best time recorded for this command */
+ Double avg; /* average time (as Double) for command */
+ Double deviation; /* standard deviation (as Double) for command */
+} CommandMetric;
+
+/*
+ * Metric structure
+ * - performance data for current data set execution
+ * - includes total time to complete, input time, output time and separate
+ * performance measures of the insert, query, and delete commands.
+ * - Note that the typedef Time could be changed to a structure
+ * for different systems and/or timing methods. This change
+ * should not require a change of this structure definition.
+ */
+typedef struct
+{
+ Time totalTime; /* total time to complete */
+ /* data set */
+ Time inputTime; /* total time required for */
+ /* input of data set */
+ Time outputTime; /* total time required for */
+ /* output of queries */
+ CommandMetric insertCommandMetric; /* insert metric data */
+ CommandMetric queryCommandMetric; /* query metric data */
+ CommandMetric deleteCommandMetric; /* delete metric data */
+
+ CommandType lastCommand;
+} Metrics;
+
+/*
+ * Time value parameters
+ */
+#define MINIMUM_VALUE_OF_TIME MINIMUM_VALUE_OF_INT
+#define MAXIMUM_VALUE_OF_TIME MAXIMUM_VALUE_OF_INT
+
+#endif /* DIS_METRICS_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/openFiles.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/openFiles.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/openFiles.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/openFiles.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,248 @@
+
+/*
+ * Name: openFiles
+ * Input: number of command-line arguments, argc
+ * array of command-line argument strings, argv
+ * Output: input FILE pointer
+ * output FILE pointer
+ * metrics FILE pointer
+ * Return: OPEN_FILES_SUCCESS, or
+ * OPEN_FILES_USAGE_REQUEST
+ * OPEN_FILES_USAGE_ERROR
+ * OPEN_FILES_INPUT_FILE_ERROR,
+ * OPEN_FILES_OUTPUT_FILE_ERROR,
+ * OPEN_FILES_METRICS_FILE_ERROR,
+ * Description: Routine opens the three files used by the application:
+ * input, output, and metrics. The FILE pointers are returned
+ * open and at the beginning of the files. Default values for
+ * the input, output, and metric files are stdin, stdout, and
+ * stderr respectively. The command-line arguments are passed
+ * to the routine for default overrides. The usage for the
+ * baseline application is:
+ *
+ * a.out -i name : specify input file name
+ * -o name : specify output file name
+ * -m name : specify metrics file name
+ * -h : display usage and return
+ *
+ * The routine also initializes the output buffer by passing
+ * the value of the output file pointer to initOutputBuffer().
+ * Calls: errorMessage()
+ * initOutputBuffer()
+ * System: fopen()
+ * fprintf()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ * 06Jul99 Matthew Rivas Modified command-line argument parsing and added
+ * usage parameter -h
+ * 12Jul99 Matthew Rivas Change file assertions to correct form
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdio.h> /* for FILE definitions and fopen() */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "openFiles.h" /* for openFiles return codes */
+
+/*
+ * Function Prototypes
+ */
+extern void initOutputBuffer( FILE *file );
+
+Int openFiles( Int argc, /* command-line arguments to provide */
+ Char **argv, /* input values for file names */
+ FILE **inputFile, /* input file ptr - output */
+ FILE **outputFile, /* output file ptr - output */
+ FILE **metricsFile ) /* metrics file ptr - output */
+{ /* begin openFiles() */
+ Char *inputFileName; /* character strings used to store name */
+ Char *outputFileName; /* values parsed from input command-line */
+ Char *metricsFileName; /* arguments */
+
+ static Char name[] = "openFiles";
+
+ assert( argc > 0 );
+ assert( argv && argv[ 0 ] );
+ assert( *inputFile == NULL );
+ assert( *outputFile == NULL );
+ assert( *metricsFile == NULL );
+
+ /*
+ * Process input command-line arguments for the name of the input, output,
+ * and metric files. The names are set to NULL and if unchanged will
+ * default to the stdin, stdout, and stderr, respectively. If a file is
+ * specified by the command-line options, the name is referenced by the
+ * appropriate local variable and used during the opening of the file in
+ * the next section.
+ */
+ inputFileName = NULL;
+ outputFileName = NULL;
+ metricsFileName = NULL;
+ if ( argc > 1 ) {
+ Int i; /* counter for current argument being parsed */
+
+ i = 1; /* start with second argument - first is program name */
+ while ( i < argc ) { /* parse command-line arguments until all parsed */
+ if ( strlen( argv[ i ] ) == 2 && argv[ i ][ 0 ] == '-' ) {
+ if ( argv[ i ][ 1 ] == 'i' ) {
+ if ( i + 1 < argc ) {
+ i++;
+ inputFileName = argv[ i ];
+ } /* end of if i+1 <= argc */
+ else {
+ errorMessage( "missing argument for -i", REPLACE );
+ errorMessage( name, PREPEND );
+
+ inputFileName = NULL;
+ outputFileName = NULL;
+ metricsFileName = NULL;
+
+ fprintf( stderr, "Usage: %s [-h], or\n", argv[ 0 ] );
+ fprintf( stderr, " %s", argv[ 0 ] );
+ fprintf( stderr, " [-i <input file = stdin>]" );
+ fprintf( stderr, " [-o <output file = stdout>]" );
+ fprintf( stderr, " [-m <metrics file = stderr>]\n" );
+ return ( OPEN_FILES_USAGE_ERROR );
+ } /* end of if i+1 > argc */
+ i++;
+ } /* end of if argv[ i ][ 1 ] = 'i' */
+ else if ( argv[ i ][ 1 ] == 'o' ) {
+ if ( i + 1 < argc ) {
+ i++;
+ outputFileName = argv[ i ];
+ } /* end of if i+1 <= argc */
+ else {
+ errorMessage( "missing argument for -o", REPLACE );
+ errorMessage( name, PREPEND );
+
+ inputFileName = NULL;
+ outputFileName = NULL;
+ metricsFileName = NULL;
+
+ fprintf( stderr, "Usage: %s [-h], or\n", argv[ 0 ] );
+ fprintf( stderr, " %s", argv[ 0 ] );
+ fprintf( stderr, " [-i <input file = stdin>]" );
+ fprintf( stderr, " [-o <output file = stdout>]" );
+ fprintf( stderr, " [-m <metrics file = stderr>]\n" );
+ return ( OPEN_FILES_USAGE_ERROR );
+ } /* end of if i+1 > argc */
+ i++;
+ } /* end of if argv[ i ][ 1 ] = 'o' */
+ else if ( argv[ i ][ 1 ] == 'm' ) {
+ if ( i + 1 < argc ) {
+ i++;
+ metricsFileName = argv[ i ];
+ } /* end of if i+1 <= argc */
+ else {
+ errorMessage( "missing argument for -m", REPLACE );
+ errorMessage( name, PREPEND );
+
+ inputFileName = NULL;
+ outputFileName = NULL;
+ metricsFileName = NULL;
+
+ fprintf( stderr, "Usage: %s [-h], or\n", argv[ 0 ] );
+ fprintf( stderr, " %s", argv[ 0 ] );
+ fprintf( stderr, " [-i <input file = stdin>]" );
+ fprintf( stderr, " [-o <output file = stdout>]" );
+ fprintf( stderr, " [-m <metrics file = stderr>]\n" );
+ return ( OPEN_FILES_USAGE_ERROR );
+ } /* end of if i+1 > argc */
+ i++;
+ } /* end of if argv[ i ][ 1 ] = 'm' */
+ else if ( argv[ i ][ 1 ] == 'h' ) {
+ fprintf( stderr, "Usage: %s [-h], or\n", argv[ 0 ] );
+ fprintf( stderr, " %s", argv[ 0 ] );
+ fprintf( stderr, " [-i <input file = stdin>]" );
+ fprintf( stderr, " [-o <output file = stdout>]" );
+ fprintf( stderr, " [-m <metrics file = stderr>]\n" );
+ return ( OPEN_FILES_USAGE_REQUEST );
+ } /* end of if argv[ i ][ 1 ] = 'h' */
+ else {
+ errorMessage( "unknown option", REPLACE );
+ errorMessage( name, PREPEND );
+
+ inputFileName = NULL;
+ outputFileName = NULL;
+ metricsFileName = NULL;
+
+ fprintf( stderr, "Usage: %s [-h], or\n", argv[ 0 ] );
+ fprintf( stderr, " %s", argv[ 0 ] );
+ fprintf( stderr, " [-i <input file = stdin>]" );
+ fprintf( stderr, " [-o <output file = stdout>]" );
+ fprintf( stderr, " [-m <metrics file = stderr>]\n" );
+ return ( OPEN_FILES_USAGE_ERROR );
+ } /* end of else - unknown option */
+ } /* end of if strlen( argv ) > 1 && argv[i][0] = '-' */
+ else {
+ errorMessage( "incorrect format - unknown option", REPLACE );
+ errorMessage( name, PREPEND );
+
+ inputFileName = NULL;
+ outputFileName = NULL;
+ metricsFileName = NULL;
+
+ fprintf( stderr, "Usage: %s [-h], or\n", argv[ 0 ] );
+ fprintf( stderr, " %s", argv[ 0 ] );
+ fprintf( stderr, " [-i <input file = stdin>]" );
+ fprintf( stderr, " [-o <output file = stdout>]" );
+ fprintf( stderr, " [-m <metrics file = stderr>]\n" );
+ return ( OPEN_FILES_USAGE_ERROR );
+ } /* end of else - incorrect format */
+ } /* end of option present with '-' in front */
+ } /* end of if argc > 1 - command-line arguments present */
+
+ /*
+ * Check each file name for either default value or no value, open each
+ * file and check value of FILE pointer. If a failure occurs, place
+ * message in error buffer and return appropriate code.
+ */
+ if ( inputFileName == NULL ) { /* input file */
+ *inputFile = stdin;
+ } /* end of if ( inputFileName == NULL ) */
+ else {
+ *inputFile = fopen( inputFileName, "r" );
+ if ( *inputFile == NULL ) {
+ errorMessage( "error opening input file", REPLACE );
+ errorMessage( name, PREPEND );
+
+ return ( OPEN_FILES_INPUT_FILE_ERROR );
+ } /* end of if ( *inputFile == NULL ) */
+ } /* end of branches for input file */
+
+ if ( outputFileName == NULL ) { /* output file */
+ *outputFile = stdout;
+ } /* end of if ( outputFileName == NULL ) */
+ else {
+ *outputFile = fopen( outputFileName, "w" );
+ if ( *outputFile == NULL ) {
+ errorMessage( "error opening output file", REPLACE );
+ errorMessage( name, PREPEND );
+
+ return ( OPEN_FILES_OUTPUT_FILE_ERROR );
+ } /* end of if ( *outputFile == NULL ) */
+ } /* end of branches for output file */
+
+ initOutputBuffer( *outputFile );
+
+ if ( metricsFileName == NULL ) { /* metrics file */
+ *metricsFile = stderr;
+ } /* end of if ( metricsFileName == NULL ) */
+ else {
+ *metricsFile = fopen( metricsFileName, "w" );
+ if ( *metricsFile == NULL ) {
+ errorMessage( "error opening metrics file", REPLACE );
+ errorMessage( name, PREPEND );
+
+ return ( OPEN_FILES_METRICS_FILE_ERROR );
+ } /* end of if ( *metricsFile == NULL ) */
+ } /* end of branches for metrics file */
+
+ return ( OPEN_FILES_SUCCESS );
+} /* end of openFiles() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/openFiles.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/openFiles.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/openFiles.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/openFiles.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,42 @@
+
+/*
+ * DIS Data Management: openFiles
+ *
+ * This header file contains the return codes and function prototype for
+ * the openFiles routine. The fist non-zero return code indicates that the
+ * usage flag was present in the command-line options. The second non-zero
+ * return code is for a usage error and the final three error return codes
+ * indicate which of the files could not be opened.
+ *
+ * Revision History:
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ * 06Jul99 Matthew Rivas Added return flag USAGE_REQUEST and USAGE_ERROR
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_OPEN_FILES_H
+#define DIS_OPEN_FILES_H
+
+#include <stdio.h> /* for FILE definition */
+#include "dataManagement.h" /* for primitive type definitions */
+
+/*
+ * Return codes
+ */
+#define OPEN_FILES_SUCCESS 0
+#define OPEN_FILES_USAGE_REQUEST 1
+#define OPEN_FILES_USAGE_ERROR 2
+#define OPEN_FILES_INPUT_FILE_ERROR 3
+#define OPEN_FILES_OUTPUT_FILE_ERROR 4
+#define OPEN_FILES_METRICS_FILE_ERROR 5
+
+/*
+ * Function Prototype
+ */
+extern Int openFiles( Int argc, Char **argv, FILE **inputFile,
+ FILE **outputFile, FILE **metricsFile );
+
+#endif /* DIS_OPEN_FILES_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/outputMetricsData.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/outputMetricsData.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/outputMetricsData.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/outputMetricsData.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,86 @@
+
+/*
+ * Name: outputMetricsData
+ * Input: FILE pointer for output, file
+ * metrics structure, metrics
+ * Output: none
+ * Return: void
+ * Description: The routine displays the metrics collected during a
+ * execution of the baseline application. The routine
+ * calcMetricsData() is called to setup all of the displayed
+ * fields.
+ * Calls: calcMetricsData()
+ * System: fprintf()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 28May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdio.h> /* for fprintf() definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "metrics.h" /* for Metrics definitions */
+
+/*
+ * Function prototype
+ */
+extern void calcMetricsData( Metrics *metrics );
+
+void outputMetricsData( FILE *file, /* output file */
+ Metrics *metrics ) /* metrics to output */
+{ /* beginning of outputMetricsData() */
+
+ assert( file );
+ assert( metrics );
+
+ /*
+ * Calculate the metric statistical values
+ */
+ calcMetricsData( metrics );
+
+ /*
+ * Display the metric statistical values
+ */
+ fprintf( file, "DIS Data Management Metrics\n" );
+ fprintf( file, " total time = %li msecs\n", metrics->totalTime );
+ fprintf( file, " input time = %li msecs\n", metrics->inputTime );
+ fprintf( file, " output time = %li msecs\n", metrics->outputTime );
+
+ fprintf( file, " Insert Commmand Metrics:\n" );
+ fprintf( file, " best time = %li msecs\n",
+ metrics->insertCommandMetric.best );
+ fprintf( file, " worst time = %li msecs\n",
+ metrics->insertCommandMetric.worst );
+ fprintf( file, " average = %f msecs\n",
+ metrics->insertCommandMetric.avg );
+ fprintf( file, " standard deviation = %f msecs\n",
+ metrics->insertCommandMetric.deviation );
+
+ fprintf( file, " Query Commmand Metrics:\n" );
+ fprintf( file, " best time = %li msecs\n",
+ metrics->queryCommandMetric.best );
+ fprintf( file, " worst time = %li msecs\n",
+ metrics->queryCommandMetric.worst );
+ fprintf( file, " average = %f msecs\n",
+ metrics->queryCommandMetric.avg );
+ fprintf( file, " standard deviation = %f msecs\n",
+ metrics->queryCommandMetric.deviation );
+
+ fprintf( file, " Delete Commmand Metrics:\n" );
+ fprintf( file, " best time = %li msecs\n",
+ metrics->deleteCommandMetric.best );
+ fprintf( file, " worst time = %li msecs\n",
+ metrics->deleteCommandMetric.worst );
+ fprintf( file, " average = %f msecs\n",
+ metrics->deleteCommandMetric.avg );
+ fprintf( file, " standard deviation = %f msecs\n",
+ metrics->deleteCommandMetric.deviation );
+
+ return;
+} /* end of outputMetricsData() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/outputQuery.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/outputQuery.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/outputQuery.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/outputQuery.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,289 @@
+
+/*
+ * File Name: outputQuery.c
+ * Purpose: This file contains three routines which handle the output
+ * of the index queries. The first routine initializes the
+ * the output by saving the output FILE ptr which is needed
+ * by the output buffer for display. It's possible to pass
+ * this FILE ptr to the display routine, but this would also
+ * require the outputQuery() routine to have the FILE as
+ * part of it's parameter list, since the outputQuery()
+ * routine may need to flush the output buffer. For clarity,
+ * the FILE ptr is saved and is static to this file. The
+ * second routine is the routine that the query() method
+ * requires and places one data object into the output
+ * buffer. The object is converted to a string
+ * representation and placed in the output buffer. Before
+ * placement, an overflow condition is checked and, if
+ * necessary, the buffer is flushed before. Note that
+ * the size of the output buffer MUST be at least the
+ * length of the largest possible data object string
+ * representation. The final routine flushes the output
+ * buffer by displaying the contents to the output stream,
+ * via the output FILE ptr.
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ * 23Jun99 Matthew Rivas Added initializer to numberOfAttributes to prevent
+ * warning message during compilation
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for NULL definition */
+#include <stdio.h> /* for sprintf() definition */
+#include <string.h> /* for strcpy() definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "dataObject.h" /* for DataObject definitions */
+#include "errorMessage.h" /* for errorMessage() definition */
+
+/*
+ * Static definition of output buffer
+ * - approximate maximum length of a single data object represented
+ * as a character string is:
+ *
+ * 44483 characters = 8 * 50 key float values
+ * + 43 * 1024 non-key char strings
+ * + 50 place delimiters
+ * + 1 line-feed/carriage return
+ * - output buffer length should be set
+ */
+
+#define LENGTH_OF_KEY_VALUE 50
+#define LENGTH_OF_NON_KEY_VALUE MAX_SIZE_OF_NON_KEY_ATTRIBUTE
+#define MAX_LENGTH_OF_ATTRIBUTE MAX_SIZE_OF_NON_KEY_ATTRIBUTE
+#define NUM_OF_NON_KEY_ATTRIBUTES ( NUM_OF_LARGE_ATTRIBUTES - NUM_OF_KEY_ATTRIBUTES )
+#define REPRESENTATION_LENGTH 44483
+#define OUTPUT_BUFFER_LENGTH 2 * REPRESENTATION_LENGTH
+#define ATTRIBUTE_DELIMITER " "
+#define END_OF_LINE_INDICATOR "\n"
+
+static Char outputBuffer[ OUTPUT_BUFFER_LENGTH + 1 ];
+static FILE *outputFile = NULL;
+
+/*
+ * Function prototype
+ */
+void flushOutputBuffer( void );
+
+/*
+ * Name: outputQuery
+ * Input: data object to place in output buffer, dataObject
+ * Output: none
+ * Return: void
+ * Description: This routine places a single data object into the output
+ * buffer. The object is first converted to a string
+ * representation which consists of each attribute in
+ * character format separated by a single space. A local
+ * static character array is used to build the data object
+ * string representation. The static array, called
+ * dataObjectString, must have a length which can handle a
+ * data object of maximum size, i.e., largest possible key
+ * values, large type with each non-key string of maximum
+ * length. Also, the output buffer size must be at least this
+ * size. A check is made to see if the output buffer needs to
+ * be flushed prior to the dataObjectString placement and then
+ * the dataObjectString is placed in the output buffer.
+ * Calls: errorMessage()
+ * flushErrorMessage()
+ * flushOutputBuffer()
+ * System: strcat()
+ * strlen()
+ * sprintf()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+void outputQuery( DataObject *dataObject ) /* object to place in buffer */
+{ /* beginning of outputQuery() */
+ Int i; /* loop variable for attributes */
+ Int numberOfAttributes; /* number of attributes for object */
+
+#ifndef NDEBUG
+ static Char name[] = "outputQuery";
+#endif /* NDEBUG */
+
+ /*
+ * Static character strings for converting dataObject to string
+ * representation. temp is used to convert individual key attributes to a
+ * string and then strcat() is used to place the attribute string version
+ * into the dataObjectString which holds the entire data object string
+ * representation. When all of the attributes have been processed,
+ * dataObjectString is placed into the output buffer.
+ */
+ static Char temp[ LENGTH_OF_KEY_VALUE + 1 ];
+ static Char dataObjectString[ REPRESENTATION_LENGTH + 1 ];
+
+ assert( outputFile );
+ assert( dataObject );
+ assert( !(dataObject->type != SMALL && \
+ dataObject->type != MEDIUM && \
+ dataObject->type != LARGE ) );
+ assert( LENGTH_OF_KEY_VALUE <= MAX_LENGTH_OF_ATTRIBUTE && \
+ LENGTH_OF_NON_KEY_VALUE <= MAX_LENGTH_OF_ATTRIBUTE );
+ assert( REPRESENTATION_LENGTH >= \
+ LENGTH_OF_KEY_VALUE * NUM_OF_KEY_ATTRIBUTES \
+ + LENGTH_OF_NON_KEY_VALUE * NUM_OF_NON_KEY_ATTRIBUTES \
+ + ( NUM_OF_LARGE_ATTRIBUTES - 1 ) \
+ + 1 );
+ assert( REPRESENTATION_LENGTH <= OUTPUT_BUFFER_LENGTH );
+ assert( MIN_ATTRIBUTE_CODE < NUM_OF_KEY_ATTRIBUTES );
+ assert( MIN_ATTRIBUTE_CODE < MAX_ATTRIBUTE_CODE );
+ assert( MAX_ATTRIBUTE_CODE < NUM_OF_LARGE_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_SMALL_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_MEDIUM_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_LARGE_ATTRIBUTES );
+ assert( REPRESENTATION_LENGTH <= OUTPUT_BUFFER_LENGTH );
+
+ /*
+ * Determine the number of attributes for data object
+ */
+ numberOfAttributes = 0;
+ if ( dataObject->type == SMALL ) {
+ numberOfAttributes = NUM_OF_SMALL_ATTRIBUTES - 1;
+ } /* end if ( dataObject->type == SMALL ) */
+ else if ( dataObject->type == MEDIUM ) {
+ numberOfAttributes = NUM_OF_MEDIUM_ATTRIBUTES - 1;
+ } /* end if ( dataObject->type == MEDIUM ) */
+ else if ( dataObject->type == LARGE ) {
+ numberOfAttributes = NUM_OF_LARGE_ATTRIBUTES - 1;
+ } /* end if ( dataObject->type == LARGE ) */
+
+ /*
+ * Place each attribute into dataObjectString. Key and Non-Key values are
+ * handled separately because of the format command, i.e. %f or %s. The
+ * temp string is used to hold the character string representation of the
+ * key attribute values returned from sprintf(). Then strcat() is used to
+ * add the attribute string representation to the full data object
+ * representation being built up in dataObjectString. All of the non-key
+ * attributes are added to the dataObjectString using strcat() except for
+ * the last attribute. This attribute has no space delimiter after and so
+ * is handled separately. Finally, an end-of-line indicator is added to
+ * the data object string and the string is place in the output buffer.
+ * Note that the dataObjectString needs to be initialized to EMPTY/'\0'
+ * each time the routine is called, since the array is static for memory
+ * efficiency.
+ */
+ dataObjectString[ 0 ] = '\0';
+ for ( i = MIN_ATTRIBUTE_CODE; i < NUM_OF_KEY_ATTRIBUTES; i++ ) {
+ sprintf( temp, "%.8e", dataObject->attributes[ i ].value.key );
+ strcat( dataObjectString, temp );
+ strcat( dataObjectString, ATTRIBUTE_DELIMITER );
+ } /* end of loop for key attributes */
+
+ for ( i = NUM_OF_KEY_ATTRIBUTES; i < numberOfAttributes; i++ ) {
+ assert( dataObject->attributes[ i ].value.nonKey );
+ assert( strlen( dataObject->attributes[ i ].value.nonKey ) > 0 );
+
+ strcat( dataObjectString, dataObject->attributes[ i ].value.nonKey );
+ strcat( dataObjectString, ATTRIBUTE_DELIMITER );
+ } /* end of loop for non-key attributes */
+
+ assert( dataObject->attributes[ numberOfAttributes ].value.nonKey );
+ assert(strlen(dataObject->attributes[numberOfAttributes].value.nonKey) > 0);
+
+ strcat( dataObjectString,
+ dataObject->attributes[ numberOfAttributes ].value.nonKey );
+ strcat( dataObjectString, END_OF_LINE_INDICATOR );
+
+ assert( strlen( dataObjectString ) <= REPRESENTATION_LENGTH );
+
+ /*
+ * Place the data object string representation into the output buffer,
+ * flushing if necessary.
+ */
+ if ( strlen( dataObjectString ) + strlen( outputBuffer )
+ > OUTPUT_BUFFER_LENGTH ) {
+#ifndef NDEBUG
+ errorMessage( "output buffer full - flushing", REPLACE );
+ errorMessage( name, PREPEND );
+ flushErrorMessage();
+#endif /* NDEBUG */
+
+ flushOutputBuffer();
+ }
+
+ strcat( outputBuffer, dataObjectString );
+
+ return;
+} /* end of outputQuery() */
+
+/*
+ * Name: initOutputBuffer
+ * Input: FILE ptr to output stream, file
+ * Output: none
+ * Return: void
+ * Description: This routine initializes the output buffer by
+ * saving the output FILE ptr for later buffer
+ * display.
+ * Calls:
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+void initOutputBuffer( FILE *file )
+{ /* beginning of initOutputBuffer() */
+ assert( file );
+
+ outputFile = file;
+} /* end of initOutputBuffer() */
+
+/*
+ * Name: flushOutputBuffer
+ * Input: none
+ * Output: none
+ * Return: void
+ * Description: This routine flushes the output buffer by displaying
+ * the current contents of the buffer into the output
+ * stream via the static outputFile FILE ptr. A check
+ * is made to ensure that the buffer has contents to
+ * display before a flush occurs.
+ * Calls:
+ * System: fprintf()
+ * fflush()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+void flushOutputBuffer( void )
+{ /* beginning of flushOutputBuffer() */
+ assert( outputFile );
+
+ /*
+ * If the contents are not empty, flush the buffer
+ */
+ if ( strlen( outputBuffer ) > 0 ) {
+ fprintf( outputFile, "%s", outputBuffer );
+ fflush( outputFile );
+ }
+
+ outputBuffer[ 0 ] = '\0';
+
+ return;
+} /* end of flushOutputBuffer() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/partitionEntries.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/partitionEntries.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/partitionEntries.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/partitionEntries.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,275 @@
+/*
+ *
+ * Name: partitionEntries
+ * Input: input list of index entries, I
+ * integer fan value, fan
+ * Output: output list of index entries, A
+ * output list of index entries, B
+ * Return: void
+ * Description: Separate input list of index entries into two groups. The
+ * method used for partitioning the entries is extremely
+ * implementation dependent. The basic idea is to set-up the
+ * two output index entry lists to have minimal bounding
+ * index keys which will improve later queries on the index,
+ * since fewer branches of the index tree will need to be
+ * traversed to satisfy the query command. However, the
+ * method itself is probably the most computationally
+ * expensive of the insertion subroutines, because multiple
+ * loops through the index entry lists and volume
+ * calculations are required for true "minimal" bounding index
+ * keys to be determined. If multiple branch searches is not
+ * prohibitive, i.e., a parallel search is possible or query
+ * response time is not time consuming relative to an insert
+ * operation, then the partition subroutine can use a
+ * sub-minimal approach. In fact, the partition can simply
+ * split the input list into two equal groups ignoring the
+ * bounding index keys completely. The effect will be to
+ * cause new traversals of the index to descend multiple
+ * branches, but this trade-off may be acceptable for a given
+ * implementation.
+ *
+ * On entrance, the input list, I, should have at least
+ * MINIMUM_FAN_SIZE entries and nor more than 2 * fan entries,
+ * and the output lists, A and B, should be empty(NULL). On
+ * exit, the input list, I, is empty(NULL) and the output
+ * lists, A and B, have the partitioned entries (both are
+ * non-NULL). Each list is ready for insertion into an
+ * IndexNode.
+ * Calls: errorMessage()
+ * keyUnion()
+ * penalty()
+ * volume()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for NULL definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "index.h" /* for IndexEntry definition */
+#include "indexKey.h" /* for IndexKey definition */
+
+/*
+ * Function prototypes
+ */
+extern Float penalty( IndexEntry A, IndexEntry B );
+extern Float volume( IndexKey key );
+extern void keyUnion( IndexKey *A, IndexKey *B, IndexKey *U );
+
+void partitionEntries( IndexEntry *I, /* input entry list to partition */
+ Int fan, /* fan or order of index */
+ IndexEntry **A, /* 1st group partitioned entries */
+ IndexEntry **B ) /* 2nd group partitioned entries */
+{ /* beginning of partitionEntries() */
+ IndexEntry *entry1; /* looping entry to find first entry of groups */
+ IndexEntry *entry2; /* looping entry to find first entry of groups */
+ IndexEntry *currentEntry; /* looping entry for input list */
+ IndexEntry *previousEntry; /* looping entry for input list */
+ IndexEntry *tempA; /* temp entry to find first entry of group A */
+ IndexEntry *tempB; /* temp entry to find first entry of group B */
+ IndexKey unionAB; /* union of first entries of group A and B */
+ Float volumeAB; /* volume of first entries of group A and B */
+ Int sizeOfGroupA; /* current size of group A */
+ Int sizeOfGroupB; /* current size of group B */
+
+ static Char name[] = "partitionEntries";
+
+ assert( I && I->next ); /* need at least two entries to partition */
+ assert( MINIMUM_FAN_SIZE > 1 );
+ assert( fan >= MINIMUM_FAN_SIZE );
+
+ /*
+ * Find "worst" combination of all entries in I. The worst combination is
+ * the one which produces the largest bounding index key, i.e., the
+ * largest hyper-cube volume. The two entries which form the worst combo
+ * will be the first entries into the two groups, A and B. The method
+ * used to find the worst combo is straight forward enumeration of all
+ * possible combinations. Note that only forward combinations are
+ * necessary since the volume( union( A, B ) ) is the same as the
+ * volume( union( B, A ) ). The first candidate pair for the worst case
+ * are chosen as the first and second entries of the input list, I.
+ */
+ *A = I;
+ *B = I->next;
+ keyUnion( &(*A)->key, &(*B)->key, &unionAB );
+ volumeAB = volume( unionAB );
+
+ /*
+ * A double loop through the input list, I, is used to find all
+ * combinations.
+ */
+ for ( entry1 = I; entry1 != NULL; entry1 = entry1->next ) {
+ for ( entry2 = entry1->next; entry2 != NULL; entry2 = entry2->next ) {
+ IndexKey tempKey;
+ Float tempVolume;
+
+ /*
+ * If this combination produces a worse penalty, then replace old
+ * candidates with new pair.
+ */
+ keyUnion( &entry1->key, &entry2->key, &tempKey );
+ tempVolume = volume( tempKey );
+
+ if ( tempVolume > volumeAB ) {
+ *A = entry1;
+ *B = entry2;
+ unionAB = tempKey;
+ volumeAB = tempVolume;
+ } /* end of if ( tempVolume > volumeAB ) */
+ } /* end of loop for entry2 */
+ } /* end of loop for entry1 */
+
+ /*
+ * The entry pointers, A and B, now point to the first entries of the
+ * two groups which are forming during the partition. Remove them from the
+ * input list, I. Set the size of each group to one for the initial
+ * entries. The entries of I which correspond to A and B are
+ * found by comparing pointer values.
+ */
+ currentEntry = I; /* current entry (starts at beginning of I) */
+ previousEntry = NULL; /* previous entry (NULL for first entry) */
+ while ( currentEntry != NULL ) {
+ if ( currentEntry == *A || currentEntry == *B ) {
+ /*
+ * Found A or B in list as currentEntry. Remove current entry from
+ * list, checking for special case where current entry is the head
+ * of list, i.e., no previous entry.
+ */
+ if ( previousEntry == NULL ) {
+ /*
+ * No previous pointer means that the current entry is the
+ * head of the list. Removing the entry means updating I and
+ * reseting the values for currentEntry and previousEntry.
+ */
+ I = currentEntry->next;
+ currentEntry = I;
+ previousEntry = NULL;
+ } /* end of if ( previousEntry == NULL ) */
+ else {
+ /*
+ * Remove current entry by setting previous entry's pointer to
+ * skip the current.
+ */
+ previousEntry->next = currentEntry->next;
+
+ /*
+ * Setup entries for next loop. Since an entry was removed
+ * from the list, the previous entry, previousEntry, does not
+ * change.
+ */
+ currentEntry = previousEntry->next;
+ } /* end of else */
+ } /* end of if ( currentEntry == A || currentEntry == B ) */
+ else {
+ /*
+ * Did not find either A or B, so just set up for next loop
+ */
+ previousEntry = currentEntry;
+ currentEntry = currentEntry->next;
+ } /* end of else */
+ } /* end of loop for currentEntry */
+
+ /*
+ * Finish up by fixing the next pointers for both A and B to NULL since
+ * their the first and only entries in the lists, and setting the size of
+ * each group to one.
+ */
+ (*A)->next = NULL;
+ (*B)->next = NULL;
+ sizeOfGroupA = 1;
+ sizeOfGroupB = 1;
+
+ /*
+ * The first entries of groups A and B are now assigned and removed from
+ * the input list, I. The "volume" for A and B is the "worst" possible
+ * for all combinations of the entries of I.
+ *
+ * Assign all remaining entries of I to each group based on penalty. The
+ * current implementation finds the penalty of the entry with the first
+ * entries into the group, i.e., A or B. Other methods are possible,
+ * including using the penalty of the current group rather than the first
+ * entry into that group.
+ */
+ tempA = *A;
+ tempB = *B;
+ while ( I != NULL ) {
+ /*
+ * If neither group is full, add according to penalty
+ */
+ if ( sizeOfGroupA < fan && sizeOfGroupB < fan ) {
+ if ( penalty( **A, *I ) < penalty( **B, *I ) ) {
+ /*
+ * Place current entry into group A, incrementing counter
+ */
+ tempA->next = I; /* add current entry to group A */
+ I = I->next; /* increment current entry */
+ tempA = tempA->next; /* increment group A ptr */
+ tempA->next = NULL; /* remove new entry from group I */
+
+ sizeOfGroupA++;
+ } /* end of if ( penalty( I, A ) < penalty( I, B ) ) */
+ else {
+ /*
+ * Place current entry into group B, incrementing counter
+ */
+ tempB->next = I; /* add current entry to group B */
+ I = I->next; /* increment current entry */
+ tempB = tempB->next; /* increment group B ptr */
+ tempB->next = NULL; /* remove new entry from group I */
+
+ sizeOfGroupB++;
+ } /* end of else */
+ } /* end of if ( sizeOfGroupA < fan && sizeOfGroupB < fan ) */
+ /*
+ * If group A is full and there is room on group B, then add entry to
+ * group B
+ */
+ else if ( sizeOfGroupA >= fan && sizeOfGroupB < fan ) {
+ /*
+ * Place entry into group B, incrementing counter
+ */
+ tempB->next = I; /* add current entry to group B */
+ I = I->next; /* increment current entry */
+ tempB = tempB->next; /* increment group B ptr */
+ tempB->next = NULL; /* remove new entry from group I */
+
+ sizeOfGroupB++;
+ } /* end of if ( sizeOfGroupA >= fan ) */
+ /*
+ * If group B is full and there is room on group A, then add entry to
+ * group A
+ */
+ else if ( sizeOfGroupB >= fan && sizeOfGroupA < fan ) {
+ /*
+ * Place current entry into group A, incrementing counter
+ */
+ tempA->next = I; /* add current entry to group A */
+ I = I->next; /* increment current entry */
+ tempA = tempA->next; /* increment group A ptr */
+ tempA->next = NULL; /* remove new entry from group I */
+
+ sizeOfGroupA++;
+ } /* end of if ( sizeOfGroupB >= fan ) */
+ else {
+ /*
+ * Special(error) case when both groups are full and no where to
+ * place entry. Simply ignore entry and try to continue.
+ */
+ I = I->next;
+
+ errorMessage( "too many entries to partition", REPLACE );
+ errorMessage( name, PREPEND );
+
+ }
+ } /* end of loop for currentEntry */
+
+ return;
+} /* end paritionEntries() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/penalty.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/penalty.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/penalty.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/penalty.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,53 @@
+/*
+ *
+ * Name: penalty
+ * Input: index entry, A
+ * index entry. B
+ * Output: float value of penalty
+ * Return: float
+ * Description: Calculates and returns the penalty for the two input index
+ * entries. The penalty for the index is defined as the
+ * increase in hyper-cube volume. Note that the penalty
+ * routine is not communative, i.e., the penalty( A, B ) is
+ * not necessarily the penalty( B, A ).
+ * Calls: keyUnion()
+ * volume()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include "dataManagement.h" /* for primitive type definitions */
+#include "index.h" /* for IndexEntry definition */
+#include "indexKey.h" /* for IndexKey definition */
+
+/*
+ * Function Prototypes
+ */
+extern void keyUnion( IndexKey *A, IndexKey *B, IndexKey *U );
+extern Float volume( IndexKey key );
+
+Float penalty( IndexEntry A, /* first entry for penalty */
+ IndexEntry B ) /* second entry for penalty */
+{ /* beginning of penalty() */
+ Float penalty;
+ IndexKey key;
+
+ /*
+ * Find union of A and B
+ */
+ keyUnion( &A.key, &B.key, &key );
+
+ /*
+ * Determine increase in "volume"
+ */
+ penalty = volume( key ) - volume( A.key );
+
+ return ( penalty );
+} /* end of penalty() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/query.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/query.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/query.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/query.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,185 @@
+
+/*
+ * Name: query
+ * Input: root node of index, root
+ * search index key, searchKey
+ * search non-key list, searchNonKey
+ * validity check flag, checkValidity
+ * output function pointer, outputQuery
+ * Output: integer return code
+ * Return: QUERY_SUCCESS, or
+ * QUERY_INVALID_KEY_SEARCH_VALUE,
+ * QUERY_INVALID_NON_KEY_SEARCH_VALUE
+ * Description: The routine searchs the index and calls the outputQuery
+ * routine for each consistent data object found. The routine
+ * first uses the R-Tree index to find individual leaf nodes
+ * which point to data objects which have index keys which are
+ * consistent with the input search key. The found data
+ * object's non-key attributes are then compared with the input
+ * list of non-key search values for consistency. The input
+ * list of non-key search values consist of the attribute code
+ * and a character sequence. Two utility subroutines are used
+ * to check the validity of the input search values. The input
+ * is checked only when the validity input flag is set to TRUE
+ * which prevents multiple checks of the same data since this
+ * routine is applied recursively. Note that the index is
+ * never altered by a query which means no error is fatal. Two
+ * utility subroutines are used to determine consistency which
+ * is intersection for the DIS application. The utility
+ * subroutines are used to separate the specific hyper-cube
+ * dimension and character string from the general R-Tree
+ * algorithm.
+ *
+ * Once a consistent data object has been found, the input
+ * routine outputQuery() is called for this object. It's
+ * expected that the outputQuery() routine will place some
+ * representation of the data object into an output buffer for
+ * the query response. The query() routine does not define
+ * what the representation will be, which allows the calling
+ * program to determine the format and timing of the response
+ * display.
+ * Calls: consistentKey()
+ * consistentNonKey()
+ * errorMessage()
+ * validKey()
+ * validNonKey()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for NULL definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "dataObject.h" /* for DataAttribute and DataObject definitions */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "index.h" /* for IndexNode and IndexEntry definitions */
+#include "indexKey.h" /* for IndexKey definition */
+#include "query.h" /* for query return codes */
+
+/*
+ * Function prototypes
+ */
+extern Boolean consistentKey( IndexKey *A, IndexKey *B );
+extern Boolean consistentNonKey( Char *A, Char *B );
+extern Boolean validIndexKey( IndexKey *key );
+extern Boolean validAttributes( DataAttribute *attributes );
+
+Int query( IndexNode *node, /* current node of index */
+ IndexKey *searchKey, /* index key search values */
+ DataAttribute *searchNonKey, /* non-key search values */
+ Boolean checkValidity, /* flag to check validity */
+ void (*outputQuery)( DataObject *) ) /* output valid object */
+{ /* beginning of query() */
+ static Char name[] = "query";
+
+ assert( node );
+ assert( searchKey );
+ assert( !( checkValidity != TRUE && checkValidity != FALSE ) );
+
+ /*
+ * If flag is set, check validity of key and non-key values.
+ */
+ if ( checkValidity == TRUE ) {
+ if ( validIndexKey( searchKey ) == FALSE ) {
+ errorMessage( "invalid index key search values", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( QUERY_INVALID_KEY_SEARCH_VALUE );
+ } /* end validity check of key values */
+ else if ( validAttributes( searchNonKey ) == FALSE ) {
+ errorMessage( "invalid non-key search values", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( QUERY_INVALID_NON_KEY_SEARCH_VALUE );
+ } /* end validity check of non-key values */
+ } /* end of checkValidity == TRUE */
+
+ /*
+ * The routine is applied recursively so the current node may or may not be
+ * a leaf node. If it is a leaf node, the child referenced by the entries
+ * residing on the node are data objects. If it is not a leaf node, the
+ * child referenced by the entries are other nodes. So if the current
+ * level is not a leaf, recursively call the query routine on each
+ * consistent entry.
+ */
+ if ( node->level > LEAF ) {
+ IndexEntry *entry; /* temp entry for looping through list */
+
+ /*
+ * Loop through each entry on current node and query each consistent
+ * child node. Note that only the key values are available for
+ * consistency checks at any level greater than the LEAF level.
+ */
+ for ( entry = node->entries; entry != NULL; entry = entry->next ) {
+ if ( consistentKey( &entry->key, searchKey ) == TRUE ) {
+ query( entry->child.node, searchKey, searchNonKey, FALSE,
+ outputQuery );
+ } /* end of branch which is consistent */
+ } /* end of loop for entry */
+ } /* end of if ( node->level > LEAF ) */
+ else {
+ IndexEntry *entry; /* temp entry for looping through list */
+
+ /*
+ * Loop through each entry on current node and query each consistent
+ * child node. The first consistency check is made on the key value.
+ * If the key values are consistent, then the data object is checked
+ * for its non-key values. A temporary upperBound value is set to
+ * prevent out-of-range checks on the three types of data objects.
+ */
+ for ( entry = node->entries; entry != NULL; entry = entry->next ) {
+ if ( consistentKey( &entry->key, searchKey ) == TRUE ) {
+ DataAttribute *temp; /* attribute for list loop */
+ DataObject *object; /* allows easier reading */
+ Int upperBound; /* prevents out-of-range */
+ Boolean acceptanceFlag; /* flag to output object */
+
+ object = entry->child.dataObject;
+
+ upperBound = 0;
+ if ( object->type == SMALL ) {
+ upperBound = NUM_OF_SMALL_ATTRIBUTES;
+ } /* end of type == SMALL */
+ else if ( object->type == MEDIUM ) {
+ upperBound = NUM_OF_MEDIUM_ATTRIBUTES;
+ } /* end of type == MEDIUM */
+ else if ( object->type == LARGE ) {
+ upperBound = NUM_OF_LARGE_ATTRIBUTES;
+ } /* end of type == LARGE */
+
+ /*
+ * The loop checks each value of the non-key search list and
+ * compares that value for that specific attribute code to the
+ * value stored in the data object. If all of the attributes
+ * are consistent, the flag is set to TRUE at the end of the
+ * loop, and the outputQuery routine is called for the data
+ * object. If any of the attributes are not consistent, the
+ * flag is set to FALSE and the loop exits and the next entry
+ * is checked.
+ */
+ acceptanceFlag = TRUE;
+ temp = searchNonKey;
+ while ( temp != NULL && acceptanceFlag == TRUE ) {
+ if ( temp->code < upperBound ) {
+ acceptanceFlag = consistentNonKey(
+ object->attributes[ temp->code ].value.nonKey,
+ temp->attribute.value.nonKey );
+ } /* end of code < upperBound */
+ temp = temp->next;
+ } /* end of loop through non-key search value list */
+
+ if ( acceptanceFlag == TRUE ) {
+ outputQuery( entry->child.dataObject );
+ } /* end of acceptanceFlag == TRUE */
+ } /* end of if consistentKey == TRUE */
+ } /* end of loop for entry */
+ } /* end of if ( node->level == LEAF ) */
+
+ return ( QUERY_SUCCESS );
+} /* end query() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/query.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/query.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/query.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/query.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,43 @@
+
+/*
+ * DIS Data Management: query
+ *
+ * This header file contains the return codes for the query routine
+ * and the function prototype. There are two different failure modes for
+ * the routine. The first indicates that the search index key passed as
+ * input to the routine is invalid. The second indicates that the
+ * attribute code specifying which non-key attribute to search on is
+ * invalid (too small or too large).
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_QUERY_H
+#define DIS_QUERY_H
+
+#include "dataManagement.h" /* for primitive type definitions */
+#include "dataObject.h" /* for DataAttribute and DataObject definitions */
+#include "indexKey.h" /* for IndexKey definition */
+#include "index.h" /* for IndexNode definition */
+
+/*
+ * Return Codes
+ */
+#define QUERY_SUCCESS 0
+#define QUERY_INVALID_KEY_SEARCH_VALUE 1
+#define QUERY_INVALID_NON_KEY_SEARCH_VALUE 2
+
+/*
+ * Function prototype
+ */
+extern Int query( IndexNode *node, IndexKey *searchKey,
+ DataAttribute *searchNonKey, Boolean checkValidity,
+ void (*outputQuery)( DataObject *) );
+
+#endif /* DIS_QUERY_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/setMetricsData.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/setMetricsData.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/setMetricsData.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/setMetricsData.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,77 @@
+
+
+/*
+ * Name: setMetricsData
+ * Input: Metrics structure
+ * Output: Metrics structure
+ * Return: void
+ * Description: This routine sets two values for laster metric collection.
+ * The first is specific to the individual command being
+ * processed and sets the lastTimeMark field for that command
+ * metric structure. The second value set is the command type
+ * for later update which is stored in the lastCommand filed of
+ * the input Metric structure. If a command type is passed
+ * which is not recognized, it sets the lastCommand field to
+ * INVALID.
+ * Calls: getTime()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "getNextCommandCode.h" /* for Commandtype enumeration */
+#include "metrics.h" /* for Metrics definition */
+
+/*
+ * Function prototype
+ */
+extern Time getTime( void );
+
+void setMetricsData( Metrics *metrics, /* metrics struct to update */
+ CommandType command ) /* command to update */
+{ /* begin setMetricsData() */
+ Time temp; /* variable used to find current time */
+
+ assert( metrics );
+ assert( command == INIT || \
+ command == INSERT || \
+ command == QUERY || \
+ command == DELETE || \
+ command == NONE || \
+ command == INVALID );
+
+ /*
+ * Get the current time and set the appropriate command metric lastTimeMark
+ * field to this time. Also, set lastCommand field. If command is not an
+ * INSERT, QUERY, or DELETE, set lastCommand to INVALID which will prevent
+ * the updateMetricsData() routine from incorrectly altering any of the
+ * individual command metric statistics.
+ */
+ temp = getTime();
+ if ( command == INSERT ) {
+ metrics->insertCommandMetric.lastTimeMark = temp;
+ metrics->lastCommand = INSERT;
+ } /* end of command == INSERT */
+ else if ( command == QUERY ) {
+ metrics->queryCommandMetric.lastTimeMark = temp;
+ metrics->lastCommand = QUERY;
+ } /* end of command == QUERY */
+ else if ( command == DELETE ) {
+ metrics->deleteCommandMetric.lastTimeMark = temp;
+ metrics->lastCommand = DELETE;
+ } /* end of command == DELETE */
+ else {
+ metrics->lastCommand = INVALID;
+ } /* end of inappropriate command */
+
+ return;
+} /* end of setMetricsData() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/splitNode.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/splitNode.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/splitNode.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/splitNode.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,124 @@
+
+/*
+ * Name: splitNode
+ * Input: index node to split, nodeToSplit
+ * integer fan value, fan
+ * new index entry which caused split, entry
+ * Output: index entry of new node after splitting, splitEntry
+ * Return: SPLIT_NODE_SUCCESS, or
+ * SPLIT_NODE_ALLOCATION_FAILURE
+ * Description: This routine splits and index node. An index node needs to
+ * split whenever a new index entry is added to the node and
+ * the node is full, i.e., the current number of entries
+ * residing on the node is equal to the fan or order of the
+ * index tree. A node split consists of dividing the current
+ * entries of a node and the new entry into two groups via a
+ * partitionEntries routine. One group is placed onto the
+ * node and the other group is placed onto a new node created
+ * for that purpose. A new index entry is created for the new
+ * node and is returned as the splitEntry in the output.
+ * Since both a new index node and a new index entry are
+ * created during the splitting process, a memory allocation
+ * failure is possible during the execution of this
+ * subroutine. The allocation failure is fatal for most uses
+ * of the method, but in certain cases, splitting a leaf node
+ * for instance, a recovery is possible at a higher level.
+ * For this reason, the splitNode routine will "clean-up"
+ * before returning, i.e., free memory, etc.
+ * Calls: createIndexEntry()
+ * createIndexNode()
+ * deleteIndexNode()
+ * errorMessage()
+ * keysUnion()
+ * partitionEntries()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for NULL definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "index.h" /* for IndexNode and IndexEntry definitions */
+#include "splitNode.h" /* for splitNode() return codes */
+
+/*
+ * Function prototypes
+ */
+extern void partitionEntries( IndexEntry *I, Int fan, IndexEntry **A,
+ IndexEntry **B );
+extern void keysUnion( IndexEntry *I, IndexKey *U );
+
+Int splitNode( IndexNode *nodeToSplit, /* node to split */
+ IndexEntry *entry, /* entry which caused split */
+ Int fan, /* fan of index */
+ IndexEntry **splitEntry ) /* output entry of new node */
+{ /* beginning of splitNode() */
+ IndexEntry *listOfEntries; /* union of entries of nodeToSplit and entry */
+ IndexNode *splitNode; /* new split node referenced by splitEntry */
+
+ static Char name[] = "splitNode";
+
+ assert( nodeToSplit );
+ assert( nodeToSplit->entries );
+ assert( entry );
+ assert( MINIMUM_FAN_SIZE > 1 );
+ assert( fan >= MINIMUM_FAN_SIZE );
+
+ /*
+ * Create new index entry which will reference the newly created node.
+ * Check for memory allocation failure. Also, create new node for
+ * partitioning. The new node is a "sibling" of the input node, so its
+ * level is the same. If memory allocation failure, free index entry
+ * allocation in previous step, place message in error buffer, and return.
+ */
+ *splitEntry = createIndexEntry();
+ if ( *splitEntry == NULL ) {
+ errorMessage( "allocation failure - split entry", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( SPLIT_NODE_ALLOCATION_FAILURE );
+ } /* end of if ( *splitEntry == NULL ) */
+ else {
+ splitNode = createIndexNode( nodeToSplit->level );
+ if ( splitNode == NULL ) {
+ deleteIndexEntry( *splitEntry, nodeToSplit->level );
+ errorMessage( "allocation failure - sibling node", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( SPLIT_NODE_ALLOCATION_FAILURE );
+ } /* end of if ( splitNode == NULL ) */
+ } /* end of split entry and node allocation */
+
+ /*
+ * Create a list which is the union of the current entries of the node to
+ * split and the entry which caused the split to occur.
+ */
+ listOfEntries = entry;
+ listOfEntries->next = nodeToSplit->entries;
+ nodeToSplit->entries = NULL;
+ splitNode->entries = NULL;
+
+ /*
+ * Partition entries unto old nodeToSplit and new temporary node.
+ */
+ partitionEntries( listOfEntries, /* entries to partition */
+ fan, /* fan of index */
+ &(nodeToSplit->entries), /* 1st partitioned group */
+ &(splitNode->entries) ); /* 2nd partitioned group */
+
+ /*
+ * Set reference of splitEntry to new split node and adjust
+ * key of splitEntry for new node. Note that the key of the entry
+ * for nodeToSplit is adjusted in the same process that called splitNode.
+ */
+ keysUnion( splitNode->entries, &((*splitEntry)->key) );
+ (*splitEntry)->child.node = splitNode;
+
+ return ( SPLIT_NODE_SUCCESS );
+} /* end splitNode() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/splitNode.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/splitNode.h?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/splitNode.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/splitNode.h Sun Jan 27 23:23:39 2008
@@ -0,0 +1,35 @@
+
+/*
+ * DIS Data Management: splitNode
+ *
+ * This header file contains the return codes for the splitNode routine and
+ * the function prototype. The only failure possible for the slitNode
+ * routine is an allocation failure.
+ *
+ * Revision History:
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifndef DIS_SPLIT_NODE_H
+#define DIS_SPLIT_NODE_H
+
+#include "dataManagement.h" /* for primitive type definitions */
+#include "index.h" /* for IndexNode and IndexEntry definitions */
+
+/*
+ * Return Codes
+ */
+#define SPLIT_NODE_SUCCESS 0
+#define SPLIT_NODE_ALLOCATION_FAILURE 1
+
+/*
+ * Function prototypes
+ */
+extern Int splitNode( IndexNode *nodeToSplit, IndexEntry *entry,
+ Int fan, IndexEntry **splitEntry );
+
+#endif /* DIS_SPLIT_NODE_H */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/timer.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/timer.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/timer.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/timer.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,272 @@
+
+/*
+ * File Name: timer.c
+ * Purpose: Provides timing routines for the DIS Data Management
+ * Benchmark application. Preprocessor directives are setup to
+ * allow either the ANSI/ISO C standard time() routine to be
+ * used or the BSD Unix gettimeofday() routine to be used. The
+ * gettimeofday() routine has a fidelity of microseconds while
+ * the ANSI/ISO time() routine is only seconds. The Data
+ * Management baseline data sets will generally require a
+ * better timing resolution than seconds, but nothing exists
+ * within the ANSI/ISO C standard which provides the required
+ * fidelity. Because the DIS hardware teams are only required
+ * to conform to the ANSI/ISO C standard libraries and this
+ * will cause inaccuracies in the metric statistics, a
+ * compromise is implemented. If USE_GETTIMEOFDAY is defined
+ * (not TRUE/FALSE, just defined), the metrics will use the
+ * Unix standard gettimeofday() promoting the microseconds to
+ * milliseconds to allow storage in a long integer. If
+ * USE_GETTIMEOFDAY is not defined, the metrics will use the
+ * ANSI/ISO C standard time() routine. This will generally
+ * invalidate the metric statistical values for individual
+ * commands, but may provide a relatively accurate overall
+ * time required to complete the data set.
+ *
+ * Modifications required to run the program on different
+ * hardware systems with different system timing routines
+ * should only need to change this function. As long as the
+ * getTime() routine returns milliseconds from program start,
+ * the rest of the baseline source code should function
+ * correctly.
+ *
+ * Revision History:
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ * 04Jun99 Matthew Rivas Added SECONDS_TO_MILLI to ANSI/ISO C standard ver.
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#ifdef USE_GETTIMEOFDAY
+#include <sys/time.h> /* for timeval definition */
+#include <unistd.h> /* for gettimeofday() definition */
+#include "errorMessage.h" /* for errorMessage() definition */
+#else /* USE_GETTIMEOFDAY undefined */
+#include <time.h> /* for time() definition */
+#endif /* USE_GETTIMEOFDAY */
+
+#include <assert.h> /* for assert() */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "metrics.h" /* for Time type definition */
+
+/*
+ * Static value of program start time
+ * - value is stored as timeval returned by gettimeofday()
+ * - timeval struct represents the time in seconds and microseconds since
+ * Jan 1, 1970.
+ * - don't use structure because difficulty in working with two longs for
+ * statistical calcs and milliseconds will suffice for timing fidelity.
+ */
+#ifdef USE_GETTIMEOFDAY
+static struct timeval startTime;
+
+#define MILLION 1000000
+#define MILLION_TO_MILLI 1e-3
+#define SECONDS_TO_MILLI 1000
+#else
+static time_t startTime;
+
+#define SECONDS_TO_MILLI 1000
+#endif /* USE_GETTIMEOFDAY */
+
+/*
+ * Name: initTime
+ * Input: none
+ * Output: none
+ * Return: void
+ * Description: Initialize the static startTime variable which will be used
+ * by getTime() to return time in milliseconds since program
+ * start, i.e., when the initTime() routine was called.
+ * Calls: errorMessage()
+ * System: gettimeofday(), or
+ * time()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+void initTime( void )
+{ /* beginning of initTime() */
+#ifdef USE_GETTIMEOFDAY
+ Int error; /* flag for error checking on gettimeofday() */
+ static Char name[] = "initTime";
+#endif /* USE_GETTIMEOFDAY */
+
+#ifdef USE_GETTIMEOFDAY
+
+ error = gettimeofday( &startTime, NULL );
+ if ( error == -1 ) { /* check for error */
+ errorMessage( "system time failure - can't set start time", REPLACE );
+ errorMessage( name, PREPEND );
+ flushErrorMessage();
+ } /* end of if error == -1 */
+
+ /*
+ * Check that seconds and microseconds from Jan 1, 1970 are positive, and
+ * that the microseconds value is less than a million, otherwise the
+ * seconds would have been incremented.
+ */
+ assert( startTime.tv_sec >= 0 && \
+ startTime.tv_usec >= 0 && \
+ startTime.tv_usec < MILLION );
+
+#else /* USE_GETTIMEOFDAY undefined */
+
+ startTime = time( NULL );
+
+#endif /* USE_GETTIMEOFDAY */
+
+ return;
+} /* end of initTime() */
+
+/*
+ * Name: getTime
+ * Input: none
+ * Output: milliseconds since program start
+ * Return: Time
+ * Description: The routine provides a wrapper for the system timing
+ * routines and returns the current time in milliseconds from
+ * the beginning of program execution, i.e., when initTime()
+ * routine was called. The routine is setup to be compiled
+ * using the gettimeofday() routine or the ANSI/ISO standard
+ * time() routine.
+ * Calls: errorMessage()
+ * System: gettimeofday(), or
+ * difftime()
+ * time()
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+Time getTime( void )
+{ /* beginning of getTime() */
+ Time currentTime; /* current time in milliseconds */
+
+#ifdef USE_GETTIMEOFDAY
+ Int error; /* flag for checking on gettimeofday() */
+ struct timeval temp; /* current time returned by gettimeofday() */
+ static Char name[] = "getTime";
+#else /* USE_GETTIMEOFDAY undefined */
+ time_t temp; /* current time returned by time() */
+#endif /* USE_GETTIMEOFDAY */
+
+#ifdef USE_GETTIMEOFDAY
+
+ /*
+ * Check that seconds and microseconds from Jan 1, 1970 are positive, and
+ * that the microseconds value is less than a million, otherwise the
+ * seconds would have been incremented.
+ */
+ assert( startTime.tv_sec >= 0 && \
+ startTime.tv_usec >= 0 && \
+ startTime.tv_usec < MILLION );
+
+ /*
+ * Get the current time and store in temp. Check for error, an if none,
+ * calculate difference in milliseconds between current time and startTime.
+ */
+ error = gettimeofday( &temp, NULL );
+ if ( error == -1 ) { /* check for error */
+ errorMessage( "system time failure - can't get time", REPLACE );
+ errorMessage( name, PREPEND );
+ flushErrorMessage();
+
+ currentTime = MINIMUM_VALUE_OF_INT;
+ } /* end of if error == -1 */
+ else {
+ /*
+ * Check that seconds and microseconds from Jan 1, 1970 are positive,
+ * and that the microseconds value is less than a million, otherwise
+ * the seconds would have been incremented.
+ */
+ assert( temp.tv_sec >= 0 && \
+ temp.tv_usec >= 0 && \
+ temp.tv_usec < MILLION );
+ /*
+ * The current time must be later than the start time for the time
+ * difference arithmetic to work properly.
+ */
+ assert( temp.tv_sec > startTime.tv_sec || \
+ ( temp.tv_sec == startTime.tv_sec && \
+ temp.tv_usec >= startTime.tv_usec ) );
+
+ /*
+ * Determine milliseconds conversion of difference between the current
+ * time, temp, and the start time, startTime. Because 0 <= usec <
+ * MILLION and it is assumed that the current time is later than the
+ * start time, only two cases exist for the conversion. The first is
+ * that the current time microseconds are greater than the start time
+ * microseconds. For this case, the current time in milliseconds is
+ * the sum of the seconds difference and the microseconds difference
+ * with the appropriate conversion factors, i.e., SECONDS_TO_MILLI =
+ * 1000 and MILLION_TO_MILLI = 1e-3. The second case is that the
+ * current time microseconds is less than the start time microseconds.
+ * For this case, the current time in milliseconds is the sum of the
+ * seconds difference minus one and the microseconds difference plus a
+ * MILLION with the appropriate conversion factors. Note that the
+ * minus one to the seconds difference and plus a MILLION to the
+ * microseconds, is the carry, i.e., a second was taken from the
+ * seconds place and added to the microseconds place.
+ */
+ if ( temp.tv_usec >= startTime.tv_usec ) {
+ currentTime = SECONDS_TO_MILLI * ( temp.tv_sec - startTime.tv_sec );
+ currentTime += MILLION_TO_MILLI * ( temp.tv_usec - startTime.tv_usec );
+ } /* end of temp.usec >= start.usec */
+ else {
+ currentTime = SECONDS_TO_MILLI
+ * ( temp.tv_sec - startTime.tv_sec - 1 );
+ currentTime += MILLION_TO_MILLI
+ * ( temp.tv_usec - startTime.tv_usec + MILLION );
+ } /* end of temp.usec < start.usec */
+
+ /*
+ * Check for overflow of negative time difference, both of which should
+ * never happen since the system call should ensure non-negative
+ * differences and the maximum value for a time difference using
+ * milliseconds is 49.71 days.
+ */
+ if ( currentTime > MAXIMUM_VALUE_OF_INT ) {
+ errorMessage( "overflow error calculating current time", REPLACE );
+ errorMessage( name, PREPEND );
+ flushErrorMessage();
+
+ currentTime = MAXIMUM_VALUE_OF_INT;
+ } /* end of upper bound check on currentTime */
+ else if ( currentTime < 0 ) {
+ errorMessage( "start time appears not to be set", REPLACE );
+ errorMessage( name, PREPEND );
+ flushErrorMessage();
+
+ currentTime = 0;
+ } /* end of lower bound check on currentTime */
+ } /* end of if error != -1 */
+
+#else /* USE_GETTIMEOFDAY undefined */
+
+ /*
+ * Get the current time, determine the difference in seconds since
+ * the start time, convert seconds to milliseconds, and set current
+ * time to correct value.
+ */
+ temp = time( NULL );
+ currentTime = SECONDS_TO_MILLI * (Int)difftime( temp, startTime );
+
+#endif /* USE_GETTIMEOFDAY */
+
+ return ( currentTime );
+} /* end of getTime() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/updateMetricsData.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/updateMetricsData.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/updateMetricsData.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/updateMetricsData.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,120 @@
+
+/*
+ * Name: updateMetricsData
+ * Input: Metrics structure
+ * Output: Metrics structure
+ * Return: void
+ * Description: This routine determines the time required to complete
+ * a command. The routine uses the lastCommand field of
+ * of the metrics structure to determine which command
+ * to update. If the value of lastCommand is not one
+ * of the commands which has a command metric, then the
+ * user is informed and the routine exits. The routine
+ * updates the best and worst time fields of the command
+ * metric. Also, the running sum and sum of the squares
+ * for this command are updated.
+ * Calls: errorMessage()
+ * flushErrorMessage()
+ * getTime()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ *
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 27May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "getNextCommandCode.h" /* for CommandType enumeration */
+#include "metrics.h" /* for Metrics definition */
+
+/*
+ * Function prototypes
+ */
+extern Time getTime( void );
+
+void updateMetricsData( Metrics *metrics ) /* metrics struct to update */
+{ /* begin updateMetricsData() */
+ Time temp; /* variable used to find current time */
+ CommandMetric *commandMetric; /* command metric to update */
+
+ static Char name[] = "updateMetricsData";
+
+ assert( metrics );
+ assert( !( metrics->lastCommand != INIT && \
+ metrics->lastCommand != INSERT && \
+ metrics->lastCommand != QUERY && \
+ metrics->lastCommand != DELETE && \
+ metrics->lastCommand != NONE && \
+ metrics->lastCommand != INVALID ) );
+
+ /*
+ * Set the commandMetric pointer to the correct command metric to update
+ * based on the lastCommand field. The lastCommand field is assumed to be
+ * correctly setup before the call to updateMetricsData(). If the value of
+ * lastCommand is not an INSERT, QUERY, or DELETE, an error message is
+ * displayed, lastCommand is set to INVALID, and the routine returns
+ * without updating any of the other command metric structures.
+ */
+ if ( metrics->lastCommand == INSERT ) {
+ commandMetric = &(metrics->insertCommandMetric);
+ } /* end of command == INSERT */
+ else if ( metrics->lastCommand == QUERY ) {
+ commandMetric = &(metrics->queryCommandMetric);
+ } /* end of command == QUERY */
+ else if ( metrics->lastCommand == DELETE ) {
+ commandMetric = &(metrics->deleteCommandMetric);
+ } /* end of command == DELETE */
+ else {
+ metrics->lastCommand = INVALID;
+ return;
+ } /* end of inappropriate command */
+
+ /*
+ * Get the current time and update the command metric. The first step is
+ * to calculate the time difference between the current time and the
+ * lastTimeMark stored in the command metric structure. A check is made to
+ * insure that the time returned is a valid time, i.e., non-negative. The
+ * next step is to compare the time difference, stored as temp, with the
+ * best and worst time differences stored in the command structure. If
+ * temp is less than the best, the best is set to temp. If temp is greater
+ * than the worst, the worst is set to temp. Next, the running sum is
+ * updated and the running sum of the squares is also updated. Finally,
+ * the number of commands updated for this command metric is incremented
+ * for later statistical calculations in calcMetricsData().
+ */
+ temp = getTime() - commandMetric->lastTimeMark;
+
+ if ( temp < 0 ) {
+ errorMessage( "lastTimeMark doesn't seem to be set", REPLACE );
+ errorMessage( name, PREPEND );
+ flushErrorMessage();
+ } /* end of validity check on time */
+ else {
+ if ( temp < commandMetric->best ) {
+ commandMetric->best = temp;
+ } /* end of temp < best */
+
+ if ( temp > commandMetric->worst ) {
+ commandMetric->worst = temp;
+ } /* end of temp > worst */
+
+ commandMetric->sum += (Double)temp;
+ commandMetric->sumSquares += ( (Double)temp * (Double)temp );
+
+ commandMetric->numOfCommands++;
+ } /* end of update of command metric */
+
+ /*
+ * Set lastCommand field to INVALID to prevent any erroneous update repeats
+ */
+ metrics->lastCommand = INVALID;
+
+ return;
+} /* end of updateMetricsData() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/valid.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/valid.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/valid.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/valid.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,145 @@
+
+/*
+ * File Name: valid.c
+ * Purpose: Determines the validity for both index key and non-key
+ * attributes.
+ *
+ * Revision History:
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include <stdlib.h> /* for NULL definition */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "dataObject.h" /* for DataAttribute definition */
+#include "errorMessage.h" /* for errorMessage() definition */
+#include "indexKey.h" /* for IndexKey definition */
+
+/*
+ *
+ * Name: validIndexKey
+ * Input: index key, A
+ * Output: flag indicating validity
+ * Return: TRUE or FALSE
+ * Description: Returns boolean value indicating if the input index key is
+ * valid, i.e., the lower point is lower than the upper point,
+ * etc.
+ * Calls: errorMessage()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+Boolean validIndexKey( IndexKey *key ) /* key to validate */
+{ /* beginning of validIndexKey() */
+ Boolean flag = TRUE;
+ static Char name[] = "validIndexKey";
+
+ assert( key );
+
+ /*
+ * Check that lower point is less than upper point
+ */
+ if ( key->lower.T >= key->upper.T ) {
+ errorMessage( "Lower T > Upper T", REPLACE );
+ errorMessage( name, PREPEND );
+ flag = FALSE;
+ }
+ else if ( key->lower.X >= key->upper.X ) {
+ errorMessage( "Lower X > Upper X", REPLACE );
+ errorMessage( name, PREPEND );
+ flag = FALSE;
+ }
+ else if ( key->lower.Y >= key->upper.Y ) {
+ errorMessage( "Lower Y > Upper Y", REPLACE );
+ errorMessage( name, PREPEND );
+ flag = FALSE;
+ }
+ else if ( key->lower.Z >= key->upper.Z ) {
+ errorMessage( "Lower Z > Upper Z", REPLACE );
+ errorMessage( name, PREPEND );
+ flag = FALSE;
+ }
+
+ return ( flag );
+} /* end of validIndexKey() */
+
+/*
+ *
+ * Name: validAttributes
+ * Input: list of attributes
+ * Output: flag indicating validity
+ * Return: TRUE or FALSE
+ * Description: Returns boolean value indicating if all attributes in list
+ * are valid. An attribute is valid if the code lies within
+ * the specified range and if key values lie within range and
+ * non-key values are not NULL.
+ * Calls: errorMessage()
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+Boolean validAttributes( DataAttribute *attributes ) /* attribute to validate */
+{ /* beginning of validAttributes() */
+ DataAttribute *temp; /* looping variable for checking list of attributes */
+
+ static Char name[] = "validAttributes";
+
+ assert( MIN_ATTRIBUTE_CODE < NUM_OF_KEY_ATTRIBUTES );
+ assert( MIN_ATTRIBUTE_CODE < MAX_ATTRIBUTE_CODE );
+ assert( MAX_ATTRIBUTE_CODE < NUM_OF_LARGE_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_SMALL_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_MEDIUM_ATTRIBUTES );
+ assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_LARGE_ATTRIBUTES );
+
+ /*
+ * Loop through attribute list checking each attribute. An attribute is
+ * checked by first checking the code. If the code is in range, check for
+ * key or non-key value. If key, check float range. If non-key, check
+ * non-NULL.
+ */
+ for ( temp = attributes; temp != NULL; temp = temp->next ) {
+ /*
+ * check for bad attribute code
+ */
+ if ( temp->code < MIN_ATTRIBUTE_CODE ||
+ temp->code > MAX_ATTRIBUTE_CODE ) {
+ errorMessage( "invalid attribute code", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( FALSE );
+ }
+ else {
+ if ( temp->code >= MIN_ATTRIBUTE_CODE &&
+ temp->code < NUM_OF_KEY_ATTRIBUTES ) {
+ /*
+ * Check key value for range
+ */
+ if ( temp->attribute.value.key < MINIMUM_VALUE_OF_FLOAT ||
+ temp->attribute.value.key > MAXIMUM_VALUE_OF_FLOAT ) {
+ errorMessage( "key value out-of-range", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( FALSE );
+ }
+ }
+ else {
+ /*
+ * Check non-key value for non-NULL
+ */
+ if ( temp->attribute.value.nonKey == NULL ) {
+ errorMessage( "non-key value set to NULL", REPLACE );
+ errorMessage( name, PREPEND );
+ return ( FALSE );
+ }
+ }
+ }
+ }
+
+ return ( TRUE );
+} /* end of validAttributes() */
Added: test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/volume.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/volume.c?rev=46435&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/volume.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/dbms/volume.c Sun Jan 27 23:23:39 2008
@@ -0,0 +1,43 @@
+/*
+ *
+ * Name: volume
+ * Input: index key, key
+ * Output: float value of volume of key
+ * Return: float
+ * Description: Calculates and returns the volume of the provided index key.
+ * Calls:
+ * System:
+ * Author: M.L.Rivas
+ *
+ * Revision History:
+ * Date Name Revision
+ * ------- --------------- ------------------------------
+ * 24May99 Matthew Rivas Created
+ *
+ * Copyright 1999, Atlantic Aerospace Electronics Corp.
+ */
+
+#include <assert.h> /* for assert() */
+#include "dataManagement.h" /* for primitive type definitions */
+#include "indexKey.h" /* for IndexKey definition */
+
+Float volume( IndexKey key ) /* input key for volume calc */
+{ /* beginning of volume() */
+ Float vol; /* calculated volume of index key */
+
+ /*
+ * Determine "volume" of key
+ */
+ vol = ( key.upper.T - key.lower.T );
+ vol *= ( key.upper.X - key.lower.X );
+ vol *= ( key.upper.Y - key.lower.Y );
+ vol *= ( key.upper.Z - key.lower.Z );
+
+ /* assert( vol > 0.0 ); */
+ if (vol <= 0.0) {
+ Float* p = 0;
+ vol = *p;
+ }
+
+ return ( vol );
+} /* end of volume() */
More information about the llvm-commits
mailing list