예제 #1
0
        KeyValuePair <DatabaseEntry, MultipleDatabaseEntry> GetBothMultiple(
            DatabaseEntry key, DatabaseEntry data,
            int BufferSize, Transaction txn, LockingInfo info)
        {
            KeyValuePair <DatabaseEntry, DatabaseEntry> kvp;
            int datasz = (int)data.Data.Length;

            for (; ;)
            {
                byte[] udata = new byte[BufferSize];
                Array.Copy(data.Data, udata, datasz);
                data.UserData = udata;
                data.size     = (uint)datasz;
                try {
                    kvp = Get(key, data, txn, info,
                              DbConstants.DB_MULTIPLE | DbConstants.DB_GET_BOTH);
                    break;
                } catch (MemoryException) {
                    int sz = (int)data.size;
                    if (sz > BufferSize)
                    {
                        BufferSize = sz;
                    }
                    else
                    {
                        BufferSize *= 2;
                    }
                }
            }
            MultipleDatabaseEntry dbe = new MultipleDatabaseEntry(kvp.Value);

            return(new KeyValuePair <DatabaseEntry, MultipleDatabaseEntry>(
                       kvp.Key, dbe));
        }
예제 #2
0
        /// <summary>
        /// Retrieve a specific numbered key and all duplicate data items from
        /// the database.
        /// </summary>
        /// <param name="recno">
        /// The record number of the record to be retrieved.
        /// </param>
        /// <param name="BufferSize">
        /// The initial size of the buffer to fill with duplicate data items. If
        /// the buffer is not large enough, it is automatically resized.
        /// </param>
        /// <param name="txn">
        /// <paramref name="txn"/> is a Transaction object returned from
        /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if
        /// the operation is part of a Berkeley DB Concurrent Data Store group,
        /// <paramref name="txn"/> is a handle returned from
        /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null.
        /// </param>
        /// <param name="info">The locking behavior to use.</param>
        /// <exception cref="NotFoundException">
        /// A NotFoundException is thrown if <paramref name="recno"/> is not in
        /// the database.
        /// </exception>
        /// <returns>
        /// A <see cref="KeyValuePair{T,T}"/> whose Key parameter is
        /// <paramref name="recno"/> and whose Value parameter is the retrieved
        /// data items.
        /// </returns>
        public KeyValuePair <DatabaseEntry, MultipleDatabaseEntry> GetMultiple(
            uint recno, int BufferSize, Transaction txn, LockingInfo info)
        {
            KeyValuePair <DatabaseEntry, DatabaseEntry> kvp;

            DatabaseEntry key = new DatabaseEntry();

            key.Data = BitConverter.GetBytes(recno);

            DatabaseEntry data = new DatabaseEntry();

            for (; ;)
            {
                data.UserData = new byte[BufferSize];
                try {
                    kvp = Get(key, data, txn, info,
                              DbConstants.DB_MULTIPLE | DbConstants.DB_SET_RECNO);
                    break;
                } catch (MemoryException) {
                    int sz = (int)data.size;
                    if (sz > BufferSize)
                    {
                        BufferSize = sz;
                    }
                    else
                    {
                        BufferSize *= 2;
                    }
                }
            }
            MultipleDatabaseEntry dbe = new MultipleDatabaseEntry(kvp.Value);

            return(new KeyValuePair <DatabaseEntry, MultipleDatabaseEntry>(
                       kvp.Key, dbe));
        }
예제 #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
        /// <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);
        }