예제 #1
0
        /// <summary>
        /// Send a message on the message channel. The message is sent
        /// asynchronously. The method does not wait for a response before
        /// returning. It usually completes quickly because it only waits for
        /// local TCP implementation to accept the bytes into its network data
        /// buffer. However, this message could block briefly for longer
        /// messages, and/or if the network data buffer is nearly full.
        /// It could even block indefinitely if the remote site is slow
        /// to read.
        /// </summary>
        /// <remarks>
        /// <para>
        /// To block while waiting for a response from a remote site, use
        /// <see cref="SendRequest"/> instead of this method.
        /// </para>
        /// <para>
        /// The sent message is received and handled at remote sites using a
        /// message dispatch callback, which is configured using
        /// <see cref="DatabaseEnvironment.RepMessageDispatch"/>. This
        /// method may be used within the message dispatch callback on the
        /// remote site to send a reply or acknowledgement for messages that it
        /// receives and is handling.
        /// </para>
        /// <para>
        /// This method may be used on channels opened to any destination. See
        /// <see cref="DatabaseEnvironment.RepMgrChannel"/> for a list of
        /// potential destinations.
        /// </para>
        /// </remarks>
        /// <param name="msg">
        /// An array of DatabaseEntry objects. Any flags for the DatabaseEntry
        /// objects are ignored.
        /// </param>
        public void SendMessage(DatabaseEntry[] msg)
        {
            int size = msg.Length;

            IntPtr[] dbts = new IntPtr[size];
            for (int i = 0; i < size; i++)
            {
                dbts[i] = DBT.getCPtr(DatabaseEntry.getDBT(msg[i])).Handle;
            }
            channel.send_msg(dbts, (uint)size, 0);
        }
예제 #2
0
        /// <summary>
        /// Send a message on the message channel. The message is sent
        /// synchronously. The method blocks waiting for a response before
        /// returning. If a response is not received within the timeout value
        /// configured for this request, this method returns with an error
        /// condition.
        /// </summary>
        /// <remarks>
        /// <para>
        /// To avoid block while waiting for a response from a remote site,
        /// use <see cref="SendMessage"/>
        /// </para>
        /// <para>
        /// The message sent by this method is received and handled at remote
        /// sites using a message dispatch callback, which is configured using
        /// <see cref="DatabaseEnvironment.RepMessageDispatch"/>
        /// </para>
        /// </remarks>
        /// <param name="request">
        /// DatabaseEntry objects array. Any flags for the DatabaseEntry objects
        /// are ignored.
        /// </param>
        /// <param name="timeout">
        /// The amount of time that may elapse while this method waits for a
        /// response from the remote site. The timeout value must be specified
        /// as an unsigned 32-bit number of microseconds, limiting the maximum
        /// timeout to roughly 71 minutes. A timeout value of 0 indicates that
        /// the channel's default timeout value should be used. This default is
        /// configured using <see cref="Timeout"/>.
        /// </param>
        /// <returns>The response from remote site</returns>
        public DatabaseEntry SendRequest(
            DatabaseEntry[] request, uint timeout)
        {
            int size = request.Length;

            IntPtr[] dbts = new IntPtr[size];
            for (int i = 0; i < size; i++)
            {
                dbts[i] = DBT.getCPtr(DatabaseEntry.getDBT(request[i])).Handle;
            }
            DatabaseEntry response = new DatabaseEntry();

            channel.send_request(dbts, (uint)size, response, timeout, 0);
            return(response);
        }
