Coverage Report

Created: 2026-08-07 05:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exec/spill/spill_file.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "exec/spill/spill_file.h"
19
20
#include <glog/logging.h>
21
22
#include <filesystem>
23
#include <memory>
24
#include <utility>
25
26
#include "exec/spill/spill_file_manager.h"
27
#include "exec/spill/spill_file_reader.h"
28
#include "exec/spill/spill_file_writer.h"
29
#include "io/fs/local_file_system.h"
30
#include "runtime/exec_env.h"
31
#include "runtime/query_context.h"
32
#include "runtime/runtime_profile.h"
33
#include "runtime/runtime_state.h"
34
#include "util/debug_points.h"
35
36
namespace doris {
37
SpillFile::SpillFile(SpillDataDir* data_dir, std::string relative_path)
38
344
        : _data_dir(data_dir),
39
344
          _spill_dir(data_dir->get_spill_data_path() + "/" + std::move(relative_path)) {}
40
41
344
SpillFile::~SpillFile() {
42
344
    gc();
43
344
}
44
45
484
void SpillFile::gc() {
46
484
    bool exists = false;
47
484
    auto status = io::global_local_filesystem()->exists(_spill_dir, &exists);
48
484
    if (status.ok() && exists) {
49
        // Delete spill directory directly instead of moving it to a GC directory.
50
        // This simplifies cleanup and avoids retaining spill data under a GC path.
51
266
        status = io::global_local_filesystem()->delete_directory(_spill_dir);
52
266
        DBUG_EXECUTE_IF("fault_inject::spill_file::gc", {
53
266
            status = Status::Error<INTERNAL_ERROR>("fault_inject spill_file gc failed");
54
266
        });
55
266
        if (!status.ok()) {
56
0
            LOG_EVERY_T(WARNING, 1) << fmt::format("failed to delete spill data, dir {}, error: {}",
57
0
                                                   _spill_dir, status.to_string());
58
0
        }
59
266
    }
60
    // Decrease spill data usage even if per-file cleanup failed. QueryContext teardown deletes the
61
    // whole query spill directory and retains failures for later retries.
62
484
    _data_dir->update_spill_data_usage(-_total_written_bytes);
63
484
    _total_written_bytes = 0;
64
484
}
65
66
Status SpillFile::create_writer(RuntimeState* state, RuntimeProfile* profile,
67
313
                                SpillFileWriterSPtr& writer) {
68
313
    writer = std::make_shared<SpillFileWriter>(shared_from_this(), state, profile, _data_dir,
69
313
                                               _spill_dir);
70
    // _active_writer is set in SpillFileWriter constructor via the shared_ptr
71
313
    return Status::OK();
72
313
}
73
74
191
SpillFileReaderSPtr SpillFile::create_reader(RuntimeState* state, RuntimeProfile* profile) const {
75
    // It's a programming error to create a reader while a writer is still active.
76
191
    DCHECK(_active_writer == nullptr) << "create_reader() called while writer still active";
77
191
    return std::make_shared<SpillFileReader>(state, profile, _spill_dir, _part_count);
78
191
}
79
80
297
void SpillFile::finish_writing() {
81
297
    _ready_for_reading = true;
82
    // writer finished; clear active writer pointer
83
297
    _active_writer = nullptr;
84
297
}
85
86
721
void SpillFile::update_written_bytes(int64_t delta_bytes) {
87
721
    _total_written_bytes += delta_bytes;
88
721
}
89
90
261
void SpillFile::increment_part_count() {
91
261
    ++_part_count;
92
261
}
93
94
} // namespace doris