[{"id":38636,"web_url":"https://patchwork.libcamera.org/comment/38636/","msgid":"<20260423214117.GE3132278@killaraus.ideasonboard.com>","date":"2026-04-23T21:41:17","subject":"Re: [PATCH v2 26/42] libcamera: value_node: Add functions to erase\n\tchild nodes","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Thu, Apr 23, 2026 at 03:59:54PM +0200, Barnabás Pőcze wrote:\n> 2026. 04. 07. 17:34 keltezéssel, Laurent Pinchart írta:\n> > There will be a need to erase child nodes when implementing support for\n> > overriding configuration options. Add two erase() functions to the\n> > ValueNode class, mimicking the add() API.\n> > \n> > More erase() overloads could be added, for instance taking iterators as\n> > parameters, to improve efficiency. This should be considered later, when\n> > usage of the ValueNode class will expand, based on the actual usage\n> > patterns.\n> > \n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >   include/libcamera/internal/value_node.h |  3 ++\n> >   src/libcamera/value_node.cpp            | 51 +++++++++++++++++++++++++\n> >   2 files changed, 54 insertions(+)\n> > \n> > diff --git a/include/libcamera/internal/value_node.h b/include/libcamera/internal/value_node.h\n> > index 14c5e0eb0202..4e3757af7d09 100644\n> > --- a/include/libcamera/internal/value_node.h\n> > +++ b/include/libcamera/internal/value_node.h\n> > @@ -244,6 +244,9 @@ public:\n> >   \tValueNode *add(std::initializer_list<std::string_view> path,\n> >   \t\t       std::unique_ptr<ValueNode> &&child);\n> >   \n> > +\tvoid erase(const std::string &key);\n> > +\tvoid erase(std::initializer_list<std::string_view> path);\n> > +\n> >   private:\n> >   \tLIBCAMERA_DISABLE_COPY_AND_MOVE(ValueNode)\n> >   \n> > diff --git a/src/libcamera/value_node.cpp b/src/libcamera/value_node.cpp\n> > index 990e46d70358..8a1af13a5d6e 100644\n> > --- a/src/libcamera/value_node.cpp\n> > +++ b/src/libcamera/value_node.cpp\n> > @@ -621,4 +621,55 @@ ValueNode *ValueNode::add(std::initializer_list<std::string_view> path,\n> >   \treturn node;\n> >   }\n> >   \n> > +/**\n> > + * \\brief Erase a child node in a dictionary\n> > + * \\param[in] key The dictionary key\n> > + *\n> > + * Erase the child node referenced by \\a key in a dictionary node. If the \\a\n> > + * key does not exist, or if this node is not a dictionary, the function\n> > + * returns without performing any operation.\n> > + */\n> > +void ValueNode::erase(const std::string &key)\n> > +{\n> > +\tauto node = dictionary_.extract(key);\n> \n> `extract()` has an overload taking an iterator, I think that would make it\n> possible to use `std::string_view key` here. Or just `find()` + `erase(it)` at the end,\n> without any `extract()`.\n\nI'll for for find + erase.\n\n> > +\tif (node.empty())\n> > +\t\treturn;\n> > +\n> > +\tfor (auto iter = list_.begin(); iter != list_.end(); ++iter) {\n> \n> I feel that this loop deserves a \"\\todo Not ideal algorithm\".\n\nAck.\n\n> > +\t\tif (iter->value.get() != node.mapped())\n> > +\t\t\tcontinue;\n> > +\n> > +\t\tlist_.erase(iter);\n> > +\t\treturn;\n> > +\t}\n> > +}\n> > +\n> > +/**\n> > + * \\brief Erase the child node at the given path\n> > + * \\param[in] path The path\n> > + *\n> > + * Erase the child node at the given \\a path. If no child node exists for the\n> > + * path, the function returns without performing any operation.\n> > + */\n> > +void ValueNode::erase(std::initializer_list<std::string_view> path)\n> > +{\n> > +\tif (!path.size())\n> > +\t\treturn;\n> > +\n> > +\tValueNode *node = this;\n> > +\n> > +\tfor (const auto [i, name] : utils::enumerate(path)) {\n> > +\t\tif (i == path.size() - 1) {\n> > +\t\t\tnode->erase(std::string{ name });\n> > +\t\t\treturn;\n> > +\t\t}\n> > +\n> > +\t\tauto iter = node->dictionary_.find(name);\n> > +\t\tif (iter == node->dictionary_.end())\n> > +\t\t\treturn;\n> > +\n> > +\t\tnode = iter->second;\n> > +\t}\n> > +}\n> > +\n> >   } /* namespace libcamera */","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 46844BDCB5\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 23 Apr 2026 21:41:21 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 73E7062F59;\n\tThu, 23 Apr 2026 23:41:20 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 989BD62F56\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 23 Apr 2026 23:41:19 +0200 (CEST)","from killaraus.ideasonboard.com\n\t(2001-14ba-703d-e500--2a1.rev.dnainternet.fi\n\t[IPv6:2001:14ba:703d:e500::2a1])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 0F4DF2D7;\n\tThu, 23 Apr 2026 23:39:39 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"m6r6QVaS\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1776980380;\n\tbh=7j6AJlbYGt4UiUdg6j8KM+O3QGxy6GzNXr1WE9ReHG0=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=m6r6QVaSwtrcqGQUOPSLY0Wn4VTjAj72g4DY/zYhRXfyi7oyzrFk14vuolGccPSSL\n\tLdHpWg2z8QBReHIVueLto78bq6d3S9+x548yqygYEUF2dsSBLe0KMa+5Khl4aBxHbg\n\tFz7gwn9OAyFxzy7/jSk2dIraLFiI6yCvXC1g+8mo=","Date":"Fri, 24 Apr 2026 00:41:17 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v2 26/42] libcamera: value_node: Add functions to erase\n\tchild nodes","Message-ID":"<20260423214117.GE3132278@killaraus.ideasonboard.com>","References":"<20260407153427.1825999-1-laurent.pinchart@ideasonboard.com>\n\t<20260407153427.1825999-27-laurent.pinchart@ideasonboard.com>\n\t<c9265369-d8bc-4a76-bc93-c7563c4a8e32@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<c9265369-d8bc-4a76-bc93-c7563c4a8e32@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]