예제 #3
0
        /// <summary>
        /// Send a message on the message channel. The message is sent
        /// synchronously. The method blocks waiting for a response before
        /// returning. If a response is not received within the timeout value
        /// configured for this request, this method returns with an error
        /// condition.
        /// </summary>
        /// <remarks>
        /// <para>
        /// To avoid block while waiting for a response from a remote site,
        /// use <see cref="SendMessage"/>
        /// </para>
        /// <para>
        /// The message sent by this method is received and handled at remote
        /// sites using a message dispatch callback, which is configured using
        /// <see cref="DatabaseEnvironment.RepMessageDispatch"/>
        /// </para>
        /// </remarks>
        /// <param name="request">
        /// DatabaseEntry objects array. Any flags for the DatabaseEntry objects
        /// are ignored.
        /// </param>
        /// <param name="bufferSize">Size of bulk buffer</param>
        /// <param name="timeout">
        /// The amount of time that may elapse while this method waits for a
        /// response from the remote site. The timeout value must be specified
        /// as an unsigned 32-bit number of microseconds, limiting the maximum
        /// timeout to roughly 71 minutes. A timeout value of 0 indicates that
        /// the channel's default timeout value should be used. This default is
        /// configured using <see cref="Timeout"/>.
        /// </param>
        /// <returns>Multiple responses from the remote site.</returns>
        public MultipleDatabaseEntry SendRequest(
            DatabaseEntry[] request, int bufferSize, uint timeout)
        {
            int size = request.Length;

            IntPtr[] dbts = new IntPtr[size];
            for (int i = 0; i < size; i++)
            {
                dbts[i] = DBT.getCPtr(DatabaseEntry.getDBT(request[i])).Handle;
            }
            DatabaseEntry data = new DatabaseEntry();

            data.UserData = new byte[bufferSize];
            channel.send_request(dbts, (uint)size, data, timeout,
                                 DbConstants.DB_MULTIPLE);
            MultipleDatabaseEntry response = new MultipleDatabaseEntry(data);

            return(response);
        }
예제 #4
0
        private void Config(BTreeDatabaseConfig cfg)
        {
            base.Config(cfg);

            /*
             * Database.Config calls set_flags, but that does not get the BTree
             * specific flags.  No harm in calling it again.
             */
            db.set_flags(cfg.flags);

            if (cfg.BlobDir != null && cfg.Env == null)
            {
                db.set_ext_file_dir(cfg.BlobDir);
            }

            if (cfg.ExternalFileDir != null && cfg.Env == null)
            {
                db.set_ext_file_dir(cfg.ExternalFileDir);
            }

            if (cfg.blobThresholdIsSet)
            {
                db.set_ext_file_threshold(cfg.BlobThreshold, 0);
            }

            if (cfg.BTreeCompare != null)
            {
                Compare = cfg.BTreeCompare;
            }

            if (cfg.BTreePrefixCompare != null)
            {
                PrefixCompare = cfg.BTreePrefixCompare;
            }

            // The duplicate comparison function cannot change.
            if (cfg.DuplicateCompare != null)
            {
                DupCompare = cfg.DuplicateCompare;
            }

            if (cfg.minkeysIsSet)
            {
                db.set_bt_minkey(cfg.MinKeysPerPage);
            }

            if (cfg.compressionIsSet)
            {
                Compress   = cfg.Compress;
                Decompress = cfg.Decompress;
                if (Compress == null)
                {
                    doCompressRef = null;
                }
                else
                {
                    doCompressRef = new BDB_CompressDelegate(doCompress);
                }
                if (Decompress == null)
                {
                    doDecompressRef = null;
                }
                else
                {
                    doDecompressRef = new BDB_DecompressDelegate(doDecompress);
                }
                db.set_bt_compress(doCompressRef, doDecompressRef);
            }

            if (cfg.partitionIsSet)
            {
                nparts    = cfg.NParts;
                Partition = cfg.Partition;
                if (Partition == null)
                {
                    doPartitionRef = null;
                }
                else
                {
                    doPartitionRef = new BDB_PartitionDelegate(doPartition);
                }
                partitionKeys = cfg.PartitionKeys;
                IntPtr[] ptrs = null;
                if (partitionKeys != null)
                {
                    int size = (int)nparts - 1;
                    ptrs = new IntPtr[size];
                    for (int i = 0; i < size; i++)
                    {
                        ptrs[i] = DBT.getCPtr(
                            DatabaseEntry.getDBT(partitionKeys[i])).Handle;
                    }
                }
                db.set_partition(nparts, ptrs, doPartitionRef);
            }
        }
