/* 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 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); }