|
|
1.1 root 1: /*
2: Controller.m:
3: You may freely copy, distribute, and reuse the code in this example.
4: NeXT disclaims any warranty of any kind, expressed or implied, as to its fitness for any
5: particular use.
6:
7: Controller for BlockSizer
8: Written by Jack Greenfield
9: */
10:
11: #import "Controller.h"
12: #import "ScrollViewExtras.h"
13:
14: #import <appkit/appkit.h>
15: #import <store/IXStoreBlock.h>
16: #import <store/IXStoreFile.h>
17:
18: #define FILENAME "/tmp/BlockSizer.store"
19:
20: @implementation Controller
21:
22: - appDidInit:sender
23: {
24: /* Try to open the store file */
25: if (store = [[IXStoreFile alloc] initFromFile:FILENAME forWriting:YES]) {
26: [store enableExceptions:NO];
27: [consoleText sprintf:"opened " FILENAME "\n"];
28: [self size:self];
29: return self;
30: }
31:
32: /* Didn't find one -- create one instead */
33: [self reset:self];
34: return self;
35: }
36:
37: - ping:sender
38: {
39: unsigned blockSize;
40: unsigned blockHandle;
41: unsigned commitLimit;
42:
43: if (store) {
44: blockSize = [sizeField intValue];
45: blockHandle = [handleField intValue];
46: if (!blockSize) {
47: if (blockHandle >= [store capacity]) {
48: [handleField setIntValue:[store capacity]];
49: return self;
50: }
51:
52: if ([store blockExists:blockHandle]) {
53: [store freeBlock:blockHandle];
54: [consoleText sprintf:"freed block %d, ", blockHandle, blockSize];
55: [consoleText sprintf:"resident size = %d\n", [store residentSize]];
56: }
57: } else {
58: if ([store blockExists:blockHandle]) {
59: [store resizeBlock:blockHandle toSize:blockSize];
60: [consoleText sprintf:"resized block %d to size %d, ",
61: blockHandle, blockSize];
62: [consoleText sprintf:"resident size = %d\n", [store residentSize]];
63: } else {
64: [store createBlock:&blockHandle ofSize:blockSize];
65: [consoleText sprintf:"created block %d of size %d, ",
66: blockHandle, blockSize];
67: [consoleText sprintf:"resident size = %d\n", [store residentSize]];
68: }
69: }
70:
71: if (++pingCount < [recordField intValue])
72: [self perform:_cmd with:sender afterDelay:0 cancelPrevious:NO];
73:
74: [handleField setIntValue:blockHandle + 1];
75: commitLimit = [commitField intValue];
76: if (commitLimit && (pingCount % commitLimit) == 0)
77: [self commit:self];
78: }
79:
80: return self;
81: }
82:
83: - size:sender
84: {
85: unsigned totalSize;
86: unsigned blockCount;
87: unsigned oldSize;
88: unsigned newSize;
89: unsigned oldBlock;
90: unsigned newBlock;
91: struct stat fileStats;
92:
93: [consoleText sprintf:"\n"];
94: totalSize = 0;
95: blockCount = [store capacity];
96: if (blockCount > 1) {
97: oldSize = 0;
98: [consoleText sprintf:"store capacity = %d\n", blockCount];
99: for (oldBlock = 1, newBlock = 1; newBlock <= blockCount; ++newBlock) {
100: newSize = [store sizeOfBlock:newBlock];
101: totalSize += newSize;
102: if (oldSize) {
103: if (!newSize || oldSize != newSize || newBlock == blockCount) {
104: if (oldBlock < newBlock - 1) {
105: [consoleText sprintf:"size of blocks %d through %d = %d\n",
106: oldBlock, newBlock - 1, oldSize];
107: } else {
108: [consoleText sprintf:"size of block %d = %d\n", oldBlock, oldSize];
109: }
110:
111: oldBlock = newBlock;
112: oldSize = newSize;
113: }
114: } else {
115: if (newSize || newBlock == blockCount) {
116: if (oldBlock < newBlock - 1) {
117: [consoleText sprintf:"blocks %d through %d do not exist\n",
118: oldBlock, newBlock - 1];
119: } else {
120: if (newBlock > 1)
121: [consoleText sprintf:"block %d does not exist\n", oldBlock];
122: }
123:
124: oldBlock = newBlock;
125: oldSize = newSize;
126: }
127: }
128: }
129: }
130:
131: [consoleText sprintf:"total of block sizes = %d\n\n", totalSize];
132: [consoleText sprintf:"resident size = %d, ", [store residentSize]];
133: [consoleText sprintf:"apparent size = %d\n", [store apparentSize]];
134: stat(FILENAME, &fileStats);
135: [consoleText sprintf:"%ld disk blocks allocated, ", fileStats.st_blocks];
136: [consoleText sprintf:"file size = %ld\n", fileStats.st_size];
137: [consoleText sprintf:"storage efficiency = %.2f%\n",
138: (100.0 * totalSize) / fileStats.st_size];
139: [countField setIntValue:[store capacity]];
140: if ([handleField intValue] > [store capacity])
141: [handleField setIntValue:[store capacity]];
142:
143: [consoleText sprintf:"\n"];
144: return self;
145: }
146:
147: - run:sender
148: {
149: pingCount = 0;
150: if ([handleField intValue] > [store capacity])
151: [handleField setIntValue:[store capacity]];
152:
153: [self ping:sender];
154: return self;
155: }
156:
157: - stop:sender
158: {
159: pingCount = [recordField intValue];
160: return self;
161: }
162:
163: - step:sender
164: {
165: pingCount = 0;
166: [recordField setIntValue:1];
167: if ([handleField intValue] > [store capacity])
168: [handleField setIntValue:[store capacity]];
169:
170: [self ping:sender];
171: return self;
172: }
173:
174: - abort:sender
175: {
176: [consoleText sprintf:"aborting... "];
177: NXPing();
178: [store abortTransaction];
179: [consoleText sprintf:"done.\n"];
180: return self;
181: }
182:
183: - commit:sender
184: {
185: [consoleText sprintf:"committing... "];
186: NXPing();
187: [store commitTransaction];
188: [consoleText sprintf:"done.\n"];
189: return self;
190: }
191:
192: - compact:sender
193: {
194: [store commitTransaction];
195: [consoleText sprintf:"compacting... "];
196: NXPing();
197: [store compact];
198: [consoleText sprintf:"done.\n"];
199: return self;
200: }
201:
202: - empty:sender
203: {
204: [store commitTransaction];
205: [consoleText sprintf:"emptying... "];
206: NXPing();
207: [store empty];
208: [consoleText sprintf:"done.\n"];
209: return self;
210: }
211:
212: - reset:sender
213: {
214: [consoleText clear:self];
215: unlink(FILENAME);
216: store = [[IXStoreFile alloc] initWithFile:FILENAME];
217: [store enableExceptions:NO];
218: [store startTransaction];
219: [consoleText sprintf:"created " FILENAME "\n"];
220: [self commit:self];
221: [self size:self];
222: return self;
223: }
224:
225: - clear:sender
226: {
227: [consoleText clear:self];
228: return self;
229: }
230:
231: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.