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