summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/include/dhandle.h
blob: 865ea0d9568ec8c69d4b2c5e8c358dcf8735c476 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*-
 * Copyright (c) 2014-present MongoDB, Inc.
 * Copyright (c) 2008-2014 WiredTiger, Inc.
 *	All rights reserved.
 *
 * See the file LICENSE for redistribution information.
 */

/*
 * Helpers for calling a function with a data handle in session->dhandle then restoring afterwards.
 */
#define WT_WITH_DHANDLE(s, d, e)                        \
    do {                                                \
        WT_DATA_HANDLE *__saved_dhandle = (s)->dhandle; \
        (s)->dhandle = (d);                             \
        e;                                              \
        (s)->dhandle = __saved_dhandle;                 \
    } while (0)

#define WT_WITH_BTREE(s, b, e) WT_WITH_DHANDLE(s, (b)->dhandle, e)

/* Call a function without the caller's data handle, restore afterwards. */
#define WT_WITHOUT_DHANDLE(s, e) WT_WITH_DHANDLE(s, NULL, e)

/*
 * Call a function with the caller's data handle, restore it afterwards in case it is overwritten.
 */
#define WT_SAVE_DHANDLE(s, e) WT_WITH_DHANDLE(s, (s)->dhandle, e)

/* Check if a handle is inactive. */
#define WT_DHANDLE_INACTIVE(dhandle) \
    (F_ISSET(dhandle, WT_DHANDLE_DEAD) || !F_ISSET(dhandle, WT_DHANDLE_EXCLUSIVE | WT_DHANDLE_OPEN))

/* Check if a handle could be reopened. */
#define WT_DHANDLE_CAN_REOPEN(dhandle) \
    (!F_ISSET(dhandle, WT_DHANDLE_DEAD | WT_DHANDLE_DROPPED) && F_ISSET(dhandle, WT_DHANDLE_OPEN))

/* The metadata cursor's data handle. */
#define WT_SESSION_META_DHANDLE(s) (((WT_CURSOR_BTREE *)((s)->meta_cursor))->dhandle)

#define WT_DHANDLE_ACQUIRE(dhandle) (void)__wt_atomic_add32(&(dhandle)->session_ref, 1)

#define WT_DHANDLE_RELEASE(dhandle) (void)__wt_atomic_sub32(&(dhandle)->session_ref, 1)

#define WT_DHANDLE_NEXT(session, dhandle, head, field)                                     \
    do {                                                                                   \
        WT_ASSERT(session, FLD_ISSET(session->lock_flags, WT_SESSION_LOCKED_HANDLE_LIST)); \
        if ((dhandle) == NULL)                                                             \
            (dhandle) = TAILQ_FIRST(head);                                                 \
        else {                                                                             \
            WT_DHANDLE_RELEASE(dhandle);                                                   \
            (dhandle) = TAILQ_NEXT(dhandle, field);                                        \
        }                                                                                  \
        if ((dhandle) != NULL)                                                             \
            WT_DHANDLE_ACQUIRE(dhandle);                                                   \
    } while (0)

#define WT_DHANDLE_IS_CHECKPOINT(dhandle) ((dhandle)->checkpoint != NULL)

/*
 * WT_WITH_DHANDLE_WRITE_LOCK_NOWAIT --
 *	Try to acquire write lock for the session's current dhandle, perform an operation, drop the
 *  lock.
 */
#define WT_WITH_DHANDLE_WRITE_LOCK_NOWAIT(session, ret, op)               \
    do {                                                                  \
        if (((ret) = __wt_session_dhandle_try_writelock(session)) == 0) { \
            op;                                                           \
            __wt_session_dhandle_writeunlock(session);                    \
        }                                                                 \
    } while (0)

/*
 * WT_DATA_HANDLE --
 *	A handle for a generic named data source.
 */
struct __wt_data_handle {
    WT_RWLOCK rwlock; /* Lock for shared/exclusive ops */
    TAILQ_ENTRY(__wt_data_handle) q;
    TAILQ_ENTRY(__wt_data_handle) hashq;

