From 8782472fda71c2ebcea8755275491e95be25b5ac Mon Sep 17 00:00:00 2001 From: John Lyu Date: Wed, 12 Aug 2026 18:13:42 +0800 Subject: [PATCH 1/2] test: cover FileFeatureStorage overwrite behavior --- .../test_file_feature_storage.py | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 tests/storage_tests/test_file_feature_storage.py diff --git a/tests/storage_tests/test_file_feature_storage.py b/tests/storage_tests/test_file_feature_storage.py new file mode 100644 index 00000000000..332df55efb0 --- /dev/null +++ b/tests/storage_tests/test_file_feature_storage.py @@ -0,0 +1,65 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +import numpy as np + +from qlib.data.storage.file_storage import FileFeatureStorage + + +class LocalFileFeatureStorage(FileFeatureStorage): + """FileFeatureStorage backed by a test-provided path.""" + + def __init__(self, uri): + super().__init__(instrument="TEST", field="close", freq="day") + self._uri = uri + + @property + def uri(self): + return self._uri + + +def test_write_overwrites_values_in_place(tmp_path): + storage = LocalFileFeatureStorage(tmp_path / "close.day.bin") + storage.write([10.0, 11.0, 12.0], index=5) + + storage.write([20.0, 21.0], index=6) + + assert storage.start_index == 5 + assert storage.end_index == 7 + np.testing.assert_array_equal(storage[:].values, [10.0, 20.0, 21.0]) + np.testing.assert_array_equal( + np.fromfile(storage.uri, dtype=" Date: Wed, 12 Aug 2026 18:13:45 +0800 Subject: [PATCH 2/2] perf: overwrite file features in place --- qlib/data/storage/file_storage.py | 59 ++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/qlib/data/storage/file_storage.py b/qlib/data/storage/file_storage.py index e2bc5c3679a..865e994e4ee 100644 --- a/qlib/data/storage/file_storage.py +++ b/qlib/data/storage/file_storage.py @@ -303,30 +303,47 @@ def write(self, data_array: Union[List, np.ndarray], index: int = None) -> None: "if you need to clear the FeatureStorage, please execute: FeatureStorage.clear" ) return - if not self.uri.exists(): - # write + data_array = np.asarray(data_array, dtype=" storage_end_index: + gap = np.full(index - storage_end_index - 1, np.nan, dtype="= storage_start_index: + # Values are fixed-width float32, so an overlapping write can update + # the affected bytes directly without loading and rewriting the file. + with self.uri.open("rb+") as fp: + fp.seek(4 * (index - storage_start_index + 1)) + data_array.tofile(fp) else: - if index is None or index > self.end_index: - # append - index = 0 if index is None else index - with self.uri.open("ab+") as fp: - np.hstack([[np.nan] * (index - self.end_index - 1), data_array]).astype(" Union[int, None]: