Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals

st_add.c

Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 2002 by Kevin L. Mitchell <klmitch@mit.edu>
00003 **
00004 ** This library is free software; you can redistribute it and/or
00005 ** modify it under the terms of the GNU Library General Public
00006 ** License as published by the Free Software Foundation; either
00007 ** version 2 of the License, or (at your option) any later version.
00008 **
00009 ** This library is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 ** Library General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU Library General Public
00015 ** License along with this library; if not, write to the Free
00016 ** Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00017 ** MA 02111-1307, USA
00018 **
00019 ** @(#)$Id: st_add.c,v 1.5 2006/07/13 20:27:36 klmitch Exp $
00020 */
00028 #include <errno.h>
00029 
00030 #include "dbprim.h"
00031 #include "dbprim_int.h"
00032 
00033 RCSTAG("@(#)$Id: st_add.c,v 1.5 2006/07/13 20:27:36 klmitch Exp $");
00034 
00035 unsigned long
00036 st_add(smat_table_t *table, smat_entry_t **entry_p,
00037        smat_head_t *head1, link_loc_t loc1, smat_entry_t *ent1,
00038        smat_head_t *head2, link_loc_t loc2, smat_entry_t *ent2)
00039 {
00040   smat_entry_t *se;
00041   unsigned long retval = 0;
00042   unsigned int freeflags = 0;
00043   db_key_t key;
00044 
00045   initialize_dbpr_error_table(); /* initialize error table */
00046 
00047   /* Verify arguments--like ll_add(), but has to account for two seperate
00048    * linked lists
00049    */
00050   if (!st_verify(table) || !sh_verify(head1) || !sh_verify(head2) ||
00051       head1->sh_elem != SMAT_LOC_FIRST || head2->sh_elem != SMAT_LOC_SECOND ||
00052       (ent1 && !se_verify(ent1)) || (ent2 && !se_verify(ent2)) ||
00053       ((loc1 == LINK_LOC_BEFORE || loc1 == LINK_LOC_AFTER) && !ent1) ||
00054       ((loc2 == LINK_LOC_BEFORE || loc2 == LINK_LOC_AFTER) && !ent2))
00055     return DB_ERR_BADARGS;
00056 
00057   /* verify that everything's in the right tables... */
00058   if ((head1->sh_table && head1->sh_table != table) ||
00059       (head2->sh_table && head2->sh_table != table) ||
00060       (ent1 && ent1->se_table != table) ||
00061       (ent2 && ent2->se_table != table))
00062     return DB_ERR_WRONGTABLE;
00063 
00064   if (!(se = _smat_alloc())) /* get an entry object */
00065     return ENOMEM;
00066 
00067   freeflags |= ST_REM_FREE; /* entry has been allocated */
00068 
00069   se->se_object[SMAT_LOC_FIRST] = sh_object(head1); /* set up the hash key */
00070   se->se_object[SMAT_LOC_SECOND] = sh_object(head2);
00071   dk_key(&key) = se->se_object;
00072   dk_len(&key) = sizeof(se->se_object);
00073 
00074   /* add the element to the hash table first */
00075   if ((retval = ht_add(&table->st_table, &se->se_hash, &key)))
00076     goto error;
00077 
00078   freeflags |= ST_REM_HASH; /* entry must be removed from hash table */
00079 
00080   /* add the element to the first linked list */
00081   if ((retval = ll_add(&head1->sh_head, &se->se_link[SMAT_LOC_FIRST], loc1,
00082                        ent1 ? &ent1->se_link[SMAT_LOC_FIRST] : 0)))
00083     goto error;
00084 
00085   freeflags |= ST_REM_FIRST; /* entry must be removed from linked list 1 */
00086 
00087   /* add the element to the second linked list */
00088   if ((retval = ll_add(&head2->sh_head, &se->se_link[SMAT_LOC_SECOND], loc2,
00089                        ent2 ? &ent2->se_link[SMAT_LOC_SECOND] : 0)))
00090     goto error;
00091 
00092   head1->sh_table = head2->sh_table = table; /* remember our table */
00093   se->se_table = table;
00094 
00095   if (entry_p) /* user wants to know which entry it is */
00096     *entry_p = se;
00097 
00098   return 0; /* all done! */
00099 
00100  error:
00101   /* unlink entry from linked list 1 */
00102   if ((freeflags & ST_REM_FIRST) &&
00103       ll_remove(&head1->sh_head, &se->se_link[SMAT_LOC_FIRST]))
00104     return DB_ERR_UNRECOVERABLE;
00105 
00106   /* remove element from hash table */
00107   if ((freeflags & ST_REM_HASH) && ht_remove(&table->st_table, &se->se_hash))
00108     return DB_ERR_UNRECOVERABLE;
00109 
00110   /* return element to free pool */
00111   if (freeflags & ST_REM_FREE)
00112     _smat_free(se);
00113 
00114   return retval; /* return error */
00115 }

Generated on Sat Jul 15 14:10:33 2006 for DatabasePrimitivesLibrary by  doxygen 1.4.4