예제 #5
0
        private void Config(HashDatabaseConfig cfg)
        {
            base.Config(cfg);

            /*
             * Database.Config calls set_flags, but that does not get the Hash
             * specific flags.  No harm in calling it again.
             */
            db.set_flags(cfg.flags);

            if (cfg.BlobDir != null && cfg.Env == null)
            {
                db.set_ext_file_dir(cfg.BlobDir);
            }
            if (cfg.ExternalFileDir != null && cfg.Env == null)
            {
                db.set_ext_file_dir(cfg.ExternalFileDir);
            }

            if (cfg.blobThresholdIsSet)
            {
                db.set_ext_file_threshold(cfg.BlobThreshold, 0);
            }

            if (cfg.HashFunction != null)
            {
                HashFunction = cfg.HashFunction;
            }
            // The duplicate comparison function cannot change.
            if (cfg.DuplicateCompare != null)
            {
                DupCompare = cfg.DuplicateCompare;
            }
            if (cfg.fillFactorIsSet)
            {
                db.set_h_ffactor(cfg.FillFactor);
            }
            if (cfg.nelemIsSet)
            {
                db.set_h_nelem(cfg.TableSize);
            }
            if (cfg.HashComparison != null)
            {
                Compare = cfg.HashComparison;
            }

            if (cfg.partitionIsSet)
            {
                nparts    = cfg.NParts;
                Partition = cfg.Partition;
                if (Partition == null)
                {
                    doPartitionRef = null;
                }
                else
                {
                    doPartitionRef = new BDB_PartitionDelegate(doPartition);
                }
                partitionKeys = cfg.PartitionKeys;
                IntPtr[] ptrs = null;
                if (partitionKeys != null)
                {
                    int size = (int)nparts - 1;
                    ptrs = new IntPtr[size];
                    for (int i = 0; i < size; i++)
                    {
                        ptrs[i] = DBT.getCPtr(
                            DatabaseEntry.getDBT(partitionKeys[i])).Handle;
                    }
                }
                db.set_partition(nparts, ptrs, doPartitionRef);
            }
        }
예제 #6
0
        /// <summary>
        /// Protected method to call the key generation function.
        /// </summary>
        /// <param name="dbp">Secondary DB Handle</param>
        /// <param name="keyp">Primary Key</param>
        /// <param name="datap">Primary Data</param>
        /// <param name="skeyp">Scondary Key</param>
        /// <returns>0 on success, !0 on failure</returns>
        protected static int doAssociate(
            IntPtr dbp, IntPtr keyp, IntPtr datap, IntPtr skeyp)
        {
            DB     db = new DB(dbp, false);
            DBT    key = new DBT(keyp, false);
            DBT    data = new DBT(datap, false);
            DBT    skey = new DBT(skeyp, false);
            IntPtr dataPtr, sdataPtr;
            int    nrecs, dbt_sz;

            DatabaseEntry s =
                ((SecondaryDatabase)db.api_internal).KeyGen(
                    DatabaseEntry.fromDBT(key), DatabaseEntry.fromDBT(data));

            if (s == null)
            {
                return(DbConstants.DB_DONOTINDEX);
            }
            if (s is MultipleDatabaseEntry)
            {
                MultipleDatabaseEntry mde = (MultipleDatabaseEntry)s;
                nrecs = mde.nRecs;

                /*
                 * Allocate an array of nrecs DBT in native memory.  The call
                 * returns sizeof(DBT), so that we know where one DBT ends and
                 * the next begins.
                 */
                dbt_sz = (int)libdb_csharp.alloc_dbt_arr(null, nrecs, out sdataPtr);

                /*
                 * We need a managed array to copy each DBT into and then we'll
                 * copy the managed array to the native array we just allocated.
                 * We are not able to copy native -> native.
                 */
                byte[] arr = new byte[nrecs * dbt_sz];
                IntPtr p;
                int    off = 0;
                /* Copy each DBT into the array. */
                foreach (DatabaseEntry dbt in mde)
                {
                    /* Allocate room for the data in native memory. */
                    dataPtr = libdb_csharp.__os_umalloc(null, dbt.size);
                    Marshal.Copy(dbt.Data, 0, dataPtr, (int)dbt.size);
                    dbt.dbt.dataPtr = dataPtr;
                    dbt.flags      |= DbConstants.DB_DBT_APPMALLOC;

                    p = DBT.getCPtr(DatabaseEntry.getDBT(dbt)).Handle;
                    Marshal.Copy(p, arr, off, dbt_sz);
                    off += dbt_sz;
                }
                Marshal.Copy(arr, 0, sdataPtr, nrecs * dbt_sz);
                skey.dataPtr = sdataPtr;
                skey.size    = (uint)mde.nRecs;
                skey.flags   = DbConstants.DB_DBT_MULTIPLE | DbConstants.DB_DBT_APPMALLOC;
            }
            else
            {
                skey.data = s.Data;
            }
            return(0);
        }