Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
b66164ab
Commit
b66164ab
authored
Aug 29, 2018
by
Eugene Kosov
Committed by
Sergey Vojtovich
Mar 29, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
remove dead code
parent
65bd3820
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
0 additions
and
514 deletions
+0
-514
storage/innobase/dict/dict0stats.cc
storage/innobase/dict/dict0stats.cc
+0
-59
storage/innobase/handler/handler0alter.cc
storage/innobase/handler/handler0alter.cc
+0
-279
storage/innobase/include/dict0stats.h
storage/innobase/include/dict0stats.h
+0
-15
storage/innobase/include/ha_prototypes.h
storage/innobase/include/ha_prototypes.h
+0
-1
storage/innobase/include/mem0mem.h
storage/innobase/include/mem0mem.h
+0
-64
storage/innobase/include/mem0mem.ic
storage/innobase/include/mem0mem.ic
+0
-96
No files found.
storage/innobase/dict/dict0stats.cc
View file @
b66164ab
...
...
@@ -3838,65 +3838,6 @@ dict_stats_rename_table(
return
(
ret
);
}
#ifdef MYSQL_RENAME_INDEX
/*********************************************************************//**
Renames an index in InnoDB persistent stats storage.
This function creates its own transaction and commits it.
@return DB_SUCCESS or error code. DB_STATS_DO_NOT_EXIST will be returned
if the persistent stats do not exist. */
dberr_t
dict_stats_rename_index
(
/*====================*/
const
dict_table_t
*
table
,
/*!< in: table whose index
is renamed */
const
char
*
old_index_name
,
/*!< in: old index name */
const
char
*
new_index_name
)
/*!< in: new index name */
{
rw_lock_x_lock
(
dict_operation_lock
);
mutex_enter
(
&
dict_sys
->
mutex
);
if
(
!
dict_stats_persistent_storage_check
(
true
))
{
mutex_exit
(
&
dict_sys
->
mutex
);
rw_lock_x_unlock
(
dict_operation_lock
);
return
(
DB_STATS_DO_NOT_EXIST
);
}
char
dbname_utf8
[
MAX_DB_UTF8_LEN
];
char
tablename_utf8
[
MAX_TABLE_UTF8_LEN
];
dict_fs2utf8
(
table
->
name
.
m_name
,
dbname_utf8
,
sizeof
(
dbname_utf8
),
tablename_utf8
,
sizeof
(
tablename_utf8
));
pars_info_t
*
pinfo
;
pinfo
=
pars_info_create
();
pars_info_add_str_literal
(
pinfo
,
"dbname_utf8"
,
dbname_utf8
);
pars_info_add_str_literal
(
pinfo
,
"tablename_utf8"
,
tablename_utf8
);
pars_info_add_str_literal
(
pinfo
,
"new_index_name"
,
new_index_name
);
pars_info_add_str_literal
(
pinfo
,
"old_index_name"
,
old_index_name
);
dberr_t
ret
;
ret
=
dict_stats_exec_sql
(
pinfo
,
"PROCEDURE RENAME_INDEX_IN_INDEX_STATS () IS
\n
"
"BEGIN
\n
"
"UPDATE
\"
"
INDEX_STATS_NAME
"
\"
SET
\n
"
"index_name = :new_index_name
\n
"
"WHERE
\n
"
"database_name = :dbname_utf8 AND
\n
"
"table_name = :tablename_utf8 AND
\n
"
"index_name = :old_index_name;
\n
"
"END;
\n
"
,
NULL
);
mutex_exit
(
&
dict_sys
->
mutex
);
rw_lock_x_unlock
(
dict_operation_lock
);
return
(
ret
);
}
#endif
/* MYSQL_RENAME_INDEX */
/* tests @{ */
#ifdef UNIV_ENABLE_UNIT_TEST_DICT_STATS
...
...
storage/innobase/handler/handler0alter.cc
View file @
b66164ab
...
...
@@ -104,9 +104,6 @@ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_NOREBUILD
|
INNOBASE_FOREIGN_OPERATIONS
|
Alter_inplace_info
::
DROP_INDEX
|
Alter_inplace_info
::
DROP_UNIQUE_INDEX
#ifdef MYSQL_RENAME_INDEX
|
Alter_inplace_info
::
RENAME_INDEX
#endif
|
Alter_inplace_info
::
ALTER_COLUMN_NAME
|
Alter_inplace_info
::
ALTER_COLUMN_EQUAL_PACK_LENGTH
//| Alter_inplace_info::ALTER_INDEX_COMMENT
...
...
@@ -2028,23 +2025,6 @@ innobase_check_index_keys(
}
}
#ifdef MYSQL_RENAME_INDEX
/* If a key by the same name is being created and
renamed, the name clash is OK. E.g.
ALTER TABLE t ADD INDEX i (col), RENAME INDEX i TO x
where the index "i" exists prior to the ALTER command.
In this case we:
1. rename the existing index from "i" to "x"
2. add the new index "i" */
for
(
uint
i
=
0
;
i
<
info
->
index_rename_count
;
i
++
)
{
const
KEY_PAIR
*
pair
=
&
info
->
index_rename_buffer
[
i
];
if
(
0
==
strcmp
(
key
.
name
,
pair
->
old_key
->
name
))
{
goto
name_ok
;
}
}
#endif
/* MYSQL_RENAME_INDEX */
my_error
(
ER_WRONG_NAME_FOR_INDEX
,
MYF
(
0
),
key
.
name
);
...
...
@@ -5236,192 +5216,6 @@ innobase_check_foreign_key_index(
return
(
false
);
}
#ifdef MYSQL_RENAME_INDEX
/**
Rename a given index in the InnoDB data dictionary.
@param index index to rename
@param new_name new name of the index
@param[in,out] trx dict transaction to use, not going to be committed here
@retval true Failure
@retval false Success */
static
MY_ATTRIBUTE
((
warn_unused_result
))
bool
rename_index_in_data_dictionary
(
/*============================*/
const
dict_index_t
*
index
,
const
char
*
new_name
,
trx_t
*
trx
)
{
DBUG_ENTER
(
"rename_index_in_data_dictionary"
);
ut_ad
(
mutex_own
(
&
dict_sys
->
mutex
));
ut_ad
(
rw_lock_own
(
dict_operation_lock
,
RW_LOCK_X
));
ut_ad
(
trx
->
dict_operation_lock_mode
==
RW_X_LATCH
);
pars_info_t
*
pinfo
;
dberr_t
err
;
pinfo
=
pars_info_create
();
pars_info_add_ull_literal
(
pinfo
,
"table_id"
,
index
->
table
->
id
);
pars_info_add_ull_literal
(
pinfo
,
"index_id"
,
index
->
id
);
pars_info_add_str_literal
(
pinfo
,
"new_name"
,
new_name
);
trx
->
op_info
=
"Renaming an index in SYS_INDEXES"
;
DBUG_EXECUTE_IF
(
"ib_rename_index_fail1"
,
DBUG_SET
(
"+d,innodb_report_deadlock"
);
);
err
=
que_eval_sql
(
pinfo
,
"PROCEDURE RENAME_INDEX_IN_SYS_INDEXES () IS
\n
"
"BEGIN
\n
"
"UPDATE SYS_INDEXES SET
\n
"
"NAME = :new_name
\n
"
"WHERE
\n
"
"ID = :index_id AND
\n
"
"TABLE_ID = :table_id;
\n
"
"END;
\n
"
,
FALSE
,
trx
);
/* pinfo is freed by que_eval_sql() */
DBUG_EXECUTE_IF
(
"ib_rename_index_fail1"
,
DBUG_SET
(
"-d,innodb_report_deadlock"
);
);
trx
->
op_info
=
""
;
if
(
err
!=
DB_SUCCESS
)
{
my_error_innodb
(
err
,
index
->
table
->
name
.
m_name
,
0
);
DBUG_RETURN
(
true
);
}
DBUG_RETURN
(
false
);
}
/**
Rename all indexes in data dictionary of a given table that are
specified in ha_alter_info.
@param ctx alter context, used to fetch the list of indexes to
rename
@param ha_alter_info fetch the new names from here
@param[in,out] trx dict transaction to use, not going to be committed here
@retval true Failure
@retval false Success */
static
MY_ATTRIBUTE
((
warn_unused_result
))
bool
rename_indexes_in_data_dictionary
(
/*==============================*/
const
ha_innobase_inplace_ctx
*
ctx
,
const
Alter_inplace_info
*
ha_alter_info
,
trx_t
*
trx
)
{
DBUG_ENTER
(
"rename_indexes_in_data_dictionary"
);
ut_ad
(
ctx
->
num_to_rename
==
ha_alter_info
->
index_rename_count
);
for
(
ulint
i
=
0
;
i
<
ctx
->
num_to_rename
;
i
++
)
{
KEY_PAIR
*
pair
=
&
ha_alter_info
->
index_rename_buffer
[
i
];
dict_index_t
*
index
;
index
=
ctx
->
rename
[
i
];
ut_ad
(
strcmp
(
index
->
name
,
pair
->
old_key
->
name
)
==
0
);
if
(
rename_index_in_data_dictionary
(
index
,
pair
->
new_key
->
name
,
trx
))
{
/* failed */
DBUG_RETURN
(
true
);
}
}
DBUG_RETURN
(
false
);
}
/**
Rename a given index in the InnoDB data dictionary cache.
@param[in,out] index index to rename
@param new_name new index name
*/
static
void
rename_index_in_cache
(
/*==================*/
dict_index_t
*
index
,
const
char
*
new_name
)
{
DBUG_ENTER
(
"rename_index_in_cache"
);
ut_ad
(
mutex_own
(
&
dict_sys
->
mutex
));
ut_ad
(
rw_lock_own
(
dict_operation_lock
,
RW_LOCK_X
));
size_t
old_name_len
=
strlen
(
index
->
name
);
size_t
new_name_len
=
strlen
(
new_name
);
if
(
old_name_len
>=
new_name_len
)
{
/* reuse the old buffer for the name if it is large enough */
memcpy
(
const_cast
<
char
*>
(
index
->
name
()),
new_name
,
new_name_len
+
1
);
}
else
{
/* Free the old chunk of memory if it is at the topmost
place in the heap, otherwise the old chunk will be freed
when the index is evicted from the cache. This code will
kick-in in a repeated ALTER sequences where the old name is
alternately longer/shorter than the new name:
1. ALTER TABLE t RENAME INDEX a TO aa;
2. ALTER TABLE t RENAME INDEX aa TO a;
3. go to 1. */
index
->
name
=
mem_heap_strdup_replace
(
index
->
heap
,
/* Presumed topmost element of the heap: */
index
->
name
,
old_name_len
+
1
,
new_name
);
}
DBUG_VOID_RETURN
;
}
/**
Rename all indexes in data dictionary cache of a given table that are
specified in ha_alter_info.
@param ctx alter context, used to fetch the list of indexes to rename
@param ha_alter_info fetch the new names from here
*/
static
void
rename_indexes_in_cache
(
/*====================*/
const
ha_innobase_inplace_ctx
*
ctx
,
const
Alter_inplace_info
*
ha_alter_info
)
{
DBUG_ENTER
(
"rename_indexes_in_cache"
);
ut_ad
(
ctx
->
num_to_rename
==
ha_alter_info
->
index_rename_count
);
for
(
ulint
i
=
0
;
i
<
ctx
->
num_to_rename
;
i
++
)
{
KEY_PAIR
*
pair
=
&
ha_alter_info
->
index_rename_buffer
[
i
];
dict_index_t
*
index
;
index
=
ctx
->
rename
[
i
];
ut_ad
(
strcmp
(
index
->
name
,
pair
->
old_key
->
name
)
==
0
);
rename_index_in_cache
(
index
,
pair
->
new_key
->
name
);
}
DBUG_VOID_RETURN
;
}
#endif
/* MYSQL_RENAME_INDEX */
/** Fill the stored column information in s_cols list.
@param[in] altered_table mysql table object
...
...
@@ -6020,43 +5814,6 @@ ha_innobase::prepare_inplace_alter_table(
n_rename_index
=
0
;
rename_index
=
NULL
;
#ifdef MYSQL_RENAME_INDEX
n_rename_index
=
ha_alter_info
->
index_rename_count
;
/* Create a list of dict_index_t objects that are to be renamed,
also checking for requests to rename nonexistent indexes. If
the table is going to be rebuilt (new_clustered == true in
prepare_inplace_alter_table_dict()), then this can be skipped,
but we don't for simplicity (we have not determined the value of
new_clustered yet). */
if
(
n_rename_index
>
0
)
{
rename_index
=
static_cast
<
dict_index_t
**>
(
mem_heap_alloc
(
heap
,
n_rename_index
*
sizeof
(
*
rename_index
)));
for
(
ulint
i
=
0
;
i
<
n_rename_index
;
i
++
)
{
dict_index_t
*
index
=
NULL
;
const
char
*
old_name
=
NULL
;
const
char
*
old_name
=
ha_alter_info
->
index_rename_buffer
[
i
].
old_key
->
name
;
index
=
dict_table_get_index_on_name
(
indexed_table
,
old_name
);
if
(
index
==
NULL
)
{
my_error
(
ER_KEY_DOES_NOT_EXITS
,
MYF
(
0
),
old_name
,
m_prebuilt
->
table
->
name
.
m_name
);
goto
err_exit
;
}
rename_index
[
i
]
=
index
;
}
}
#endif
/* MYSQL_RENAME_INDEX */
n_add_fk
=
0
;
if
(
ha_alter_info
->
handler_flags
...
...
@@ -8088,14 +7845,6 @@ commit_try_norebuild(
DBUG_RETURN
(
true
);
}
#ifdef MYSQL_RENAME_INDEX
if
((
ha_alter_info
->
handler_flags
&
Alter_inplace_info
::
RENAME_INDEX
)
&&
rename_indexes_in_data_dictionary
(
ctx
,
ha_alter_info
,
trx
))
{
DBUG_RETURN
(
true
);
}
#endif
/* MYSQL_RENAME_INDEX */
if
((
ha_alter_info
->
handler_flags
&
Alter_inplace_info
::
DROP_VIRTUAL_COLUMN
)
&&
innobase_drop_virtual_try
(
...
...
@@ -8295,31 +8044,6 @@ alter_stats_norebuild(
}
}
#ifdef MYSQL_RENAME_INDEX
for
(
i
=
0
;
i
<
ha_alter_info
->
index_rename_count
;
i
++
)
{
KEY_PAIR
*
pair
=
&
ha_alter_info
->
index_rename_buffer
[
i
];
dberr_t
err
;
err
=
dict_stats_rename_index
(
ctx
->
new_table
,
pair
->
old_key
->
name
,
pair
->
new_key
->
name
);
if
(
err
!=
DB_SUCCESS
)
{
push_warning_printf
(
thd
,
Sql_condition
::
WARN_LEVEL_WARN
,
ER_ERROR_ON_RENAME
,
"Error renaming an index of table '%s'"
" from '%s' to '%s' in InnoDB persistent"
" statistics storage: %s"
,
table_name
,
pair
->
old_key
->
name
,
pair
->
new_key
->
name
,
ut_strerr
(
err
));
}
}
#endif
/* MYSQL_RENAME_INDEX */
for
(
i
=
0
;
i
<
ctx
->
num_to_add_index
;
i
++
)
{
dict_index_t
*
index
=
ctx
->
add_index
[
i
];
DBUG_ASSERT
(
index
->
table
==
ctx
->
new_table
);
...
...
@@ -8847,9 +8571,6 @@ ha_innobase::commit_inplace_alter_table(
innobase_rename_or_enlarge_columns_cache
(
ha_alter_info
,
table
,
ctx
->
new_table
);
#ifdef MYSQL_RENAME_INDEX
rename_indexes_in_cache
(
ctx
,
ha_alter_info
);
#endif
if
(
fk_fail
&&
m_prebuilt
->
trx
->
check_foreigns
)
{
goto
foreign_fail
;
}
...
...
storage/innobase/include/dict0stats.h
View file @
b66164ab
...
...
@@ -187,21 +187,6 @@ dict_stats_rename_table(
char
*
errstr
,
/*!< out: error string if != DB_SUCCESS
is returned */
size_t
errstr_sz
);
/*!< in: errstr size */
#ifdef MYSQL_RENAME_INDEX
/*********************************************************************//**
Renames an index in InnoDB persistent stats storage.
This function creates its own transaction and commits it.
@return DB_SUCCESS or error code. DB_STATS_DO_NOT_EXIST will be returned
if the persistent stats do not exist. */
dberr_t
dict_stats_rename_index
(
/*====================*/
const
dict_table_t
*
table
,
/*!< in: table whose index
is renamed */
const
char
*
old_index_name
,
/*!< in: old index name */
const
char
*
new_index_name
)
/*!< in: new index name */
__attribute__
((
warn_unused_result
));
#endif
/* MYSQL_RENAME_INDEX */
/** Save an individual index's statistic into the persistent statistics
storage.
...
...
storage/innobase/include/ha_prototypes.h
View file @
b66164ab
...
...
@@ -40,7 +40,6 @@ class THD;
// JAN: TODO missing features:
#undef MYSQL_FT_INIT_EXT
#undef MYSQL_PFS
#undef MYSQL_RENAME_INDEX
#undef MYSQL_STORE_FTS_DOC_ID
/*******************************************************************//**
...
...
storage/innobase/include/mem0mem.h
View file @
b66164ab
...
...
@@ -193,70 +193,6 @@ mem_heap_get_top(
mem_heap_t
*
heap
,
ulint
n
);
/** Checks if a given chunk of memory is the topmost element stored in the
heap. If this is the case, then calling mem_heap_free_top() would free
that element from the heap.
@param[in] heap memory heap
@param[in] buf presumed topmost element
@param[in] buf_sz size of buf in bytes
@return true if topmost */
UNIV_INLINE
bool
mem_heap_is_top
(
mem_heap_t
*
heap
,
const
void
*
buf
,
ulint
buf_sz
)
MY_ATTRIBUTE
((
warn_unused_result
));
/*****************************************************************//**
Allocate a new chunk of memory from a memory heap, possibly discarding
the topmost element. If the memory chunk specified with (top, top_sz)
is the topmost element, then it will be discarded, otherwise it will
be left untouched and this function will be equivallent to
mem_heap_alloc().
@return allocated storage, NULL if did not succeed (only possible for
MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
void
*
mem_heap_replace
(
/*=============*/
mem_heap_t
*
heap
,
/*!< in/out: memory heap */
const
void
*
top
,
/*!< in: chunk to discard if possible */
ulint
top_sz
,
/*!< in: size of top in bytes */
ulint
new_sz
);
/*!< in: desired size of the new chunk */
/*****************************************************************//**
Allocate a new chunk of memory from a memory heap, possibly discarding
the topmost element and then copy the specified data to it. If the memory
chunk specified with (top, top_sz) is the topmost element, then it will be
discarded, otherwise it will be left untouched and this function will be
equivallent to mem_heap_dup().
@return allocated storage, NULL if did not succeed (only possible for
MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
void
*
mem_heap_dup_replace
(
/*=================*/
mem_heap_t
*
heap
,
/*!< in/out: memory heap */
const
void
*
top
,
/*!< in: chunk to discard if possible */
ulint
top_sz
,
/*!< in: size of top in bytes */
const
void
*
data
,
/*!< in: new data to duplicate */
ulint
data_sz
);
/*!< in: size of data in bytes */
/*****************************************************************//**
Allocate a new chunk of memory from a memory heap, possibly discarding
the topmost element and then copy the specified string to it. If the memory
chunk specified with (top, top_sz) is the topmost element, then it will be
discarded, otherwise it will be left untouched and this function will be
equivallent to mem_heap_strdup().
@return allocated string, NULL if did not succeed (only possible for
MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
char
*
mem_heap_strdup_replace
(
/*====================*/
mem_heap_t
*
heap
,
/*!< in/out: memory heap */
const
void
*
top
,
/*!< in: chunk to discard if possible */
ulint
top_sz
,
/*!< in: size of top in bytes */
const
char
*
str
);
/*!< in: new data to duplicate */
/*****************************************************************//**
Frees the topmost element in a memory heap.
The size of the element must be given. */
...
...
storage/innobase/include/mem0mem.ic
View file @
b66164ab
...
...
@@ -327,102 +327,6 @@ mem_heap_get_top(
return((void*) buf);
}
/** Checks if a given chunk of memory is the topmost element stored in the
heap. If this is the case, then calling mem_heap_free_top() would free
that element from the heap.
@param[in] heap memory heap
@param[in] buf presumed topmost element
@param[in] buf_sz size of buf in bytes
@return true if topmost */
UNIV_INLINE
bool
mem_heap_is_top(
mem_heap_t* heap,
const void* buf,
ulint buf_sz)
{
const byte* first_free_byte;
const byte* presumed_start_of_buf;
ut_d(mem_block_validate(heap));
first_free_byte = mem_heap_get_heap_top(heap);
presumed_start_of_buf = first_free_byte - MEM_SPACE_NEEDED(buf_sz);
return(presumed_start_of_buf == buf);
}
/*****************************************************************//**
Allocate a new chunk of memory from a memory heap, possibly discarding
the topmost element. If the memory chunk specified with (top, top_sz)
is the topmost element, then it will be discarded, otherwise it will
be left untouched and this function will be equivallent to
mem_heap_alloc().
@return allocated storage, NULL if did not succeed (only possible for
MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
void*
mem_heap_replace(
/*=============*/
mem_heap_t* heap, /*!< in/out: memory heap */
const void* top, /*!< in: chunk to discard if possible */
ulint top_sz, /*!< in: size of top in bytes */
ulint new_sz) /*!< in: desired size of the new chunk */
{
if (mem_heap_is_top(heap, top, top_sz)) {
mem_heap_free_top(heap, top_sz);
}
return(mem_heap_alloc(heap, new_sz));
}
/*****************************************************************//**
Allocate a new chunk of memory from a memory heap, possibly discarding
the topmost element and then copy the specified data to it. If the memory
chunk specified with (top, top_sz) is the topmost element, then it will be
discarded, otherwise it will be left untouched and this function will be
equivallent to mem_heap_dup().
@return allocated storage, NULL if did not succeed (only possible for
MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
void*
mem_heap_dup_replace(
/*=================*/
mem_heap_t* heap, /*!< in/out: memory heap */
const void* top, /*!< in: chunk to discard if possible */
ulint top_sz, /*!< in: size of top in bytes */
const void* data, /*!< in: new data to duplicate */
ulint data_sz)/*!< in: size of data in bytes */
{
void* p = mem_heap_replace(heap, top, top_sz, data_sz);
memcpy(p, data, data_sz);
return(p);
}
/*****************************************************************//**
Allocate a new chunk of memory from a memory heap, possibly discarding
the topmost element and then copy the specified string to it. If the memory
chunk specified with (top, top_sz) is the topmost element, then it will be
discarded, otherwise it will be left untouched and this function will be
equivallent to mem_heap_strdup().
@return allocated string, NULL if did not succeed (only possible for
MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
char*
mem_heap_strdup_replace(
/*====================*/
mem_heap_t* heap, /*!< in/out: memory heap */
const void* top, /*!< in: chunk to discard if possible */
ulint top_sz, /*!< in: size of top in bytes */
const char* str) /*!< in: new data to duplicate */
{
return(reinterpret_cast<char*>(mem_heap_dup_replace(
heap, top, top_sz, str, strlen(str) + 1)));
}
/*****************************************************************//**
Frees the topmost element in a memory heap. The size of the element must be
given. */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment