A Stronger Defense Through Better Software
A Service Provided By
George Chastain, Huntsville, Alabama

Résumé
Home What's New? About Security Contact Submit Content Disclaimers

Search This Site


powered by FreeFind

Targeted Web Search

Departments
Development

Test, QA & Safety
The Biz

Information Security

Joint Resources

General
CDR
Systems
Weapons 101
DoD Links

Media
Office Resources
Defense News
Defense Magazines

Tech & World News

Reader's Corner

Books

 ©2006 G. Chastain

Generic Map Package in Ada 95

Developed By: George Chastain

Download Source

Some time ago, I developed a generic package that implemented a mapped ordered list.   This generic package allows the client to instantiate an ordered list of any type of data and map each element in the list to a key.  The key may also be any type of data, including a record type.  The package, GENERIC_MAP has been used often.

This class may be used in declaring and manipulating objects containing a list of data ordered by a specific, primary key. The list may contain multiple entries with the same primary key. They are not required to be unique.  All memory-management for objects of the class is automatically handled by the class.

This kinda-sorta-somewhat implements the basic functionality of the multimap container class template in the C++ Standard Template Library for those of you familiar with C++.

The real power comes from the generics that the instantiation of this generic package provides.

IMPORTANT: INSTANTIATING THIS GENERIC PACKAGE DOES NOT CREATE ANY Ordered Map. IT SIMPLY PROVIDES THE TYPES AND FUNCTIONALITY FOR MANIPULATING ORDERED Ordered Map OF A SPECIFIED TYPE.

GENERIC FORMAL PARAMETERS

This section describes the Generic Formal Parameters that MUST be supplied for an instantiation of this package.

ELEMENT_TYPE
The Generic Actual Paramter specified for this Generic Formal Parameter should be the type to be used for each entry in the Ordered Map.
 
KEYTYPE
The Generic Actual Parameter specified for this Generic Formal Parameter should be the type to be used for the primary key contained within each entry of the Ordered Map. The Ordered Map is always ordered according to the primary key. ELEMENT_TYPE should contain the KEYTYPE key or it should be the same type.
 

function OrderCompare(Key1 : in KEYTYPE; Key2 : in KEYTYPE) return Boolean is <>;

The Generic Actual Parameter specified for this Generic Formal Subprogram is used to control the order of the list. This function is used when an item is inserted into the list to control the ordering of the entries in the list. The client-specified function should compare Key1 to Key2 and return TRUE if Key1 is logically less than Key2.
 

function keyequal(Key1 : in KEYTYPE; Key2 : in KEYTYPE) return Boolean;

The Generic Actual Parameter specified for this Generic Formal Subprogram is used to check to see if two keys are equal.

 

PUBLIC DATA TYPES

This section describes the data types available to the client by an instantiation of this generic package.

type ORDERED_MAP_TYPE is private;

Used in declaring objects containing an Ordered Map.
 

type OCCURRENCE_TYPE is (FIRST, LAST, EVERY, NOT_DEFINED);

Used in by the search and delete subprograms to specify which occurrence(s) of item(s) to return or delete.

PUBLIC INTERFACES

This section describes the public interfaces for the Generic Ordered Map.  The Ordered_Map type maintains a Location Pointer within the Ordered Map.  Search functions, as well as the Next(), Prev, GetData() and UpdateData() all utilize and/or update the Location Pointer. Details will be noted below in the discussions of the individual public interfaces.

 

procedure Insert(Ordered_Map : in out ORDERED_MAP_TYPE;  
                 Key : in KEYTYPE;  
                 Item : in ELEMENT_TYPE);
Used to add an element to the Ordered Map, "Ordered_Map".  The new element is inserted into the list based on the criteria defined by the OrderCompare() function supplied by the client when this generic is instantiated. The Location Pointer within the Ordered_Map will be updated to point to the location of the newly inserted item.
 
function Size(Ordered_Map : in ORDERED_MAP_TYPE) return integer;
Returns the number of entries in "Ordered_Map".

 

procedure Delete(Ordered_Map : in out ORDERED_MAP_TYPE; 
                 Key         : in KEYTYPE; 
                 Occurrence  : in OCCURRENCE_TYPE);
Used to delete the data from the Ordered Map, "Ordered_Map" containing the specified primary key, "Key", according to the setting of "Occurrence". The caller may specify Occurrence as follows:
FIRST -- Deletes the first occurrence of an item containing primary key "Key".
LAST -- Deletes the last occurrence of an item containing primary key "Key".
EVERY -- Deletes all occurrences of items containing primary key "Key".
If the Location Pointer was positioned at the item that is being deleted, the Location Pointer will be updated to "point" to the item AFTER the one that is being deleted unless it was positioned at the end of the list. In that case, the Location Pointer will be positioned at the new end of the list.

 

