Skip to content

Commit 2e60694

Browse files
committed
all draken vectors use SIMD to merge hashes
1 parent 9533cdf commit 2e60694

22 files changed

Lines changed: 634 additions & 165 deletions

examples/disk_reader_usage.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def example_basic():
2121
# Example 2: Stream large files without cache pollution
2222
def example_streaming():
2323
"""Process multiple large files efficiently."""
24-
large_files = ["planets-gw0.duckdb", "planets-gw1.duckdb"]
24+
large_files = ["tmp/planets-gw0.duckdb", "tmp/planets-gw1.duckdb"]
2525

2626
for filename in large_files:
2727
# Read and evict from cache to save memory

opteryx/__version__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# THIS FILE IS AUTOMATICALLY UPDATED DURING THE BUILD PROCESS
22
# DO NOT EDIT THIS FILE DIRECTLY
33

4-
__build__ = 1824
4+
__build__ = 1829
55
__author__ = "@joocer"
6-
__version__ = "0.26.2-beta.1824"
6+
__version__ = "0.26.2-beta.1829"
77

88
# Store the version here so:
99
# 1) we don't load dependencies by storing it in __init__.py
Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
1+
from libc.stdint cimport uint64_t
2+
3+
from opteryx.draken.core.buffers cimport DrakenArrayBuffer
14
from opteryx.draken.vectors.vector cimport Vector
25

6+
37
cdef class ArrayVector(Vector):
4-
cdef object _arr # Store the arrow array
8+
cdef DrakenArrayBuffer* ptr
9+
cdef object _child
10+
cdef bint owns_offsets
11+
cdef bint owns_null_bitmap
12+
cdef object _arrow_parent
13+
cdef object _arrow_offsets_buf
14+
cdef object _arrow_null_buf
15+
cdef object _arrow_child_array
16+
cdef object _child_arrow_type
17+
cdef bint _child_decode_utf8
18+
19+
cdef object _materialize_row(self, Py_ssize_t idx)
20+
cdef void hash_into(
21+
self,
22+
uint64_t[::1] out_buf,
23+
Py_ssize_t offset=*,
24+
uint64_t mix_constant=*,
25+
) except *
26+
527

628
cdef ArrayVector from_arrow(object array)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "opteryx"
3-
version = "0.26.2-beta.1824"
3+
version = "0.26.2-beta.1829"
44
description = "Query your data, where it lives"
55
requires-python = '>=3.11'
66
readme = {file = "README.md", content-type = "text/markdown"}

