~ubuntu-branches/ubuntu/natty/gdbm/natty

« back to all changes in this revision

Viewing changes to gdbmdelete.c

  • Committer: Bazaar Package Importer
  • Author(s): James Troup
  • Date: 2000-12-30 01:07:10 UTC
  • Revision ID: james.westby@ubuntu.com-20001230010710-x13c8n0wop4zneh5
Tags: upstream-1.7.3
ImportĀ upstreamĀ versionĀ 1.7.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* gdbmdelete.c - Remove the key and its associated data from the database. */
 
2
 
 
3
/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
 
4
    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
 
5
 
 
6
    GDBM is free software; you can redistribute it and/or modify
 
7
    it under the terms of the GNU General Public License as published by
 
8
    the Free Software Foundation; either version 2, or (at your option)
 
9
    any later version.
 
10
 
 
11
    GDBM is distributed in the hope that it will be useful,
 
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
    GNU General Public License for more details.
 
15
 
 
16
    You should have received a copy of the GNU General Public License
 
17
    along with GDBM; see the file COPYING.  If not, write to
 
18
    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
 
 
20
    You may contact the author by:
 
21
       e-mail:  phil@cs.wwu.edu
 
22
      us-mail:  Philip A. Nelson
 
23
                Computer Science Department
 
24
                Western Washington University
 
25
                Bellingham, WA 98226
 
26
       
 
27
*************************************************************************/
 
28
 
 
29
 
 
30
/* include system configuration before all else. */
 
31
#include "autoconf.h"
 
32
 
 
33
#include "gdbmdefs.h"
 
34
#include "gdbmerrno.h"
 
35
 
 
36
/* Remove the KEYed item and the KEY from the database DBF.  The file on disk
 
37
   is updated to reflect the structure of the new database before returning
 
38
   from this procedure.  */
 
39
 
 
40
int
 
41
gdbm_delete (dbf, key)
 
42
     gdbm_file_info *dbf;
 
43
     datum key;
 
44
{
 
45
  int elem_loc;         /* The location in the current hash bucket. */
 
46
  int last_loc;         /* Last location emptied by the delete.  */
 
47
  int home;             /* Home position of an item. */
 
48
  bucket_element elem;  /* The element to be deleted. */
 
49
  char *find_data;      /* Return pointer from findkey. */
 
50
  word_t hash_val;      /* Returned by findkey. */
 
51
  off_t free_adr;       /* Temporary stroage for address and size. */
 
52
  int   free_size;
 
53
 
 
54
  /* First check to make sure this guy is a writer. */
 
55
  if (dbf->read_write != GDBM_WRITER)
 
56
    {
 
57
      gdbm_errno = GDBM_READER_CANT_DELETE;
 
58
      return -1;
 
59
    }
 
60
 
 
61
  /* Initialize the gdbm_errno variable. */
 
62
  gdbm_errno = GDBM_NO_ERROR;
 
63
 
 
64
  /* Find the item. */
 
65
  elem_loc = _gdbm_findkey (dbf, key, &find_data, &hash_val);
 
66
  if (elem_loc == -1)
 
67
    {
 
68
      gdbm_errno = GDBM_ITEM_NOT_FOUND;
 
69
      return -1;
 
70
    }
 
71
 
 
72
  /* Save the element.  */
 
73
  elem = dbf->bucket->h_table[elem_loc];
 
74
 
 
75
  /* Delete the element.  */
 
76
  dbf->bucket->h_table[elem_loc].hash_value = -1;
 
77
  dbf->bucket->count -= 1;
 
78
 
 
79
  /* Move other elements to guarantee that they can be found. */
 
80
  last_loc = elem_loc;
 
81
  elem_loc = (elem_loc + 1) % dbf->header->bucket_elems;
 
82
  while (elem_loc != last_loc
 
83
         && dbf->bucket->h_table[elem_loc].hash_value != -1)
 
84
    {
 
85
      home = dbf->bucket->h_table[elem_loc].hash_value
 
86
             % dbf->header->bucket_elems;
 
87
      if ( (last_loc < elem_loc && (home <= last_loc || home > elem_loc))
 
88
          || (last_loc > elem_loc && home <= last_loc && home > elem_loc))
 
89
        
 
90
        {
 
91
          dbf->bucket->h_table[last_loc] = dbf->bucket->h_table[elem_loc];
 
92
          dbf->bucket->h_table[elem_loc].hash_value = -1;
 
93
          last_loc = elem_loc;
 
94
        }
 
95
      elem_loc = (elem_loc + 1) % dbf->header->bucket_elems;
 
96
    }
 
97
 
 
98
  /* Free the file space. */
 
99
  free_adr = elem.data_pointer;
 
100
  free_size = elem.key_size + elem.data_size;
 
101
  _gdbm_free (dbf, free_adr, free_size);
 
102
 
 
103
  /* Set the flags. */
 
104
  dbf->bucket_changed = TRUE;
 
105
 
 
106
  /* Clear out the data cache for the current bucket. */
 
107
  if (dbf->cache_entry->ca_data.dptr != NULL)
 
108
    {
 
109
      free (dbf->cache_entry->ca_data.dptr);
 
110
      dbf->cache_entry->ca_data.dptr = NULL;
 
111
    }
 
112
  dbf->cache_entry->ca_data.hash_val = -1;
 
113
  dbf->cache_entry->ca_data.key_size = 0;
 
114
  dbf->cache_entry->ca_data.elem_loc = -1;
 
115
 
 
116
  /* Do the writes. */
 
117
  _gdbm_end_update (dbf);
 
118
  return 0;  
 
119
}