mysql5/mysql-5.7.27/sql/ndb_anyvalue.cc

185 lines
5.2 KiB
C++

/*
Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "ndb_anyvalue.h"
/*
AnyValue carries ServerId or Reserved codes
Bits from opt_server_id_bits to 30 may carry other data
so we ignore them when reading/setting AnyValue.
The idea with supporting 'other data' is to allow NdbApi
users to tag their NdbApi operations in some way that can
be picked up at NdbApi event receivers, *without* interacting
badly with / disabling normal binlogging and replication.
To achieve this, we have a variable sized mask of bits in the
*middle* of the AnyValue word which can be used to mask out
the user data for the purpose of the MySQL Server.
A better future approach would be to support > 1 tag word
per operation.
332 21 10 0
10987654321098765432109876543210
roooooooooooooooooooooooosssssss
r = Reserved bit indicates whether
bits 0-7+ have ServerId (0) or
some special reserved code (1).
o = Optional bits, depending on value
of server-id-bits will be
serverid bits or user-specific
data
s = Serverid bits or reserved codes
At least 7 bits will be available
for serverid or reserved codes
Implications :
Reserved codes can use values between
0x80000000 and 0x8000007f inclusive
(256 values).
0x8000007f was always the 'nologging'
code, so the others have started
'counting' down from there
Examples :
opt_server_id_bits= 31
- ServerIds can be up to 2^31-1
- No user-specific data supported
- Reserved codes look like :
0x8000007f etc...
opt_server_id_bits= 7
- ServerIds can be up to 2^7-1
- User specific data can be up to 2^24-1
- ServerIds have 0 top bit, 24 user bits, then
the serverid
- Reserved codes have 1 top bit, 24 user bits (prob
not used much), then the bottom lsbs of the
reserved code.
*/
#include <my_global.h>
extern ulong opt_server_id_mask;
#define NDB_ANYVALUE_RESERVED_BIT 0x80000000
#define NDB_ANYVALUE_RESERVED_MASK 0x8000007f
#define NDB_ANYVALUE_NOLOGGING_CODE 0x8000007f
#define NDB_ANYVALUE_REFRESH_OP_CODE 0x8000007e
#define NDB_ANYVALUE_REFLECT_OP_CODE 0x8000007d
#define NDB_ANYVALUE_READ_OP_CODE 0x8000007c
/* Next reserved code : 0x8000007c */
#ifndef DBUG_OFF
void dbug_ndbcluster_anyvalue_set_userbits(Uint32& anyValue)
{
/*
Set userData part of AnyValue (if there is one) to
all 1s to test that it is ignored
*/
const Uint32 userDataMask = ~(opt_server_id_mask |
NDB_ANYVALUE_RESERVED_BIT);
anyValue |= userDataMask;
}
#endif
bool ndbcluster_anyvalue_is_reserved(Uint32 anyValue)
{
return ((anyValue & NDB_ANYVALUE_RESERVED_BIT) != 0);
}
bool ndbcluster_anyvalue_is_nologging(Uint32 anyValue)
{
return ((anyValue & NDB_ANYVALUE_RESERVED_MASK) ==
NDB_ANYVALUE_NOLOGGING_CODE);
}
void ndbcluster_anyvalue_set_nologging(Uint32& anyValue)
{
anyValue |= NDB_ANYVALUE_NOLOGGING_CODE;
}
bool ndbcluster_anyvalue_is_refresh_op(Uint32 anyValue)
{
return ((anyValue & NDB_ANYVALUE_RESERVED_MASK) ==
NDB_ANYVALUE_REFRESH_OP_CODE);
}
void ndbcluster_anyvalue_set_refresh_op(Uint32& anyValue)
{
anyValue &= ~NDB_ANYVALUE_RESERVED_MASK;
anyValue |= NDB_ANYVALUE_REFRESH_OP_CODE;
}
bool ndbcluster_anyvalue_is_read_op(Uint32 anyValue)
{
return ((anyValue & NDB_ANYVALUE_RESERVED_MASK) ==
NDB_ANYVALUE_READ_OP_CODE);
}
void ndbcluster_anyvalue_set_read_op(Uint32& anyValue)
{
anyValue &= ~NDB_ANYVALUE_RESERVED_MASK;
anyValue |= NDB_ANYVALUE_READ_OP_CODE;
}
bool ndbcluster_anyvalue_is_reflect_op(Uint32 anyValue)
{
return ((anyValue & NDB_ANYVALUE_RESERVED_MASK) ==
NDB_ANYVALUE_REFLECT_OP_CODE);
}
void ndbcluster_anyvalue_set_reflect_op(Uint32& anyValue)
{
anyValue &= ~NDB_ANYVALUE_RESERVED_MASK;
anyValue |= NDB_ANYVALUE_REFLECT_OP_CODE;
}
void ndbcluster_anyvalue_set_normal(Uint32& anyValue)
{
/* Clear reserved bit and serverid bits */
anyValue &= ~(NDB_ANYVALUE_RESERVED_BIT);
anyValue &= ~(opt_server_id_mask);
}
bool ndbcluster_anyvalue_is_serverid_in_range(Uint32 serverId)
{
return ((serverId & ~opt_server_id_mask) == 0);
}
Uint32 ndbcluster_anyvalue_get_serverid(Uint32 anyValue)
{
assert(! (anyValue & NDB_ANYVALUE_RESERVED_BIT) );
return (anyValue & opt_server_id_mask);
}
void ndbcluster_anyvalue_set_serverid(Uint32& anyValue, Uint32 serverId)
{
assert(! (anyValue & NDB_ANYVALUE_RESERVED_BIT) );
anyValue &= ~(opt_server_id_mask);
anyValue |= (serverId & opt_server_id_mask);
}