xref: /haiku/src/add-ons/kernel/file_systems/ramfs/DataContainer.h (revision 9e54316c528c34ee76f4d0d21150ceadd031c4de)
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