function Search(Ordered_Map : in ORDERED_MAP_TYPE; 
                Key         : in KEYTYPE; 
                Occurrence  : in OCCURRENCE_TYPE := EVERY; 
                DeleteFlag  : in Boolean := FALSE ) return ORDERED_MAP_TYPE;
Returns the data stored in the Ordered Map, "Ordered_Map" containing the specified primary key, "Key".  The function returns a list of type ORDERED_MAP_TYPE. The returned list may contain more than one item if there were multiple entries in the list containing the same key.  NOTE: The Ordered Map is always ordered by KEYTYPE. The caller may specify Occurrence as follows:
FIRST -- Searches the first occurrence of an item containing primary key "Key".
LAST -- Searches the last occurrence of an item containing primary key "Key".
EVERY -- Searches all occurrences of items containing primary key "Key".
If the client sets the "DeleteFlag" parameter to TRUE on the call, then any and all items found and returned will ALSO be deleted from the Ordered Map, "Ordered_Map".  If the Location Pointer was positioned at an item that was deleted, the Location Pointer will be repositioned according to the rules set forth in the description for the Delete() interface above.  If the Search() was performed for the FIRST occurrence of a Key, and that item is found, the Location Pointer will be repositioned to that entry. If the Search() was performed for EVERY occurrence of a Key or for the LAST occurence of the Key, the Location Pointer will be repositioned at the LAST entry for the Key in the  Ordered_Map.
function DoesThisKeyExist(Ordered_Map : in out ORDERED_MAP_TYPE; 
                          Key         : in KEYTYPE) return Boolean;
Returns TRUE if the specified Key is present in the Ordered Map. That is, it returns TRUE if there is AT LEAST ONE entry in the Ordered Map for that key.  This allows the client to make a "quick" check of the Ordered Map for the presence of an key without the added overhead of returning data for one or more entries associated with the specified key.
procedure GetFirst(Ordered_Map : in out ORDERED_MAP_TYPE; 
                   Key         : in KEYTYPE; 
                   Result      : out ELEMENT_TYPE; 
                   DeleteFlag  : in Boolean := FALSE);
Returns the first occurrence of an entry with the specified Key. The entry is returned in "Result".  The same rules apply to the handling of the Location Pointer by an instantiation of the Generic_Search() procedure as are discussed in the description of Search() above.
procedure Clear(Ordered_Map : in out ORDERED_MAP_TYPE);
Frees up all memory allocated to the Ordered Map. Note that the allocated memory is also automatically freed when an object of type ORDERED_MAP_TYPE is destroyed.
procedure GetBegin(Ordered_Map : in ORDERED_MAP_TYPE; 
                   Key         : out KEYTYPE; 
                   Item        : out ELEMENT_TYPE);
Returns the item in the Ordered Map "Ordered_Map" that is at the beginning of the list. Depending on how the OrderCompare function behaves, this could be either the logically smallest or the logically largest item in the list.  The Location Pointer is positioned at the beginning of the Ordered_Map.
procedure GetEnd(Ordered_Map : in ORDERED_MAP_TYPE; 
                 Key         : out KEYTYPE; 
                 Item        : out ELEMENT_TYPE);
Returns the item in the Ordered Map "Ordered_Map" that is at the end of the list. Depending on how the OrderCompare function behaves, this could be either the logically smallest or the logically largest item in the list.  The Location Pointer is positioned at the end of the Ordered_Map.
procedure PopBegin(Ordered_Map : in out ORDERED_MAP_TYPE; 
                   Key         : out KEYTYPE; 
                   Item        : out ELEMENT_TYPE);
Returns the item in the Ordered Map "Ordered_Map" that is at the beginning of the list. Depending on how the OrderCompare function behaves, this could be either the logically smallest or the logically largest item in the list. It also removes that item from the list.  The Location Pointer is unchanged if it was not positioned at the beginning of the Ordered_Map. If it was positioned at the beginning of the Ordered_Map, it will be repositioned to the new starting entry of the list. If there was only one entry in the list when PopBegin() is called, the Location Pointer will be 0.
procedure PopEnd(Ordered_Map : in out ORDERED_MAP_TYPE; 
                 Key         : out KEYTYPE; 
                 Item        : out ELEMENT_TYPE);
