aboutsummaryrefslogtreecommitdiff
path: root/src/myriad.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/myriad.h')
-rw-r--r--src/myriad.h144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/myriad.h b/src/myriad.h
new file mode 100644
index 0000000..772729f
--- /dev/null
+++ b/src/myriad.h
@@ -0,0 +1,144 @@
1/*
2 * Copyright (C) 2007-2008 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_MYRIAD_H
9#define BU_MYRIAD_H
10
11#include <stdint.h>
12#include "bu/bitstring.h"
13#include "bu/exceptionbase.h"
14#include "bu/array.h"
15
16namespace Bu
17{
18 class Stream;
19 class MyriadStream;
20
21 subExceptionDecl( MyriadException )
22
23 /**
24 * Numerically Indexed Data Streams. This is a working name so I can
25 * actually get some code written instead of agonizing over the name.
26 *
27 * This is a system for creating streams that contain other streams in
28 * a flexible block-allocated system.
29 *
30 * Header format is as follows:
31 *
32 * MMMMvBssssSSSS*
33 * M = Magic number
34 * v = version number
35 * B = Bits per int
36 * s = Blocksize in bytes
37 * S = Number of Streams
38 *
39 * The * represents the Stream headers, one per stream, as follows:
40 * IIIIssss$
41 * I = Id number of the stream
42 * s = size of stream in bytes
43 *
44 * The $ represents the Block headers, one per used block, as follows:
45 * IIII
46 * I = Index of the block
47 *
48 * The stream/block data is interleaved in the header, so all blocks stored
49 * with one stream are together. The block headers are in order, and the
50 * data in them is required to be "solid" you cannot fill partial blocks
51 * mid-way through a stream.
52 *
53 * The initial block starts with the nids header, and is both the zero block
54 * and the zero stream. For now, the minimum block size is the size needed
55 * to store the base header, the zero stream header, and the first two
56 * blocks of the zero stream, so 30 bytes. Since it's reccomended to use
57 * a size that will fit evenly into filesystem blocks, then a size of 32 is
58 * probably the smallest reccomended size because all powers of two equal
59 * to or greater than 32 are evenly divisible by 32.
60 *
61 * I have had a thought that if the block size were smaller than 42 bytes
62 * the header would consume the first N blocks where N * block size is
63 * enough space to house the initial header, the first stream header, and
64 * the first N block headers. This, of course, causes you to hit an
65 * infinite header if the block size is small enough.
66 */
67 class Myriad
68 {
69 friend class MyriadStream;
70 public:
71 Myriad( Bu::Stream &sStore );
72 virtual ~Myriad();
73
74 /**
75 * Initialize this object based on the data already in the assosiated
76 * stream. This will be called automatically for you if you forget,
77 * but if you want to pre-initialize for some reason, just call this
78 * once before you actually start doing anything with your Myriad.
79 */
80 void initialize();
81
82 /**
83 * Create a new Myriad system in the assosiated stream. This should be
84 * used carefully, it will destroy all data already within the stream.
85 * More options will probably be added soon.
86 */
87 void initialize( int iBlockSize, int iPreAllocate=1 );
88
89 /**
90 * Create a new stream within the Myriad system. The ID of the new stream
91 * is returned.
92 */
93 int createStream( int iPreAllocate=1 );
94
95 /**
96 * Delete a stream that's already within the Myriad.
97 */
98 void deleteStream( int iID );
99
100 /**
101 * Return a new Stream object assosiated with the given stream ID.
102 */
103 MyriadStream openStream( int iID );
104
105 int getBlockSize();
106 int getNumBlocks();
107 int getNumUsedBlocks();
108 int getBlockOverhead();
109
110 /**
111 * Syncronize the header data, etc. with the storage stream. It's not
112 * a bad idea to call this periodically.
113 */
114 void sync();
115
116 private:
117 enum
118 {
119 blockUnused = 0xFFFFFFFFUL
120 };
121
122 void updateHeader();
123 int findEmptyBlock();
124
125 private:
126 Bu::Stream &sStore;
127 int iBlockSize;
128 int iBlocks;
129 int iUsed;
130 Bu::BitString bsBlockUsed;
131 typedef Bu::Array<int> BlockArray;
132 class Stream
133 {
134 public:
135 int iId;
136 int iSize;
137 BlockArray aBlocks;
138 };
139 typedef Bu::Array<Stream *> StreamArray;
140 StreamArray aStreams;
141 };
142};
143
144#endif