|
|
#pragma once
|
|
|
|
|
|
#include <vector>
|
|
|
#include <map>
|
|
|
#include <unordered_map>
|
|
|
#include <memory>
|
|
|
#include <algorithm>
|
|
|
#include "RingBuffer.h"
|
|
|
#include "NativeStream.h"
|
|
|
#include "StreamingTsvStream.h"
|
|
|
#include "SigmaView.h"
|
|
|
|
|
|
/**
|
|
|
* @brief 数据流管理类
|
|
|
*/
|
|
|
class StreamManager
|
|
|
{
|
|
|
public:
|
|
|
static StreamManager& Instance()
|
|
|
{
|
|
|
static StreamManager instance;
|
|
|
return instance;
|
|
|
}
|
|
|
|
|
|
/// pView 为 CSigmaView*(C# 传 IntPtr),importType 见 TableImportType;真流式:Write 时边解析边导入
|
|
|
int64_t Open(CSigmaView* pView, int importType, StreamError& error)
|
|
|
{
|
|
|
int64_t handle = m_nextId++;
|
|
|
m_streams[handle] = std::make_unique<StreamingTsvStream>(static_cast<CSigmaView*>(pView), importType);
|
|
|
|
|
|
error = StreamError::STREAM_OK;
|
|
|
return handle;
|
|
|
}
|
|
|
|
|
|
StreamError Write(int64_t handle, const void* data, size_t size)
|
|
|
{
|
|
|
auto it = m_streams.find(handle);
|
|
|
if (it == m_streams.end())
|
|
|
{
|
|
|
return HandleNotFound(handle);
|
|
|
}
|
|
|
|
|
|
try
|
|
|
{
|
|
|
it->second->Write(data, size);
|
|
|
return StreamError::STREAM_OK;
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
return StreamError::STREAM_WRITE_FAILED;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
StreamError Close(int64_t handle)
|
|
|
{
|
|
|
auto it = m_streams.find(handle);
|
|
|
if (it == m_streams.end())
|
|
|
{
|
|
|
return HandleNotFound(handle);
|
|
|
}
|
|
|
|
|
|
it->second->Complete();
|
|
|
m_streams.erase(it);
|
|
|
|
|
|
m_closedHandles.push(handle);
|
|
|
|
|
|
return StreamError::STREAM_OK;
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
using StreamMap = std::unordered_map<int64_t, std::unique_ptr<INativeStream>>;
|
|
|
|
|
|
static constexpr size_t RING_CAPCITY = 1024; // 2^10,最近关闭的 handle 数量上限
|
|
|
|
|
|
/// handle 不在 m_streams 时,区分“已关闭”与“无效 handle”
|
|
|
StreamError HandleNotFound(int64_t handle) const
|
|
|
{
|
|
|
if (m_closedHandles.contains(handle))
|
|
|
{
|
|
|
return StreamError::STREAM_ALREADY_CLOSED;
|
|
|
}
|
|
|
return StreamError::STREAM_INVALID_HANDLE;
|
|
|
}
|
|
|
|
|
|
StreamManager() = default;
|
|
|
|
|
|
StreamMap m_streams;
|
|
|
RingBuffer<int64_t, RING_CAPCITY> m_closedHandles;
|
|
|
int64_t m_nextId = 1;
|
|
|
}; |