Returns the item in the Ordered Map "Ordered_Map" that is at the end of the list. Depending on how the OrderCompare function behaves, this could be either the logically smallest or the logically largest item in the list.   It also removes that item from the list.  The Location Pointer is unchanged if it was not positioned at the end of the Ordered_Map. If it was positioned at the end of the Ordered_Map, it will be repositioned to the new end entry of the list. If there was only one entry in the list when PopEnd() is called, the Location Pointer will be 0.

 

procedure Next(Ordered_Map : in out ORDERED_MAP_TYPE);
Moves the Location Poniter to the next item in the Ordered_Map. If the Location Pointer was at the end of the list when the client calls Next(), CONSTRAINT_ERROR is raised.
procedure Prev(Ordered_Map : in out ORDERED_MAP_TYPE);
Moves the Location Poniter to the previous item in the Ordered_Map. If the Location Pointer was at the beginning of the list when the client calls Prev(), CONSTRAINT_ERROR is raised.
procedure GetData(Ordered_Map : in ORDERED_MAP_TYPE; 
                  Key         : out KEYTYPE; 
                  Item        : out ELEMENT_TYPE);
The GetData() procedure allows the client to obtain the key and the associated data from the position of the Location Pointer.
procedure UpdateData(Ordered_Map : in ORDERED_MAP_TYPE; 
                     Item        : in ELEMENT_TYPE);
The UpdateData() procedure allows the client to update the data stored at the position of the Location Pointer.  CONSTRAINT_ERROR is raised if the list is empty.

GENERIC SUBPROGRAMS PROVIDED BY AN INSTANTIATION OF THIS CONTAINER CLASS

This section describes the Generic Subprograms provided by an instantiation of this generic container class. These subprograms are optional in that the client is free to instantiate any or none of these subprograms. In order to instantiate any of these custom Generic Subprograms, the client must first create an instantiation of this generic Ordered Map container class. Then the client may instantiate versions of these Generic Subprograms from that instantiation of this generic container class.

GENERIC
procedure Generic_Traverse(Ordered_Map : in out ORDERED_MAP_TYPE);
Allows the client to instantiate a procedure to traverse the entire list, typically to modify its contents. The client must provide the Generic Actual Parameter for the following Generic Formal Parameter:
procedure Visit(Key  : in KEYTYPE; 
                Item : in ELEMENT_TYPE);
This client-supplied procedure accepts a parameter of the type specified for the Generic Formal Parameter ELEMENT_TYPE when this container class was instantiated. This would also be a convenient way to print the contents of the list. The client would provide a print procedure for the Visit() Generic Subprogram that would print the contents of any given entry. The position of the Location Pointer is set to the end of the Ordered Map.
GENERIC
procedure Generic_Traverse2(Ordered_Map : in out ORDERED_MAP_TYPE; 
                            DATA        : in out RETURN_TYPE);
Used to traverse the Ordered Map and return any kind of the client wishes.  The client must provide a Generic Actual Parameter data type for the Generic Formal Parameter RETURN_TYPE when instantiating the generic Generic_Traverse2 procedure. Further, the client must specify a Generic Actual Parameter procedure for the following Generic Formal Parameter:
procedure Visit2(Key  : in KEYTYPE; 
                 Item : in ELEMENT_TYPE; 
                 DATA : in out RETURN_TYPE);
This client-supplied procedure accepts a parameter of the type specified for the Generic Formal Parameter ELEMENT_TYPE when this container class was instantiated. Further, the client-supplied procedure accepts a parameter of the type specified for RETURN_TYPE when instantiating this generic procedure, Generic_Traverse2().  This gives the client the capability to return special information as a result of the traversal.  For example, the client could obtain a linked list of data, possibly a subset of the Ordered Map based on criteria defined by the client-supplied Visit2() procedure.  The position of the Location Pointer is set to the end of the Ordered Map.
GENERIC
function Generic_Search(Ordered_Map : in ORDERED_MAP_TYPE; 
                        Criteria    : in GENERIC_SEARCH_CRITERIA_TYPE; 
                        Occurrence  : in OCCURRENCE_TYPE := EVERY; 
                        DeleteFlag  : in Boolean := FALSE )  return ORDERED_MAP_TYPE;
Used to search for any item in the list based on a client-specified set of criteria.  The client must provide a Generic Actual Parameter for the Generic Formal Parameter GENERIC_SEARCH_CRITERIA_TYPE when the client instantiates Generic_Search().  This is the data type containing the information to be used in the search.  The instantiation of Generic_Search() will use the information contained by the parameter "Criteria" when searching for items in the Orderd List.  The client must also provide a Generic Actual Parameter for the following Generic Formal Parameter:
function Generic_Search_Compare(Item     : in ELEMENT_TYPE; 
                                Criteria : in GENERIC_SEARCH_CRITERIA_TYPE) return BOOLEAN;
