~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to src/backend/access/hash/hashscan.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * hashscan.c
 
4
 *        manage scans on hash tables
 
5
 *
 
6
 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
 
7
 * Portions Copyright (c) 1994, Regents of the University of California
 
8
 *
 
9
 *
 
10
 * IDENTIFICATION
 
11
 *        $PostgreSQL: pgsql/src/backend/access/hash/hashscan.c,v 1.38 2004-12-31 21:59:13 pgsql Exp $
 
12
 *
 
13
 *-------------------------------------------------------------------------
 
14
 */
 
15
 
 
16
#include "postgres.h"
 
17
 
 
18
#include "access/hash.h"
 
19
#include "utils/resowner.h"
 
20
 
 
21
 
 
22
typedef struct HashScanListData
 
23
{
 
24
        IndexScanDesc hashsl_scan;
 
25
        ResourceOwner hashsl_owner;
 
26
        struct HashScanListData *hashsl_next;
 
27
} HashScanListData;
 
28
 
 
29
typedef HashScanListData *HashScanList;
 
30
 
 
31
static HashScanList HashScans = NULL;
 
32
 
 
33
 
 
34
/*
 
35
 * ReleaseResources_hash() --- clean up hash subsystem resources.
 
36
 *
 
37
 * This is here because it needs to touch this module's static var HashScans.
 
38
 */
 
39
void
 
40
ReleaseResources_hash(void)
 
41
{
 
42
        HashScanList l;
 
43
        HashScanList prev;
 
44
        HashScanList next;
 
45
 
 
46
        /*
 
47
         * Note: this should be a no-op during normal query shutdown. However,
 
48
         * in an abort situation ExecutorEnd is not called and so there may be
 
49
         * open index scans to clean up.
 
50
         */
 
51
        prev = NULL;
 
52
 
 
53
        for (l = HashScans; l != NULL; l = next)
 
54
        {
 
55
                next = l->hashsl_next;
 
56
                if (l->hashsl_owner == CurrentResourceOwner)
 
57
                {
 
58
                        if (prev == NULL)
 
59
                                HashScans = next;
 
60
                        else
 
61
                                prev->hashsl_next = next;
 
62
 
 
63
                        pfree(l);
 
64
                        /* prev does not change */
 
65
                }
 
66
                else
 
67
                        prev = l;
 
68
        }
 
69
}
 
70
 
 
71
/*
 
72
 *      _Hash_regscan() -- register a new scan.
 
73
 */
 
74
void
 
75
_hash_regscan(IndexScanDesc scan)
 
76
{
 
77
        HashScanList new_el;
 
78
 
 
79
        new_el = (HashScanList) palloc(sizeof(HashScanListData));
 
80
        new_el->hashsl_scan = scan;
 
81
        new_el->hashsl_owner = CurrentResourceOwner;
 
82
        new_el->hashsl_next = HashScans;
 
83
        HashScans = new_el;
 
84
}
 
85
 
 
86
/*
 
87
 *      _hash_dropscan() -- drop a scan from the scan list
 
88
 */
 
89
void
 
90
_hash_dropscan(IndexScanDesc scan)
 
91
{
 
92
        HashScanList chk,
 
93
                                last;
 
94
 
 
95
        last = NULL;
 
96
        for (chk = HashScans;
 
97
                 chk != NULL && chk->hashsl_scan != scan;
 
98
                 chk = chk->hashsl_next)
 
99
                last = chk;
 
100
 
 
101
        if (chk == NULL)
 
102
                elog(ERROR, "hash scan list trashed; can't find 0x%p", (void *) scan);
 
103
 
 
104
        if (last == NULL)
 
105
                HashScans = chk->hashsl_next;
 
106
        else
 
107
                last->hashsl_next = chk->hashsl_next;
 
108
 
 
109
        pfree(chk);
 
110
}
 
111
 
 
112
/*
 
113
 * Is there an active scan in this bucket?
 
114
 */
 
115
bool
 
116
_hash_has_active_scan(Relation rel, Bucket bucket)
 
117
{
 
118
        Oid                     relid = RelationGetRelid(rel);
 
119
        HashScanList l;
 
120
 
 
121
        for (l = HashScans; l != NULL; l = l->hashsl_next)
 
122
        {
 
123
                if (relid == l->hashsl_scan->indexRelation->rd_id)
 
124
                {
 
125
                        HashScanOpaque so = (HashScanOpaque) l->hashsl_scan->opaque;
 
126
 
 
127
                        if (so->hashso_bucket_valid &&
 
128
                                so->hashso_bucket == bucket)
 
129
                                return true;
 
130
                }
 
131
        }
 
132
 
 
133
        return false;
 
134
}