diff --git a/mdbx.h b/mdbx.h index 82d46ef4..a99d4143 100644 --- a/mdbx.h +++ b/mdbx.h @@ -5240,177 +5240,6 @@ LIBMDBX_API int mdbx_env_turn_for_recovery(MDBX_env *env, unsigned target_meta); /** end of btree_traversal @} */ -/**** Attribute support functions for Nexenta (scheduled for removal) - * *****************************************************************/ -#if defined(MDBX_NEXENTA_ATTRS) || defined(DOXYGEN) -/** \defgroup nexenta Attribute support functions for Nexenta - * \ingroup c_crud - * @{ */ -typedef uint_fast64_t mdbx_attr_t; - -/** Store by cursor with attribute. - * - * This function stores key/data pairs into the database. The cursor is - * positioned at the new item, or on failure usually near it. - * - * \note Internally based on \ref MDBX_RESERVE feature, - * therefore doesn't support \ref MDBX_DUPSORT. - * - * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_open() - * \param [in] key The key operated on. - * \param [in] data The data operated on. - * \param [in] attr The attribute. - * \param [in] flags Options for this operation. This parameter must be set - * to 0 or one of the values described here: - * - \ref MDBX_CURRENT - * Replace the item at the current cursor position. The key parameter - * must still be provided, and must match it, otherwise the function - * return \ref MDBX_EKEYMISMATCH. - * - * - \ref MDBX_APPEND - * Append the given key/data pair to the end of the database. No key - * comparisons are performed. This option allows fast bulk loading when - * keys are already known to be in the correct order. Loading unsorted - * keys with this flag will cause a \ref MDBX_KEYEXIST error. - * - * \see \ref c_crud_hints "Quick reference for Insert/Update/Delete operations" - * - * \returns A non-zero error value on failure and 0 on success, - * some possible errors are: - * \retval MDBX_EKEYMISMATCH - * \retval MDBX_MAP_FULL The database is full, see \ref mdbx_env_set_mapsize(). - * \retval MDBX_TXN_FULL The transaction has too many dirty pages. - * \retval MDBX_EACCES An attempt was made to write in a read-only - * transaction. - * \retval MDBX_EINVAL an invalid parameter was specified. */ -LIBMDBX_API int mdbx_cursor_put_attr(MDBX_cursor *cursor, MDBX_val *key, - MDBX_val *data, mdbx_attr_t attr, - MDBX_put_flags_t flags); - -/** Store items and attributes into a database. - * - * This function stores key/data pairs in the database. The default behavior - * is to enter the new key/data pair, replacing any previously existing key - * if duplicates are disallowed. - * - * \note Internally based on \ref MDBX_RESERVE feature, - * therefore doesn't support \ref MDBX_DUPSORT. - * - * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in] key The key to store in the database. - * \param [in] attr The attribute to store in the database. - * \param [in,out] data The data to store. - * \param [in] flags Special options for this operation. This parameter - * must be set to 0 or by bitwise OR'ing together one or - * more of the values described here: - * - \ref MDBX_NOOVERWRITE - * Enter the new key/data pair only if the key does not already appear - * in the database. The function will return \ref MDBX_KEYEXIST if the key - * already appears in the database. The data parameter will be set to - * point to the existing item. - * - * - \ref MDBX_CURRENT - * Update an single existing entry, but not add new ones. The function - * will return \ref MDBX_NOTFOUND if the given key not exist in the - * database. Or the \ref MDBX_EMULTIVAL in case duplicates for the given - * key. - * - * - \ref MDBX_APPEND - * Append the given key/data pair to the end of the database. This option - * allows fast bulk loading when keys are already known to be in the - * correct order. Loading unsorted keys with this flag will cause - * a \ref MDBX_EKEYMISMATCH error. - * - * \see \ref c_crud_hints "Quick reference for Insert/Update/Delete operations" - * - * \returns A non-zero error value on failure and 0 on success, - * some possible errors are: - * \retval MDBX_KEYEXIST - * \retval MDBX_MAP_FULL The database is full, see \ref mdbx_env_set_mapsize(). - * \retval MDBX_TXN_FULL The transaction has too many dirty pages. - * \retval MDBX_EACCES An attempt was made to write - * in a read-only transaction. - * \retval MDBX_EINVAL An invalid parameter was specified. */ -LIBMDBX_API int mdbx_put_attr(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, - MDBX_val *data, mdbx_attr_t attr, - MDBX_put_flags_t flags); - -/** Set items attribute from a database. - * - * This function stores key/data pairs attribute to the database. - * - * \note Internally based on \ref MDBX_RESERVE feature, - * therefore doesn't support \ref MDBX_DUPSORT. - * - * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in] key The key to search for in the database. - * \param [in] data The data to be stored or NULL to save previous value. - * \param [in] attr The attribute to be stored. - * - * \returns A non-zero error value on failure and 0 on success, - * some possible errors are: - * \retval MDBX_NOTFOUND The key-value pair was not in the database. - * \retval MDBX_EINVAL An invalid parameter was specified. */ -LIBMDBX_API int mdbx_set_attr(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, - MDBX_val *data, mdbx_attr_t attr); - -/** Get items attribute from a database cursor. - * - * This function retrieves key/data pairs from the database. The address and - * length of the key are returned in the object to which key refers (except - * for the case of the \ref MDBX_SET option, in which the key object is - * unchanged), and the address and length of the data are returned in the object - * to which data refers. - * \see mdbx_get() - * - * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_open(). - * \param [in,out] key The key for a retrieved item. - * \param [in,out] data The data of a retrieved item. - * \param [out] pattr The pointer to retrieve attribute. - * \param [in] op A cursor operation MDBX_cursor_op. - * - * \returns A non-zero error value on failure and 0 on success, - * some possible errors are: - * \retval MDBX_NOTFOUND No matching key found. - * \retval MDBX_EINVAL An invalid parameter was specified. */ -LIBMDBX_API int mdbx_cursor_get_attr(MDBX_cursor *cursor, MDBX_val *key, - MDBX_val *data, mdbx_attr_t *pattr, - MDBX_cursor_op op); - -/** Get items attribute from a database. - * - * This function retrieves key/data pairs from the database. The address - * and length of the data associated with the specified key are returned - * in the structure to which data refers. - * If the database supports duplicate keys (see \ref MDBX_DUPSORT) then the - * first data item for the key will be returned. Retrieval of other - * items requires the use of \ref mdbx_cursor_get(). - * - * \note The memory pointed to by the returned values is owned by the - * database. The caller need not dispose of the memory, and may not - * modify it in any way. For values returned in a read-only transaction - * any modification attempts will cause a `SIGSEGV`. - * - * \note Values returned from the database are valid only until a - * subsequent update operation, or the end of the transaction. - * - * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in] key The key to search for in the database. - * \param [in,out] data The data corresponding to the key. - * \param [out] pattr The pointer to retrieve attribute. - * - * \returns A non-zero error value on failure and 0 on success, - * some possible errors are: - * \retval MDBX_NOTFOUND The key was not in the database. - * \retval MDBX_EINVAL An invalid parameter was specified. */ -LIBMDBX_API int mdbx_get_attr(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, - MDBX_val *data, mdbx_attr_t *pattr); -/** end of nexenta @} */ -#endif /* MDBX_NEXENTA_ATTRS */ - /** end of c_api @} */ /******************************************************************************* diff --git a/src/core.c b/src/core.c index eb0ec5d5..eaf9c818 100644 --- a/src/core.c +++ b/src/core.c @@ -23018,132 +23018,6 @@ __cold int mdbx_env_get_option(const MDBX_env *env, const MDBX_option_t option, return MDBX_SUCCESS; } -/*** Attribute support functions for Nexenta **********************************/ -#ifdef MDBX_NEXENTA_ATTRS - -static __inline int mdbx_attr_peek(MDBX_val *data, mdbx_attr_t *attrptr) { - if (unlikely(data->iov_len < sizeof(mdbx_attr_t))) - return MDBX_INCOMPATIBLE; - - if (likely(attrptr != NULL)) - *attrptr = *(mdbx_attr_t *)data->iov_base; - data->iov_len -= sizeof(mdbx_attr_t); - data->iov_base = - likely(data->iov_len > 0) ? ((mdbx_attr_t *)data->iov_base) + 1 : NULL; - - return MDBX_SUCCESS; -} - -static __inline int mdbx_attr_poke(MDBX_val *reserved, MDBX_val *data, - mdbx_attr_t attr, MDBX_put_flags_t flags) { - mdbx_attr_t *space = reserved->iov_base; - if (flags & MDBX_RESERVE) { - if (likely(data != NULL)) { - data->iov_base = data->iov_len ? space + 1 : NULL; - } - } else { - *space = attr; - if (likely(data != NULL)) { - memcpy(space + 1, data->iov_base, data->iov_len); - } - } - - return MDBX_SUCCESS; -} - -int mdbx_cursor_get_attr(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, - mdbx_attr_t *attrptr, MDBX_cursor_op op) { - int rc = mdbx_cursor_get(mc, key, data, op); - if (unlikely(rc != MDBX_SUCCESS)) - return rc; - - return mdbx_attr_peek(data, attrptr); -} - -int mdbx_get_attr(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, - uint64_t *attrptr) { - int rc = mdbx_get(txn, dbi, key, data); - if (unlikely(rc != MDBX_SUCCESS)) - return rc; - - return mdbx_attr_peek(data, attrptr); -} - -int mdbx_put_attr(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, - mdbx_attr_t attr, MDBX_put_flags_t flags) { - MDBX_val reserve; - reserve.iov_base = NULL; - reserve.iov_len = (data ? data->iov_len : 0) + sizeof(mdbx_attr_t); - - int rc = mdbx_put(txn, dbi, key, &reserve, flags | MDBX_RESERVE); - if (unlikely(rc != MDBX_SUCCESS)) - return rc; - - return mdbx_attr_poke(&reserve, data, attr, flags); -} - -int mdbx_cursor_put_attr(MDBX_cursor *cursor, MDBX_val *key, MDBX_val *data, - mdbx_attr_t attr, MDBX_put_flags_t flags) { - MDBX_val reserve; - reserve.iov_base = NULL; - reserve.iov_len = (data ? data->iov_len : 0) + sizeof(mdbx_attr_t); - - int rc = mdbx_cursor_put(cursor, key, &reserve, flags | MDBX_RESERVE); - if (unlikely(rc != MDBX_SUCCESS)) - return rc; - - return mdbx_attr_poke(&reserve, data, attr, flags); -} - -int mdbx_set_attr(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, - mdbx_attr_t attr) { - if (unlikely(!key || !txn)) - return MDBX_EINVAL; - - if (unlikely(txn->mt_signature != MDBX_MT_SIGNATURE)) - return MDBX_EBADSIGN; - - if (unlikely(!check_dbi(txn, dbi, DB_USRVALID))) - return MDBX_BAD_DBI; - - if (unlikely(txn->mt_flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED))) - return (txn->mt_flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN; - - MDBX_cursor_couple cx; - MDBX_val old_data; - int rc = cursor_init(&cx.outer, txn, dbi); - if (unlikely(rc != MDBX_SUCCESS)) - return rc; - rc = mdbx_cursor_set(&cx.outer, key, &old_data, MDBX_SET, NULL); - if (unlikely(rc != MDBX_SUCCESS)) { - if (rc == MDBX_NOTFOUND && data) { - cx.outer.mc_next = txn->mt_cursors[dbi]; - txn->mt_cursors[dbi] = &cx.outer; - rc = mdbx_cursor_put_attr(&cx.outer, key, data, attr, 0); - txn->mt_cursors[dbi] = cx.outer.mc_next; - } - return rc; - } - - mdbx_attr_t old_attr = 0; - rc = mdbx_attr_peek(&old_data, &old_attr); - if (unlikely(rc != MDBX_SUCCESS)) - return rc; - - if (old_attr == attr && (!data || (data->iov_len == old_data.iov_len && - memcmp(data->iov_base, old_data.iov_base, - old_data.iov_len) == 0))) - return MDBX_SUCCESS; - - cx.outer.mc_next = txn->mt_cursors[dbi]; - txn->mt_cursors[dbi] = &cx.outer; - rc = mdbx_cursor_put_attr(&cx.outer, key, data ? data : &old_data, attr, - MDBX_CURRENT); - txn->mt_cursors[dbi] = cx.outer.mc_next; - return rc; -} -#endif /* MDBX_NEXENTA_ATTRS */ - /******************************************************************************/ /* *INDENT-OFF* */ /* clang-format off */