This client-supplied procedure will compare information contained within the "Criteria" passed into Generic_Search() against the data within any given entry of the Ordered Map. This client-supplied Generic Actual Parameter must return TRUE if the criteria results in a positive match for the data in any given entry of the Ordered Map. When the client calls the instantiation of Generic_Search(), the client may specify Occurrence as follows:
FIRST -- Searches the first occurrence of an item matching the specified criteria.
LAST -- Searches the last occurrence of an item matching the specified criteria.
EVERY -- Searches all occurrences of items matching the specified criteria.
The same rules apply to the handling of the Location Pointer by an instantiation of the Generic_Search() procedure as are discussed in the description of Search() above.
GENERIC
function Generic_Delete(Ordered_Map : in ORDERED_MAP_TYPE; 
                        Criteria    : in GENERIC_DELETE_CRITERIA_TYPE) return BOOLEAN;
Used to delete entries from the list based on a client-specified set of criteria.  The client must provide a Generic Actual Parameter for the Generic Formal Parameter GENERIC_DELINSERT_CRITERIA_TYPE when the client instantiates Generic_Delete().  Further, the client must provide a Generic Actual Parameter for the following  Generic Formal Parameter:
function Generic_Delete_Compare(Item     : in ELEMENT_TYPE; 
                                Criteria : in GENERIC_DELINSERT_CRITERIA_TYPE) return BOOLEAN;
This client-supplied procedure will compare information contained within the "Criteria" passed into Generic_Delete() against the data in each entry of the Ordered Map. This client-supplied Generic Actual Parameter must return TRUE if the criteria results in a positive match for the data in any given- entry of the Ordered Map.  For every entry for which the Generic_Delete_Compare() function returns TRUE, the item will be deleted from the Ordered Map.  The same rules apply regarding the position of the Location Pointer as described for the Delete() procedure above.
GENERIC
procedure GenericDeletionInsert(Ordered_Map : in ORDERED_MAP_TYPE; 
                                Item        : in ELEMENT_TYPE; 
                                Criteria    : in GENERIC_INSERT_CRITERIA_TYPE);

 

A more specialized insert. This procedure allows the client to insert an item into the Ordered Map WHILE DELETING ENTRIES LOWER/HIGHER IN LOGICAL ORDER THAT MATCH A CLIENT-SPECIFIED SET OF CRITERIA. That is, the client is able to delete any entries from the Ordered Map that come before the item being inserted according to criteria supplied by the client. When instantiating the generic subprogram Generic_Insert(), the client must provide a Generic Actual Parameter data type for the Generic Formal Parameter GENERIC_INSERT_CRITERIA_TYPE. This will contain data used as the deletion criteria. Further, the client must supply a function for the following Generic Formal Parameter:
function Generic_Deletion_Compare(Item     : in ELEMENT_TYPE; 
                                  Criteria : in GENERIC_INSERT_CRITERIA_TYPE) return BOOLEAN;
This function will compare the contents of the criteria passed into the instantiation of the Generic_Insert() subprogram with each element in the list UP TO THE POINT OF INSERTION. Any comparison that returns TRUE will cause the instantiation of Generic_Insert() to delete that item from the list, "Ordered_Map". This is a more efficient way of inserting items if you need to delete some, or all, items logically before the item being inserted. This prevents having to instantiate Generic_Delete() and deleting some items then calling Insert() to insert the new item.  The instantiation of Generic_Insert() returns immediately after the insertion of the new item. The same rules apply to the handling of the Location Pointer by an instantiation of the GenericDeletionInsert() procedure as are discussed in the description of Insert() above.

Top

EXCEPTIONS DEFINED

This section describes the exceptions that may be raised by subprograms provided by this container class.

INVALID_INPUT_DATA : Raised if an invalid Ordered Map is passed into a procedure or function.

ITEM_NOT_FOUND : Raised if an item being searched for in a search or delete call is not found.

NULL_LIST : Raised if a search or delete operation is attempted on an empty list.

ADDITIONAL NOTES

Assignment is defined for the data type ORDERED_MAP_TYPE. When assigning an Ordered Map to another Ordered Map of the same type, a duplicate of the original list is made and assigned to the target list of the assignment. The target list does NOT represent the same list as the original list. It is a copy. Therefor, modifying one list will not make changes to the copy.

No guarantees are provided with this code either expressed or implied.  I accept no liability for any damages or losses incurred through the use of this code.  I would advise you to thoroughly test this code for yourself before committing to use it on an important project.

Enjoy.  
George.

Download Source Ada Package (Self-extracting Exe) 

Top