    const char *name;         /* Object name as a URI */
    uint64_t name_hash;       /* Hash of name */
    const char *checkpoint;   /* Checkpoint name (or NULL) */
    int64_t checkpoint_order; /* Checkpoint order number, when applicable */
    const char **cfg;         /* Configuration information */
    const char *meta_base;    /* Base metadata configuration */
    size_t meta_base_length;  /* Base metadata length */
#ifdef HAVE_DIAGNOSTIC
    const char *orig_meta_base; /* Copy of the base metadata configuration */
#endif
    /*
     * Sessions holding a connection's data handle will have a non-zero reference count; sessions
     * using a connection's data handle will have a non-zero in-use count. Instances of cached
     * cursors referencing the data handle appear in session_cache_ref.
     */
    uint32_t session_ref;          /* Sessions referencing this handle */
    int32_t session_inuse;         /* Sessions using this handle */
    uint32_t excl_ref;             /* Refs of handle by excl_session */
    uint64_t timeofdeath;          /* Use count went to 0 */
    WT_SESSION_IMPL *excl_session; /* Session with exclusive use, if any */

    WT_DATA_SOURCE *dsrc; /* Data source for this handle */
    void *handle;         /* Generic handle */

    enum {
        WT_DHANDLE_TYPE_BTREE,
        WT_DHANDLE_TYPE_TABLE,
        WT_DHANDLE_TYPE_TIERED,
        WT_DHANDLE_TYPE_TIERED_TREE
    } type;

#define WT_DHANDLE_BTREE(dhandle) \
    ((dhandle)->type == WT_DHANDLE_TYPE_BTREE || (dhandle)->type == WT_DHANDLE_TYPE_TIERED)

    bool compact_skip; /* If the handle failed to compact */

    /*
     * Data handles can be closed without holding the schema lock; threads walk the list of open
     * handles, operating on them (checkpoint is the best example). To avoid sources disappearing
     * underneath checkpoint, lock the data handle when closing it.
     */
    WT_SPINLOCK close_lock; /* Lock to close the handle */

    /* Data-source statistics */
    WT_DSRC_STATS *stats[WT_COUNTER_SLOTS];
    WT_DSRC_STATS *stat_array;

/*
 * Flags values over 0xfff are reserved for WT_BTREE_*. This lets us combine the dhandle and btree
 * flags when we need, for example, to pass both sets in a function call.
 */
/* AUTOMATIC FLAG VALUE GENERATION START 0 */
#define WT_DHANDLE_DEAD 0x001u         /* Dead, awaiting discard */
#define WT_DHANDLE_DISCARD 0x002u      /* Close on release */
#define WT_DHANDLE_DISCARD_KILL 0x004u /* Mark dead on release */
#define WT_DHANDLE_DROPPED 0x008u      /* Handle is dropped */
#define WT_DHANDLE_EVICTED 0x010u      /* Btree is evicted (advisory) */
#define WT_DHANDLE_EXCLUSIVE 0x020u    /* Exclusive access */
#define WT_DHANDLE_HS 0x040u           /* History store table */
#define WT_DHANDLE_IS_METADATA 0x080u  /* Metadata handle */
#define WT_DHANDLE_LOCK_ONLY 0x100u    /* Handle only used as a lock */
#define WT_DHANDLE_OPEN 0x200u         /* Handle is open */
                                       /* AUTOMATIC FLAG VALUE GENERATION STOP 12 */
    uint32_t flags;

/* AUTOMATIC FLAG VALUE GENERATION START 0 */
#define WT_DHANDLE_TS_ASSERT_READ_ALWAYS 0x01u /* Assert read always checking. */
#define WT_DHANDLE_TS_ASSERT_READ_NEVER 0x02u  /* Assert read never checking. */
#define WT_DHANDLE_TS_MIXED_MODE 0x04u         /* Handle using mixed mode timestamps checking. */
#define WT_DHANDLE_TS_NEVER 0x08u              /* Handle never using timestamps checking. */
#define WT_DHANDLE_TS_ORDERED 0x10u            /* Handle using ordered timestamps checking. */
                                               /* AUTOMATIC FLAG VALUE GENERATION STOP 16 */
    uint16_t ts_flags;

/* AUTOMATIC FLAG VALUE GENERATION START 0 */
#define WT_DHANDLE_LOCK_WRITE 0x1u /* Write lock is acquired. */
                                   /* AUTOMATIC FLAG VALUE GENERATION STOP 16 */
    uint16_t lock_flags;
};