2
* PROGRAM: JRD Access Method
4
* DESCRIPTION: Blob handling definitions
6
* The contents of this file are subject to the Interbase Public
7
* License Version 1.0 (the "License"); you may not use this file
8
* except in compliance with the License. You may obtain a copy
9
* of the License at http://www.Inprise.com/IPL.html
11
* Software distributed under the License is distributed on an
12
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
13
* or implied. See the License for the specific language governing
14
* rights and limitations under the License.
16
* The Original Code was created by Inprise Corporation
17
* and its predecessors. Portions created by Inprise Corporation are
18
* Copyright (C) Inprise Corporation.
20
* All Rights Reserved.
21
* Contributor(s): ______________________________________.
23
* 2002.10.28 Sean Leyne - Code cleanup, removed obsolete "DecOSF" port
30
#include "../jrd/RecordNumber.h"
34
/* Blob id. A blob has two states -- temporary and permanent. In each
35
case, the blob id is 8 bytes (2 longwords) long. In the case of a
36
temporary blob, the first word is NULL and the second word points to
37
an internal blob block. In the case of a permanent blob, the first
38
word contains the relation id of the blob and the second the record
39
number of the first segment-clump. The two types of blobs can be
40
reliably distinguished by a zero or non-zero relation id. */
49
// This structure must occupy 8 bytes
52
// Internal decomposition of the structure
53
RecordNumber::Packed bid_internal;
55
// This is how bid structure represented in public API.
56
// Must be present to enforce alignment rules when structure is declared on stack
63
ULONG& bid_temp_id() {
64
// Make sure that compiler packed structure like we wanted
65
fb_assert(sizeof(*this) == 8);
67
return bid_internal.bid_temp_id();
70
ULONG bid_temp_id() const {
71
// Make sure that compiler packed structure like we wanted
72
fb_assert(sizeof(*this) == 8);
74
return bid_internal.bid_temp_id();
77
bool isEmpty() const {
78
// Make sure that compiler packed structure like we wanted
79
fb_assert(sizeof(*this) == 8);
81
return bid_quad.bid_quad_high == 0 && bid_quad.bid_quad_low == 0;
85
// Make sure that compiler packed structure like we wanted
86
fb_assert(sizeof(*this) == 8);
88
bid_quad.bid_quad_high = 0;
89
bid_quad.bid_quad_low = 0;
92
void set_temporary(ULONG temp_id) {
93
// Make sure that compiler packed structure like we wanted
94
fb_assert(sizeof(*this) == 8);
97
bid_temp_id() = temp_id;
100
void set_permanent(USHORT relation_id, RecordNumber num) {
101
// Make sure that compiler packed structure like we wanted
102
fb_assert(sizeof(*this) == 8);
105
bid_internal.bid_relation_id = relation_id;
106
num.bid_encode(&bid_internal);
109
RecordNumber get_permanent_number() const {
110
// Make sure that compiler packed structure like we wanted
111
fb_assert(sizeof(*this) == 8);
114
temp.bid_decode(&bid_internal);
118
bool operator == (const bid& other) const {
119
// Make sure that compiler packed structure like we wanted
120
fb_assert(sizeof(*this) == 8);
122
return bid_quad.bid_quad_high == other.bid_quad.bid_quad_high &&
123
bid_quad.bid_quad_low == other.bid_quad.bid_quad_low;
127
/* Your basic blob block. */
129
class blb : public pool_alloc_rpt<UCHAR, type_blb>
132
Attachment* blb_attachment; /* database attachment */
133
jrd_rel* blb_relation; /* Relation, if known */
134
jrd_tra* blb_transaction; /* Parent transaction block */
135
blb* blb_next; /* Next blob in transaction */
136
UCHAR* blb_segment; /* Next segment to be addressed */
137
BlobControl* blb_filter; /* Blob filter control block, if any */
138
bid blb_blob_id; /* Id of materialized blob */
139
vcl* blb_pages; /* Vector of pages */
140
USHORT blb_pointers; /* Max pointer on a page */
141
USHORT blb_level; /* Storage type */
142
USHORT blb_max_segment; /* Longest segment */
143
USHORT blb_flags; /* Interesting stuff (see below) */
144
USHORT blb_clump_size; /* Size of data clump */
145
USHORT blb_space_remaining; /* Data space left */
146
USHORT blb_max_pages; /* Max pages in vector */
147
USHORT blb_fragment_size; /* Residual fragment size */
148
USHORT blb_source_interp; /* source interp (for writing) */
149
USHORT blb_target_interp; /* destination interp (for reading) */
150
SSHORT blb_sub_type; /* Blob's declared sub-type */
151
UCHAR blb_charset; // Blob's charset
152
USHORT blb_pg_space_id; // page space
153
ULONG blb_sequence; /* Blob page sequence */
154
ULONG blb_max_sequence; /* Number of data pages */
155
ULONG blb_count; /* Number of segments */
156
ULONG blb_length; /* Total length of data sans segments */
157
ULONG blb_lead_page; /* First page number */
158
ULONG blb_seek; /* Seek location */
159
ULONG blb_temp_id; // ID of newly created blob in transaction
160
/* blb_data must be longword aligned */
161
UCHAR blb_data[1]; /* A page's worth of blob */
164
const int BLB_temporary = 1; /* Newly created blob */
165
const int BLB_eof = 2; /* This blob is exhausted */
166
const int BLB_stream = 4; /* Stream style blob */
167
const int BLB_closed = 8; /* Temporary blob has been closed */
168
const int BLB_damaged = 16; /* Blob is busted */
169
const int BLB_seek = 32; /* Seek is pending */
170
const int BLB_user_def = 64; /* Blob is user created */
171
const int BLB_large_scan = 128; /* Blob is larger than page buffer cache */
175
0 small blob -- blob "record" is actual data
176
1 medium blob -- blob "record" is pointer to pages
177
2 large blob -- blob "record" is pointer to pages of pointers
180
// mapping blob ids for REPLAY
181
// Useful only with REPLAY_OSRI_API_CALLS_SUBSYSTEM defined.
182
class blb_map : public pool_alloc<type_map>