1 /*-------------------------------------------------------------------------
4 * postgres OID & XID variables support routines
6 * Copyright (c) 2000, PostgreSQL Global Development Group
9 * $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.37 2001/03/18 20:18:59 tgl Exp $
11 *-------------------------------------------------------------------------
16 #include "access/transam.h"
17 #include "access/xlog.h"
18 #include "storage/proc.h"
21 /* Number of XIDs and OIDs to prefetch (preallocate) per XLOG write */
22 #define VAR_XID_PREFETCH 1024
23 #define VAR_OID_PREFETCH 8192
25 /* Spinlocks for serializing generation of XIDs and OIDs, respectively */
26 SPINLOCK XidGenLockId;
27 SPINLOCK OidGenLockId;
29 /* pointer to "variable cache" in shared memory (set up by shmem.c) */
30 VariableCache ShmemVariableCache = NULL;
33 GetNewTransactionId(TransactionId *xid)
36 * During bootstrap initialization, we return the special
37 * bootstrap transaction id.
41 *xid = AmiTransactionId;
45 SpinAcquire(XidGenLockId);
47 *xid = ShmemVariableCache->nextXid;
49 (ShmemVariableCache->nextXid)++;
51 SpinRelease(XidGenLockId);
53 if (MyProc != (PROC *) NULL)
58 * Read nextXid but don't allocate it.
61 ReadNewTransactionId(TransactionId *xid)
64 * During bootstrap initialization, we return the special
65 * bootstrap transaction id.
69 *xid = AmiTransactionId;
73 SpinAcquire(XidGenLockId);
74 *xid = ShmemVariableCache->nextXid;
75 SpinRelease(XidGenLockId);
78 /* ----------------------------------------------------------------
79 * object id generation support
80 * ----------------------------------------------------------------
83 static Oid lastSeenOid = InvalidOid;
86 GetNewObjectId(Oid *oid_return)
88 SpinAcquire(OidGenLockId);
90 /* If we run out of logged for use oids then we must log more */
91 if (ShmemVariableCache->oidCount == 0)
93 XLogPutNextOid(ShmemVariableCache->nextOid + VAR_OID_PREFETCH);
94 ShmemVariableCache->oidCount = VAR_OID_PREFETCH;
97 if (PointerIsValid(oid_return))
98 lastSeenOid = (*oid_return) = ShmemVariableCache->nextOid;
100 (ShmemVariableCache->nextOid)++;
101 (ShmemVariableCache->oidCount)--;
103 SpinRelease(OidGenLockId);
107 CheckMaxObjectId(Oid assigned_oid)
109 if (lastSeenOid != InvalidOid && assigned_oid < lastSeenOid)
112 SpinAcquire(OidGenLockId);
114 if (assigned_oid < ShmemVariableCache->nextOid)
116 lastSeenOid = ShmemVariableCache->nextOid - 1;
117 SpinRelease(OidGenLockId);
121 /* If we are in the logged oid range, just bump nextOid up */
122 if (assigned_oid <= ShmemVariableCache->nextOid +
123 ShmemVariableCache->oidCount - 1)
125 ShmemVariableCache->oidCount -=
126 assigned_oid - ShmemVariableCache->nextOid + 1;
127 ShmemVariableCache->nextOid = assigned_oid + 1;
128 SpinRelease(OidGenLockId);
133 * We have exceeded the logged oid range.
134 * We should lock the database and kill all other backends
135 * but we are loading oid's that we can not guarantee are unique
136 * anyway, so we must rely on the user.
139 XLogPutNextOid(assigned_oid + VAR_OID_PREFETCH);
140 ShmemVariableCache->oidCount = VAR_OID_PREFETCH - 1;
141 ShmemVariableCache->nextOid = assigned_oid + 1;
143 SpinRelease(OidGenLockId);