Received: by 2002:a89:48b:0:b0:1f5:f2ab:c469 with SMTP id a11csp1403654lqd; Thu, 25 Apr 2024 14:47:11 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVvieI2ErsRtKm+Yhj06aBFcUa7HSPFSrhHDHo8B9HcVfnBLhWl4Bv7yA6ENsrQ5VGZvpT5l1ORKngB92N9xPdc5mjRu/GXbUModSCmVg== X-Google-Smtp-Source: AGHT+IHbMRDNewd/PbnTzUHTAGzgrk6ZUPQuFH2fugHC9OB/I2x1KqCB+J3YhoWSdf8+yWDBCQHX X-Received: by 2002:a05:6214:f21:b0:69b:6375:43f8 with SMTP id iw1-20020a0562140f2100b0069b637543f8mr1553189qvb.13.1714081631465; Thu, 25 Apr 2024 14:47:11 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1714081631; cv=pass; d=google.com; s=arc-20160816; b=ytQe5HGj93RYR0GIReSTSixrzUMoZty1EqZ+AyejeD/UnMFHCUNaa0hDaJXFk2tXiV 4h9JMVUj2UJNoHJAQWO5WAaezrhEqQ9eMEzXdyXLkxNtWh57zpFkcWGr32mXR4bu2jS1 lM1ZZ2ggmDTuWRPKEkewzG0BcgqUY0tILoM7yGcNCGCdk8RZmcNwi89oaJwJFJyIzMez 8yxL8B4QlINxSEJy+ps+V/i++7IcYBaolYsLOaXMZL3qrAExEe2U79vc42QovN7K0xw0 1NqRPHg4iHOOBvCpm5VCmv3Vw/dZvr+kaHdEZAChi3dq+g3ZYseARdUwv8iczTzdi4ID aK9g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:feedback-id:references :in-reply-to:message-id:subject:cc:from:to:date:dkim-signature; bh=97Q4StEMSnaGADHQavqUT0bLsHbHLwxhsBOtn/7AolM=; fh=jz9ZYdkZU3gmm8weL7yql0hVHDdlmm49R0ERliAl9tY=; b=Ec0GNs8dhwR2XL7ObO7rXEER4YjIaFUNlS04jFlPxZbNXkFyVJw+I/+2E2lLC8lPxA 2aL3I22GCO7hmSxl8j94C3Imsf4xkggkxmBDRqGhIqngYpNwSMy8MAyZYrRgnvVjaKdR wK1zDppPz3b1cbxp486OKLk8iqQ892CoWJccjk0CDvOzKm7ZCTCJ8hgpsENySwONXC1C rzm83Ke/y+TDzc9sO8QaHFKIoTbx8HsZUQqM5/hGgpz4JPFMH+Rxf8gtLGAKJeR/Qtp8 VdH6EuTENiuC4mF2s3Lg6UCM5+hvPM7HmiK/qbx2JiIGlcH2KWZOc6UrxuYNTnxpkaX5 aE3w==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b=Mge3iFRK; arc=pass (i=1 spf=pass spfdomain=proton.me dkim=pass dkdomain=proton.me dmarc=pass fromdomain=proton.me); spf=pass (google.com: domain of linux-kernel+bounces-159239-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-159239-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id s12-20020a0562140cac00b0069b3be4d218si18889120qvs.162.2024.04.25.14.47.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Apr 2024 14:47:11 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-159239-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b=Mge3iFRK; arc=pass (i=1 spf=pass spfdomain=proton.me dkim=pass dkdomain=proton.me dmarc=pass fromdomain=proton.me); spf=pass (google.com: domain of linux-kernel+bounces-159239-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-159239-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 3116C1C23E74 for ; Thu, 25 Apr 2024 21:47:07 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 00DDD15623B; Thu, 25 Apr 2024 21:46:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b="Mge3iFRK" Received: from mail-40133.protonmail.ch (mail-40133.protonmail.ch [185.70.40.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 048C71553A0 for ; Thu, 25 Apr 2024 21:45:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.40.133 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714081561; cv=none; b=hHCq18MXCJi7O0w9cBj/zTy3faLZLw1b+G4G86tzMKda3l39oYCKXsRbxI78kMI/0Tk9FDbuTUrIIhHGZZaaWW9izxy82g2VJkia7KXWxpG2GWzwbnZlieoL2+iZsRA+oQ9ty5KHPuDTvkTC57l+GxGX/Sl4MH7yV9PBdJbWEXU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714081561; c=relaxed/simple; bh=YKw6OAais4gM4JicLcbq2kNDKCivA0K/YpqzcFf016A=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pLDhjim9Kk9B31nV7eUz+Ij5En5GseMmmVPr/QbCzBOlwEbpHnUASM9NR0yamrrhSoys4wW0tTM6TUfMXA63rdfh4YWuDhraGEyKclfCl/boEMDGFnQkJs8XPIZWdOEIfF4s2BZAOMQklF6MX1cgf+c2V2xXCV/2Bf9lAlqr7/E= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me; spf=pass smtp.mailfrom=proton.me; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b=Mge3iFRK; arc=none smtp.client-ip=185.70.40.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=proton.me DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=protonmail; t=1714081557; x=1714340757; bh=97Q4StEMSnaGADHQavqUT0bLsHbHLwxhsBOtn/7AolM=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=Mge3iFRKSiHxa2lzkeSAmzi7MjU65qn/kz2OEqCeBlMYcml1Y9jkU5wpk6KM71UHe +jY6HrpERqdbmTONqVtNQsYJRNm3dkKoBFw94dzw9qzJK84x9WNh8jZ52D8H7iWerm ZwF1m5Q3AE+hcej/oYJgdRnRE0+3iQmVgV/ywv2J5cuxIT8Dt1679Yg3kgBj+QiK0j rZT6lQcHdtFNnOeKm1wKOeq0rXWn3Ms+7FMHr9tIhlVuh6Gi91WDR+MuSSdBPd5OtV DT0pAiuIE42FxLmWPxBEbdLN4kxe/l/J2JYCDDMDNhKZLieElRazx+gSvqR0kaM/rj i+QeS9JtMNBig== Date: Thu, 25 Apr 2024 21:45:54 +0000 To: Matt Gilbride , Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , =?utf-8?Q?Bj=C3=B6rn_Roy_Baron?= , Andreas Hindborg , Alice Ryhl , Greg Kroah-Hartman , =?utf-8?Q?Arve_Hj=C3=B8nnev=C3=A5g?= , Todd Kjos , Martijn Coenen , Joel Fernandes , Carlos Llamas , Suren Baghdasaryan , Christian Brauner From: Benno Lossin Cc: Rob Landley , Davidlohr Bueso , Michel Lespinasse , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v3 2/5] rust: rbtree: add `RBTreeIterator` Message-ID: In-Reply-To: <20240418-b4-rbtree-v3-2-323e134390ce@google.com> References: <20240418-b4-rbtree-v3-0-323e134390ce@google.com> <20240418-b4-rbtree-v3-2-323e134390ce@google.com> Feedback-ID: 71780778:user:proton X-Pm-Message-ID: e011ff89a2cfa0e9231357b446c0d1d40cbda54c Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 18.04.24 16:15, Matt Gilbride wrote: > @@ -188,6 +212,25 @@ pub fn try_reserve_node() -> Result> { > pub fn try_allocate_node(key: K, value: V) -> Result> { > Ok(Self::try_reserve_node()?.into_node(key, value)) > } > + > + /// Returns an iterator over the tree nodes, sorted by key. > + pub fn iter(&self) -> RBTreeIterator<'_, K, V> { > + RBTreeIterator { There is a missing `INVARIANT` comment here justifying the invariants of `RBTreeIterator`. > + _tree: PhantomData, > + // SAFETY: `root` is valid as it's embedded in `self` and we= have a valid `self`. > + next: unsafe { bindings::rb_first(&self.root) }, > + } > + } > + > + /// Returns an iterator over the keys of the nodes in the tree, in s= orted order. > + pub fn keys(&self) -> impl Iterator { > + self.iter().map(|(k, _)| k) > + } > + > + /// Returns an iterator over the values of the nodes in the tree, so= rted by key. > + pub fn values(&self) -> impl Iterator { > + self.iter().map(|(_, v)| v) > + } > } >=20 > impl RBTree > @@ -373,6 +416,56 @@ fn drop(&mut self) { > } > } >=20 > +impl<'a, K, V> IntoIterator for &'a RBTree { > + type Item =3D (&'a K, &'a V); > + type IntoIter =3D RBTreeIterator<'a, K, V>; > + > + fn into_iter(self) -> Self::IntoIter { > + self.iter() > + } > +} > + > +/// An iterator over the nodes of a [`RBTree`]. > +/// > +/// Instances are created by calling [`RBTree::iter`]. > +/// > +/// # Invariants > +/// - `self.next` is a valid pointer. > +/// - `self.next` points to a node stored inside of a valid `RBTree`. > +pub struct RBTreeIterator<'a, K, V> { > + _tree: PhantomData<&'a RBTree>, > + next: *mut bindings::rb_node, > +} > + > +// SAFETY: The [`RBTreeIterator`] gives out immutable references to K an= d V, so it has the same > +// thread safety requirements as immutable references. > +unsafe impl<'a, K: Sync, V: Sync> Send for RBTreeIterator<'a, K, V> {} The bounds on `K` and `V` look like typos to me. They should be `Send` instead. > + > +// SAFETY: The [`RBTreeIterator`] gives out immutable references to K an= d V, so it has the same > +// thread safety requirements as immutable references. > +unsafe impl<'a, K: Sync, V: Sync> Sync for RBTreeIterator<'a, K, V> {} > + > +impl<'a, K, V> Iterator for RBTreeIterator<'a, K, V> { > + type Item =3D (&'a K, &'a V); > + > + fn next(&mut self) -> Option { > + if self.next.is_null() { > + return None; > + } > + > + // SAFETY: By the type invariant of `Self`, all non-null `rb_nod= e` pointers stored in `self` This is not an invariant of `Self`, but rather `RBTree` and `self` should be "`RBtree`s". --=20 Cheers, Benno > + // point to the links field of `Node` objects. > + let cur =3D unsafe { container_of!(self.next, Node, links)= }; > + > + // SAFETY: `self.next` is a valid tree node by the type invarian= ts. > + self.next =3D unsafe { bindings::rb_next(self.next) }; > + > + // SAFETY: By the same reasoning above, it is safe to dereferenc= e the node. Additionally, > + // it is ok to return a reference to members because the iterato= r must outlive it. > + Some(unsafe { (&(*cur).key, &(*cur).value) }) > + } > +} > + > /// A memory reservation for a red-black tree node. > /// > /// It contains the memory needed to hold a node that can be inserted in= to a red-black tree. One >=20 > -- > 2.44.0.769.g3c40516874-goog >=20