|
420 | 420 | %% that will be included in snapshots written to new segments |
421 | 421 | readers_counter_fun = fun(_) -> ok end :: function(), |
422 | 422 | shared :: atomics:atomics_ref(), |
423 | | - filter_size = ?DEFAULT_FILTER_SIZE :: osiris_bloom:filter_size() |
| 423 | + filter_size = ?DEFAULT_FILTER_SIZE :: osiris_bloom:filter_size(), |
| 424 | + compression :: undefined | {zstd, zstd:context()} |
424 | 425 | }). |
425 | 426 | -record(ra, |
426 | 427 | {size = ?HEADER_SIZE_B + ?DEFAULT_FILTER_SIZE :: non_neg_integer(), |
@@ -1064,14 +1065,22 @@ init_data_reader_at(ChunkId, FilePos, File, |
1064 | 1065 | Cnt = make_counter(Config), |
1065 | 1066 | counters:put(Cnt, ?C_OFFSET, ChunkId - 1), |
1066 | 1067 | CountersFun(1), |
| 1068 | + Compression = case Config of |
| 1069 | + #{compression := zstd} -> |
| 1070 | + {ok, Ctx} = zstd:context(compress), |
| 1071 | + {zstd, Ctx}; |
| 1072 | + _ -> |
| 1073 | + undefined |
| 1074 | + end, |
1067 | 1075 | {ok, |
1068 | 1076 | #?MODULE{cfg = |
1069 | 1077 | #cfg{directory = Dir, |
1070 | 1078 | counter = Cnt, |
1071 | 1079 | counter_id = counter_id(Config), |
1072 | 1080 | name = Name, |
1073 | 1081 | readers_counter_fun = CountersFun, |
1074 | | - shared = Shared |
| 1082 | + shared = Shared, |
| 1083 | + compression = Compression |
1075 | 1084 | }, |
1076 | 1085 | mode = |
1077 | 1086 | #read{type = data, |
@@ -1716,7 +1725,8 @@ send_file(Sock, State) -> |
1716 | 1725 | {error, term()} | |
1717 | 1726 | {end_of_stream, state()}. |
1718 | 1727 | send_file(Sock, |
1719 | | - #?MODULE{mode = #read{type = RType, |
| 1728 | + #?MODULE{cfg = #cfg{compression = Compression}, |
| 1729 | + mode = #read{type = RType, |
1720 | 1730 | chunk_selector = Selector, |
1721 | 1731 | transport = Transport, |
1722 | 1732 | filter_size = RaFs}} = State0, |
@@ -1755,19 +1765,32 @@ send_file(Sock, |
1755 | 1765 | FrameHeader = Callback(Header, ToSend + byte_size(HeaderData)), |
1756 | 1766 | case ra_read(DataPos, ToSend, Ra) of |
1757 | 1767 | Data when byte_size(Data) == ToSend -> |
1758 | | - case send(Transport, Sock, [FrameHeader, HeaderData, Data]) of |
| 1768 | + case send(Transport, Compression, Sock, [FrameHeader, HeaderData, Data]) of |
1759 | 1769 | ok -> |
1760 | 1770 | State = State1#?MODULE{mode = Read}, |
1761 | 1771 | {ok, State}; |
1762 | 1772 | Err -> |
1763 | 1773 | Err |
1764 | 1774 | end; |
| 1775 | + _ when Compression =/= undefined -> |
| 1776 | + case file:pread(Fd, DataPos, ToSend) of |
| 1777 | + {ok, Data} -> |
| 1778 | + case send(Transport, Compression, Sock, [FrameHeader, HeaderData, Data]) of |
| 1779 | + ok -> |
| 1780 | + State = State1#?MODULE{mode = Read}, |
| 1781 | + {ok, State}; |
| 1782 | + Err -> |
| 1783 | + Err |
| 1784 | + end; |
| 1785 | + Err -> |
| 1786 | + Err |
| 1787 | + end; |
1765 | 1788 | _ -> |
1766 | 1789 | %% the read ahead buffer could not satisfy the |
1767 | 1790 | %% data read |
1768 | | - case send(Transport, Sock, [FrameHeader, HeaderData]) of |
| 1791 | + case send(Transport, Compression, Sock, [FrameHeader, HeaderData]) of |
1769 | 1792 | ok -> |
1770 | | - case sendfile(Transport, Fd, Sock, |
| 1793 | + case sendfile(Transport, Compression, Fd, Sock, |
1771 | 1794 | DataPos, ToSend) of |
1772 | 1795 | ok -> |
1773 | 1796 | State = State1#?MODULE{mode = Read}, |
@@ -2526,30 +2549,40 @@ max_segment_size_reached( |
2526 | 2549 | CurrentSizeBytes >= MaxSizeBytes orelse |
2527 | 2550 | CurrentSizeChunks >= MaxSizeChunks. |
2528 | 2551 |
|
2529 | | -sendfile(_Transport, _Fd, _Sock, _Pos, 0) -> |
| 2552 | +sendfile(_Transport, _Compression, _Fd, _Sock, _Pos, 0) -> |
2530 | 2553 | ok; |
2531 | | -sendfile(tcp = Transport, Fd, Sock, Pos, ToSend) -> |
| 2554 | +sendfile(tcp = Transport, undefined, Fd, Sock, Pos, ToSend) -> |
2532 | 2555 | case file:sendfile(Fd, Sock, Pos, ToSend, []) of |
2533 | 2556 | {ok, 0} -> |
2534 | 2557 | %% TODO add counter for this? |
2535 | | - sendfile(Transport, Fd, Sock, Pos, ToSend); |
| 2558 | + sendfile(Transport, undefined, Fd, Sock, Pos, ToSend); |
2536 | 2559 | {ok, BytesSent} -> |
2537 | | - sendfile(Transport, Fd, Sock, Pos + BytesSent, ToSend - BytesSent); |
| 2560 | + sendfile(Transport, undefined, Fd, Sock, Pos + BytesSent, ToSend - BytesSent); |
2538 | 2561 | {error, _} = Err -> |
2539 | 2562 | Err |
2540 | 2563 | end; |
2541 | | -sendfile(ssl, Fd, Sock, Pos, ToSend) -> |
| 2564 | +sendfile(Transport, Compression, Fd, Sock, Pos, ToSend) -> |
2542 | 2565 | case file:pread(Fd, Pos, ToSend) of |
2543 | 2566 | {ok, Data} -> |
2544 | | - ssl:send(Sock, Data); |
| 2567 | + send(Transport, Compression, Sock, Data); |
2545 | 2568 | {error, _} = Err -> |
2546 | 2569 | Err |
2547 | 2570 | end. |
2548 | 2571 |
|
2549 | | -send(tcp, Sock, Data) -> |
2550 | | - gen_tcp:send(Sock, Data); |
2551 | | -send(ssl, Sock, Data) -> |
2552 | | - ssl:send(Sock, Data). |
| 2572 | +send(tcp, Compression, Sock, Data) -> |
| 2573 | + gen_tcp:send(Sock, compress_data(Compression, Data)); |
| 2574 | +send(ssl, Compression, Sock, Data) -> |
| 2575 | + ssl:send(Sock, compress_data(Compression, Data)). |
| 2576 | + |
| 2577 | +compress_data({zstd, Ctx}, Data) -> |
| 2578 | + CompressedData = zstd:compress(Data, Ctx), |
| 2579 | + Header = <<?COMPRESSED_MAGIC:4/unsigned, |
| 2580 | + ?COMPRESSED_VERSION:4/unsigned, |
| 2581 | + 3:8/unsigned, |
| 2582 | + (iolist_size(CompressedData)):32/unsigned>>, |
| 2583 | + [Header | CompressedData]; |
| 2584 | +compress_data(undefined, Data) -> |
| 2585 | + Data. |
2553 | 2586 |
|
2554 | 2587 | last_timestamp_in_index_file(IdxFile) -> |
2555 | 2588 | case file:open(IdxFile, [raw, binary, read]) of |
|
0 commit comments