setup.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -691,9 +691,11 @@ def make_draken_extension(module_path, source_file, depends=None, language=None,
691691
list_ops_link_args.append("-pthread")
692692

693693
for ext in extensions:
694-
if ext.name == "opteryx.draken.vectors.int64_vector":
695-
ext.sources.append("src/cpp/simd_hash.cpp")
696-
break
694+
if ext.name.startswith("opteryx.draken.vectors."):
695+
if "src/cpp/simd_hash.cpp" not in ext.sources:
696+
ext.sources.append("src/cpp/simd_hash.cpp")
697+
ext.language = "c++"
698+
ext.extra_compile_args = CPP_COMPILE_FLAGS
697699

698700
extensions.append(
699701
Extension(

tests/__init__.py

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def test_example():
4545
run_tests()
4646
"""
4747

48+
import datetime
4849
import os
4950
import platform
5051
from functools import wraps
@@ -615,12 +616,12 @@ def create_duck_db(): # pragma: no cover
615616

616617
worker_id = os.environ.get('PYTEST_XDIST_WORKER', 'gw0')
617618

618-
if os.path.exists(f"planets-{worker_id}.duckdb"):
619+
if os.path.exists(f"tmp/planets-{worker_id}.duckdb"):
619620
return
620621

621622
import duckdb
622623

623-
conn = duckdb.connect(database=f"planets-{worker_id}.duckdb")
624+
conn = duckdb.connect(database=f"tmp/planets-{worker_id}.duckdb")
624625
cur = conn.cursor()
625626
try:
626627
cur.execute(CREATE_DATABASE)
@@ -736,6 +737,48 @@ def cast_dataset(dataset):
736737
opteryx.register_store("iceberg", IcebergConnector, catalog=catalog)
737738

738739
for dataset in ('planets', 'satellites', 'missions', 'astronauts'):
740+
if dataset == 'planets':
741+
from opteryx.virtual_datasets import planet_data
742+
743+
def snapshot_props(label, cutoff):
744+
props = {"temporal_version": label}
745+
if cutoff is not None:
746+
props["end_date"] = cutoff.isoformat()
747+
else:
748+
props["end_date"] = "current"
749+
return props
750+
751+
def load_planet_snapshot(cutoff):
752+
table_data = planet_data.read() if cutoff is None else planet_data.read(end_date=cutoff)
753+
return cast_dataset(table_data)
754+
755+
snapshots = [
756+
("pre_uranus", datetime.datetime(1781, 4, 25)),
757+
("pre_neptune", datetime.datetime(1846, 11, 12)),
758+
("pre_pluto", datetime.datetime(1930, 3, 12)),
759+
("modern", None),
760+
]
761+
762+
snapshot_label, cutoff = snapshots[0]
763+
snapshot_data = load_planet_snapshot(cutoff)
764+
table = catalog.create_table("iceberg.planets", schema=snapshot_data.schema)
765+
table.append(snapshot_data, snapshot_properties=snapshot_props(snapshot_label, cutoff))
766+
767+
latest_snapshot = snapshot_data
768+
for snapshot_label, cutoff in snapshots[1:]:
769+
snapshot_data = load_planet_snapshot(cutoff)
770+
table.overwrite(snapshot_data, snapshot_properties=snapshot_props(snapshot_label, cutoff))
771+
latest_snapshot = snapshot_data
772+
773+
expected_rows = latest_snapshot.num_rows
774+
del latest_snapshot
775+
del snapshot_data
776+
777+
iceberged = opteryx.query("SELECT * FROM iceberg.planets")
778+
assert iceberged.rowcount == expected_rows
779+
del iceberged # Free memory immediately
780+
continue
781+
739782
data = opteryx.query_to_arrow(f"SELECT * FROM ${dataset}")
740783
data = cast_dataset(data)
741784

@@ -751,4 +794,4 @@ def cast_dataset(dataset):
751794
del iceberged # Free memory immediately
752795

753796

754-
return catalog
797+
return catalog

tests/draken/vectors/test_jsonl_support.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import sys
1616
from pathlib import Path
1717

18-
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
18+
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
1919

2020
import pytest
2121
import pyarrow as pa

tests/draken/vectors/test_temporal_vectors.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import sys
1616
from pathlib import Path
1717

18-
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
18+
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
1919

2020
import pytest
2121
import pyarrow as pa
@@ -203,7 +203,7 @@ def test_array_nested_types():
203203
# List of strings
204204
string_list = pa.array([['a', 'b'], ['c'], None, ['d', 'e', 'f']], type=pa.list_(pa.string()))
205205
vec = Vector.from_arrow(string_list)
206-
assert vec.to_pylist() == [['a', 'b'], ['c'], None, ['d', 'e', 'f']]
206+
assert vec.to_pylist() == [[b'a', b'b'], [b'c'], None, [b'd', b'e', b'f']]
207207

208208
# List of floats
209209
float_list = pa.array([[1.1, 2.2], [3.3], None, [4.4]], type=pa.list_(pa.float64()))

tests/fuzzing/test_sql_fuzzer_compare_engines.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def test_sql_fuzzing_connector_comparisons(i):
152152
worker_id = os.environ.get('PYTEST_XDIST_WORKER', 'gw0')
153153

154154
import duckdb
155-
conn = duckdb.connect(database=f"planets-{worker_id}.duckdb")
155+
conn = duckdb.connect(database=f"tmp/planets-{worker_id}.duckdb")
156156
# Use test iteration number as seed for reproducibility
157157
seed = i + hash(worker_id) % 1000
158158
random.seed(seed)

tests/fuzzing/test_sql_fuzzer_connectors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def set_up_connections():
9494
opteryx.register_store("iceberg", IcebergConnector, catalog=iceberg_catalog)
9595
#opteryx.register_store("cockroach", SqlConnector, remove_prefix=True, connection=COCKROACH_CONNECTION)
9696
#opteryx.register_store("datastax", CqlConnector, remove_prefix=True, cluster=cluster)
97-
opteryx.register_store("duckdb", SqlConnector, remove_prefix=True, connection=f"duckdb:///planets-{worker_id}.duckdb")
97+
opteryx.register_store("duckdb", SqlConnector, remove_prefix=True, connection=f"duckdb:///tmp/planets-{worker_id}.duckdb")
9898
#opteryx.register_store("mongo", MongoDbConnector, database=MONGO_DATABASE, connection=MONGO_CONNECTION, remove_prefix=True)
9999
opteryx.register_store("sqlite", SqlConnector, remove_prefix=True, connection="sqlite:///testdata/sqlite/database.db")
100100

0 commit comments

Comments
 (0)