1010
1111#include <aws/io/future.h>
1212#include <aws/io/stream.h>
13+ #ifdef _WIN32
14+ # include <windows.h>
15+ #else
16+ # include <errno.h>
17+ # include <sys/mman.h>
18+ # include <sys/stat.h>
19+ # include <unistd.h>
20+ #endif /* _WIN32 */
21+
22+ #include <fcntl.h>
23+ #include <stdio.h>
24+ #include <stdlib.h>
1325
1426#include <errno.h>
1527
@@ -252,6 +264,12 @@ struct aws_s3_mmap_part_streaming_input_stream_impl {
252264
253265 struct aws_mmap_context * mmap_context ;
254266 size_t offset ;
267+
268+ long page_size ;
269+ void * page_address ;
270+ int page_offset ;
271+ size_t page_load_length ;
272+
255273 size_t total_length ;
256274 size_t length_read ;
257275};
@@ -274,18 +292,39 @@ static int s_aws_s3_mmap_part_streaming_input_stream_read(struct aws_input_strea
274292 size_t read_length =
275293 aws_min_size (dest -> capacity - dest -> len , test_input_stream -> total_length - test_input_stream -> length_read );
276294
277- void * content = aws_mmap_context_map_content (
278- test_input_stream -> mmap_context ,
279- read_length ,
280- test_input_stream -> offset + test_input_stream -> length_read ,
281- & out_start_addr );
282-
295+ if (test_input_stream -> page_offset == -1 ) {
296+ test_input_stream -> page_load_length = aws_min_size (
297+ test_input_stream -> page_size , test_input_stream -> total_length - test_input_stream -> length_read );
298+ size_t offset = test_input_stream -> offset + test_input_stream -> length_read ;
299+ long page_size = test_input_stream -> page_size ;
300+ uint64_t number_pages = offset / page_size ;
301+ uint64_t page_starts_offset = page_size * number_pages ;
302+ uint64_t in_page_offset = offset - page_starts_offset ;
303+
304+ void * mapped_data = mmap (
305+ test_input_stream -> page_address ,
306+ test_input_stream -> page_load_length ,
307+ PROT_READ ,
308+ MAP_SHARED ,
309+ aws_mmap_context_get_fd (test_input_stream -> mmap_context ),
310+ page_starts_offset );
311+ test_input_stream -> page_address = mapped_data ;
312+ test_input_stream -> page_offset = in_page_offset ;
313+ }
314+ read_length = aws_min_size (read_length , test_input_stream -> page_size - test_input_stream -> page_offset );
315+ struct aws_byte_cursor page_cursor =
316+ aws_byte_cursor_from_array ((const uint8_t * )test_input_stream -> page_address , test_input_stream -> page_size );
317+ aws_byte_cursor_advance (& page_cursor , test_input_stream -> page_offset );
318+ page_cursor .len = read_length ;
319+ int rt = aws_byte_buf_append (dest , & page_cursor );
320+ test_input_stream -> page_offset += read_length ;
283321 test_input_stream -> length_read += read_length ;
284- AWS_FATAL_ASSERT (test_input_stream -> length_read <= test_input_stream -> total_length );
285- struct aws_byte_cursor content_cursor = aws_byte_cursor_from_array ((const uint8_t * )content , read_length );
286- int rt = aws_byte_buf_append (dest , & content_cursor );
287- /* Release the content */
288- rt |= aws_mmap_context_unmap_content (out_start_addr , read_length );
322+
323+ if (test_input_stream -> page_offset == test_input_stream -> page_load_length ) {
324+ /* unmap the data */
325+ munmap (test_input_stream -> page_address , test_input_stream -> page_load_length );
326+ test_input_stream -> page_offset = -1 ;
327+ }
289328
290329 return rt ;
291330}
@@ -350,5 +389,8 @@ struct aws_input_stream *aws_input_stream_new_from_mmap_context(
350389 mmap_input_stream -> offset = offset ;
351390 mmap_input_stream -> length_read = 0 ;
352391 mmap_input_stream -> mmap_context = mmap_context ;
392+ mmap_input_stream -> page_size = sysconf (_SC_PAGE_SIZE );
393+ mmap_input_stream -> page_address = NULL ;
394+ mmap_input_stream -> page_offset = -1 ;
353395 return & mmap_input_stream -> base ;
354396}
0 commit comments