1 /* 2 * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2019, Haiku, Inc. 4 * All rights reserved. Distributed under the terms of the MIT license. 5 */ 6 #ifndef DATA_CONTAINER_H 7 #define DATA_CONTAINER_H 8 9 #include <OS.h> 10 11 struct vm_page; 12 class VMCache; 13 class AllocationInfo; 14 class Volume; 15 16 // Size of the DataContainer's small buffer. If it contains data up to this 17 // size, no blocks are allocated, but the small buffer is used instead. 18 // 16 bytes are for free, since they are shared with the block list. 19 // (actually even more, since the list has an initial size). 20 // I ran a test analyzing what sizes the attributes in my system have: 21 // size percentage bytes used in average 22 // <= 0 0.00 93.45 23 // <= 4 25.46 75.48 24 // <= 8 30.54 73.02 25 // <= 16 52.98 60.37 26 // <= 32 80.19 51.74 27 // <= 64 94.38 70.54 28 // <= 126 96.90 128.23 29 // 30 // For average memory usage it is assumed, that attributes larger than 126 31 // bytes have size 127, that the list has an initial capacity of 10 entries 32 // (40 bytes), that the block reference consumes 4 bytes and the block header 33 // 12 bytes. The optimal length is actually 35, with 51.05 bytes per 34 // attribute, but I conservatively rounded to 32. 35 static const size_t kSmallDataContainerSize = 32; 36 37 class DataContainer { 38 public: 39 DataContainer(Volume *volume); 40 virtual ~DataContainer(); 41 42 status_t InitCheck() const; 43 44 Volume *GetVolume() const { return fVolume; } 45 46 status_t Resize(off_t newSize); 47 off_t GetSize() const { return fSize; } 48 49 VMCache* GetCache(); 50 51 virtual status_t ReadAt(off_t offset, void *buffer, size_t size, 52 size_t *bytesRead); 53 virtual status_t WriteAt(off_t offset, const void *buffer, size_t size, 54 size_t *bytesWritten); 55 56 // debugging 57 void GetAllocationInfo(AllocationInfo &info); 58 59 private: 60 inline bool _RequiresCacheMode(size_t size); 61 inline bool _IsCacheMode() const; 62 status_t _SwitchToCacheMode(); 63 void _GetPages(off_t offset, off_t length, bool isWrite, vm_page** pages); 64 void _PutPages(off_t offset, off_t length, vm_page** pages, bool success); 65 status_t _DoCacheIO(const off_t offset, uint8* buffer, ssize_t length, 66 size_t* bytesProcessed, bool isWrite); 67 68 inline int32 _CountBlocks() const; 69 70 private: 71 Volume *fVolume; 72 off_t fSize; 73 VMCache* fCache; 74 uint8 fSmallBuffer[kSmallDataContainerSize]; 75 }; 76 77 #endif // DATA_CONTAINER_H 78