yiguolei commented on code in PR #69635:
URL: https://github.com/apache/doris/pull/69635#discussion_r4522173834


##########
be/src/exec/spill/spill_data_dir.h:
##########
@@ -0,0 +1,181 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include <gen_cpp/Types_types.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <mutex>
+#include <string>
+
+#include "common/status.h"
+#include "io/fs/file_system.h"
+
+namespace doris {
+
+template <typename T>
+class AtomicGauge;
+using IntGauge = AtomicGauge<int64_t>;
+class MetricEntity;
+template <typename T>
+class AtomicCounter;
+using IntAtomicCounter = AtomicCounter<int64_t>;
+
+/// A spill store: one local disk (LocalSpillDataDir) or the object storage of 
a cloud storage
+/// vault (RemoteSpillDataDir). The IO of a spill file goes through the file 
system pinned in its
+/// SpillFile when it was created, so that SpillFile / SpillFileWriter / 
SpillFileReader share one
+/// code path for both kinds and a remote file stays on its vault. The base 
class owns
+/// what both kinds share: the spill root, the byte accounting against a 
limit, and the metrics.
+class SpillDataDir {
+public:
+    virtual ~SpillDataDir();
+
+    virtual Status init() = 0;
+
+    virtual bool is_remote() const { return false; }
+
+    /// Whether the store can be used. Local stores are always ready; a remote 
store becomes
+    /// ready once its storage vault is bound.
+    virtual bool ready() const { return true; }
+
+    /// Current file system of this store, used for new spill files and local 
query directories.
+    /// Existing files keep the one they were created on. Remote stores return 
nullptr until ready.
+    virtual io::FileSystemSPtr fs() const = 0;
+
+    /// Refresh capacity and the byte limit from the disk / the configs.
+    virtual Status update_capacity() = 0;
+
+    /// Disk usage ratio after adding `incoming_data_size`, used to spread 
spill over local
+    /// disks; object storage reports 0.
+    virtual double get_disk_usage(int64_t incoming_data_size) const { return 
0.0; }
+
+    const std::string& path() const { return _path; }
+
+    /// Root of spill data of this store, optionally for one query:
+    ///   local:  {path}/spill[/query_id]
+    ///   remote: spill/{ip}_{port}[/query_id]   (relative to the vault prefix)
+    std::string get_spill_data_path(const std::string& query_id = "") const;
+
+    TStorageMedium::type storage_medium() const { return _storage_medium; }
+
+    // check if the capacity reach the limit after adding the incoming data
+    // return true if limit reached, otherwise, return false.
+    bool reach_capacity_limit(int64_t incoming_data_size);
+
+    /// Atomically check the capacity limit and account `bytes` as used. 
Returns
+    /// DISK_REACH_CAPACITY_LIMIT without accounting when the limit would be 
exceeded.
+    /// With force=true the bytes are accounted without checking (used for 
part footers so
+    /// that an open part can always be closed).
+    Status try_reserve(int64_t bytes, bool force = false);
+
+    /// Give back bytes accounted by try_reserve().
+    void release(int64_t bytes) { update_spill_data_usage(-bytes); }
+
+    void update_spill_data_usage(int64_t incoming_data_size);
+
+    int64_t get_spill_data_bytes();
+
+    /// Logical SpillFile lifecycle counters (not physical parts or 
external-writer files).
+    /// Deletion is counted once cleanup succeeds, including an unwritten 
file's no-op cleanup.
+    void record_spill_file_created();
+    void record_spill_file_deleted(size_t count = 1);
+
+    // Bytes of remote objects that exist or may exist: successfully closed 
parts, plus the upper
+    // bound of a part whose close failed until it is reconciled. Capacity 
reservations remain
+    // tracked separately in get_spill_data_bytes() and must not be published 
as persisted usage.
+    virtual void record_persisted_bytes(int64_t bytes) {}
+    virtual void release_persisted_bytes(int64_t bytes) {}
+    virtual int64_t get_persisted_bytes() { return 0; }
+
+    int64_t get_spill_data_limit();
+
+    std::string debug_string();
+
+protected:
+    /// @param path         identifies the store (a directory for local disks, 
"s3:{vault}" for
+    ///                     object storage); used in logs, metrics and error 
messages.
+    /// @param spill_root   initial spill root; a remote store fills it in 
when it is bound.
+    /// @param metric_path  value of the "path" label of the metric entity.
+    SpillDataDir(std::string path, std::string spill_root, const std::string& 
metric_path,
+                 int64_t capacity_bytes, TStorageMedium::type storage_medium);
+
+    /// Called with _mutex held.
+    virtual bool _reach_limit_unlocked(int64_t incoming_data_size) = 0;

Review Comment:
   如果有这种lock 的假定,那么他的方法参数里传递一个const 的lock 进来



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to