[llvm] [ADT] Introduce EytzingerTableSpan (PR #208885)
David Li via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 11 13:13:36 PDT 2026
================
@@ -0,0 +1,68 @@
+//===- Eytzinger.h - Eytzinger Search Tree Span -----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines the EytzingerTableSpan class, a non-owning view of a
+/// buffer formatted as a complete binary search tree in Eytzinger
+/// (breadth-first) order.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_EYTZINGER_H
+#define LLVM_ADT_EYTZINGER_H
+
+#include "llvm/ADT/bit.h"
+#include <cassert>
+#include <cstddef>
+#include <optional>
+
+namespace llvm {
+
+/// Non-owning view of a buffer formatted as a complete binary search tree in
+/// Eytzinger (breadth-first) order.
+template <typename T> class EytzingerTableSpan {
+public:
+ EytzingerTableSpan() = default;
+ EytzingerTableSpan(const T *Data, size_t NumEntries)
+ : Data(Data), NumEntries(NumEntries) {}
+
+ [[nodiscard]] const T *data() const { return Data; }
+ [[nodiscard]] bool empty() const { return !Data || NumEntries == 0; }
+ [[nodiscard]] size_t size() const { return NumEntries; }
+ [[nodiscard]] const T &operator[](size_t Idx) const {
+ assert(Idx < NumEntries && "Index out of bounds");
+ return Data[Idx];
+ }
+
+ /// Search this Eytzinger table for Target using branchless binary search.
+ /// Returns the 0-based array index if found.
+ ///
+ /// KeyT enables heterogeneous lookups, allowing callers to search tables of
+ /// endian-specific wrappers (e.g., support::ulittle64_t) using native integer
+ /// keys without explicit conversions at the call site.
+ template <typename KeyT = T>
+ [[nodiscard]] std::optional<size_t> findIndex(const KeyT &Target) const {
+ if (empty())
+ return std::nullopt;
+ size_t K = 1;
+ while (K <= NumEntries)
+ K = 2 * K + (Data[K - 1] < Target);
+ K >>= llvm::countr_one(K) + 1;
----------------
david-xl wrote:
The bit manipulation code is hard to read. Does this version work?
size_t i = 0;
while (i < n) {
if (Data[i] == target)
return i;
i = 2 * i + 1 + (Data[i] < target);
}
https://github.com/llvm/llvm-project/pull/208885
More information about the llvm-commits
mailing list