{
"cells": [
{
"cell_type": "markdown",
"id": "f516c6f6",
"metadata": {},
"source": [
"# vo001_AdoptOrOwnMemory\n",
"In this tutorial we learn how the RVec class can be used to\n",
"adopt existing memory or allocate some.\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Danilo Piparo \n",
"This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, March 19, 2024 at 07:22 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "06d9a8bf",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2024-03-19T19:22:41.231108Z",
"iopub.status.busy": "2024-03-19T19:22:41.230669Z",
"iopub.status.idle": "2024-03-19T19:22:43.508437Z",
"shell.execute_reply": "2024-03-19T19:22:43.507331Z"
}
},
"outputs": [],
"source": [
"import ROOT"
]
},
{
"cell_type": "markdown",
"id": "895ba9ab",
"metadata": {},
"source": [
"We use this class for didactic purposes: upon copy, a line is printed to the terminal."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "c8e2c11c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2024-03-19T19:22:43.513491Z",
"iopub.status.busy": "2024-03-19T19:22:43.513126Z",
"iopub.status.idle": "2024-03-19T19:22:43.704830Z",
"shell.execute_reply": "2024-03-19T19:22:43.703644Z"
}
},
"outputs": [],
"source": [
"ROOT.gInterpreter.Declare('''\n",
"class UponCopyPrinter {\n",
"public:\n",
" UponCopyPrinter() = default;\n",
" UponCopyPrinter(UponCopyPrinter &&) = default;\n",
" UponCopyPrinter(const UponCopyPrinter &) { std::cout << \"Invoking copy c'tor!\" << std::endl; }\n",
"};\n",
"''')\n",
"\n",
"RVec_UponCopyPrinter = ROOT.ROOT.VecOps.RVec(ROOT.UponCopyPrinter)"
]
},
{
"cell_type": "markdown",
"id": "0e051d7a",
"metadata": {},
"source": [
"One of the essential features of RVec is its ability of adopting and owning memory."
]
},
{
"cell_type": "markdown",
"id": "3a991f8e",
"metadata": {},
"source": [
"Let's create an RVec of UponCopyPrinter instances. We expect no printout:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "39ab0052",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2024-03-19T19:22:43.734275Z",
"iopub.status.busy": "2024-03-19T19:22:43.733675Z",
"iopub.status.idle": "2024-03-19T19:22:44.046757Z",
"shell.execute_reply": "2024-03-19T19:22:44.032603Z"
}
},
"outputs": [],
"source": [
"v = RVec_UponCopyPrinter(3)"
]
},
{
"cell_type": "markdown",
"id": "8b2eb974",
"metadata": {},
"source": [
"Let's adopt the memory from v into v2. We expect no printout:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "4eb15e26",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2024-03-19T19:22:44.060878Z",
"iopub.status.busy": "2024-03-19T19:22:44.060503Z",
"iopub.status.idle": "2024-03-19T19:22:44.222171Z",
"shell.execute_reply": "2024-03-19T19:22:44.220866Z"
}
},
"outputs": [],
"source": [
"v2 = RVec_UponCopyPrinter(v.data(), v.size())"
]
},
{
"cell_type": "markdown",
"id": "7f0b0a68",
"metadata": {},
"source": [
"OK, let's check the addresses of the memory associated to the two RVecs It is the same!"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "5ccd591f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2024-03-19T19:22:44.231180Z",
"iopub.status.busy": "2024-03-19T19:22:44.230748Z",
"iopub.status.idle": "2024-03-19T19:22:44.421714Z",
"shell.execute_reply": "2024-03-19T19:22:44.398301Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" and \n"
]
}
],
"source": [
"print(\"%s and %s\" %(v.data(), v2.data()))"
]
},
{
"cell_type": "markdown",
"id": "cb835dcc",
"metadata": {},
"source": [
"Now, upon reallocation, the RVec stops adopting the memory and starts owning it. And yes,\n",
"a copy is triggered. Indeed internally the storage of the RVec is an std::vector. Moreover,\n",
"the interface of the RVec is very, very similar to the one of std::vector: you have already\n",
"noticed it when the `data()` method was invoked, right?"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "ce4c78dc",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2024-03-19T19:22:44.437452Z",
"iopub.status.busy": "2024-03-19T19:22:44.437070Z",
"iopub.status.idle": "2024-03-19T19:22:44.712479Z",
"shell.execute_reply": "2024-03-19T19:22:44.638851Z"
}
},
"outputs": [],
"source": [
"v2.resize(4)"
]
},
{
"cell_type": "markdown",
"id": "5b288647",
"metadata": {},
"source": [
"Of course, now the addresses are different."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "7bc0f61e",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2024-03-19T19:22:44.730869Z",
"iopub.status.busy": "2024-03-19T19:22:44.730501Z",
"iopub.status.idle": "2024-03-19T19:22:44.856252Z",
"shell.execute_reply": "2024-03-19T19:22:44.849461Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" and \n"
]
}
],
"source": [
"print(\"%s and %s\" %(v.data(), v2.data()))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}