home *** CD-ROM | disk | FTP | other *** search
- /*
- Controller.m:
- You may freely copy, distribute, and reuse the code in this example.
- NeXT disclaims any warranty of any kind, expressed or implied, as to its fitness for any
- particular use.
-
- Controller for BlockSizer
- Written by Jack Greenfield
- */
-
- #import "Controller.h"
- #import "ScrollViewExtras.h"
-
- #import <appkit/appkit.h>
- #import <store/IXStoreBlock.h>
- #import <store/IXStoreFile.h>
-
- #define FILENAME "/tmp/BlockSizer.store"
-
- @implementation Controller
-
- - appDidInit:sender
- {
- /* Try to open the store file */
- if (store = [[IXStoreFile alloc] initFromFile:FILENAME forWriting:YES]) {
- [store enableExceptions:NO];
- [consoleText sprintf:"opened " FILENAME "\n"];
- [self size:self];
- return self;
- }
-
- /* Didn't find one -- create one instead */
- [self reset:self];
- return self;
- }
-
- - ping:sender
- {
- unsigned blockSize;
- unsigned blockHandle;
- unsigned commitLimit;
-
- if (store) {
- blockSize = [sizeField intValue];
- blockHandle = [handleField intValue];
- if (!blockSize) {
- if (blockHandle >= [store capacity]) {
- [handleField setIntValue:[store capacity]];
- return self;
- }
-
- if ([store blockExists:blockHandle]) {
- [store freeBlock:blockHandle];
- [consoleText sprintf:"freed block %d, ", blockHandle, blockSize];
- [consoleText sprintf:"resident size = %d\n", [store residentSize]];
- }
- } else {
- if ([store blockExists:blockHandle]) {
- [store resizeBlock:blockHandle toSize:blockSize];
- [consoleText sprintf:"resized block %d to size %d, ",
- blockHandle, blockSize];
- [consoleText sprintf:"resident size = %d\n", [store residentSize]];
- } else {
- [store createBlock:&blockHandle ofSize:blockSize];
- [consoleText sprintf:"created block %d of size %d, ",
- blockHandle, blockSize];
- [consoleText sprintf:"resident size = %d\n", [store residentSize]];
- }
- }
-
- if (++pingCount < [recordField intValue])
- [self perform:_cmd with:sender afterDelay:0 cancelPrevious:NO];
-
- [handleField setIntValue:blockHandle + 1];
- commitLimit = [commitField intValue];
- if (commitLimit && (pingCount % commitLimit) == 0)
- [self commit:self];
- }
-
- return self;
- }
-
- - size:sender
- {
- unsigned totalSize;
- unsigned blockCount;
- unsigned oldSize;
- unsigned newSize;
- unsigned oldBlock;
- unsigned newBlock;
- struct stat fileStats;
-
- [consoleText sprintf:"\n"];
- totalSize = 0;
- blockCount = [store capacity];
- if (blockCount > 1) {
- oldSize = 0;
- [consoleText sprintf:"store capacity = %d\n", blockCount];
- for (oldBlock = 1, newBlock = 1; newBlock <= blockCount; ++newBlock) {
- newSize = [store sizeOfBlock:newBlock];
- totalSize += newSize;
- if (oldSize) {
- if (!newSize || oldSize != newSize || newBlock == blockCount) {
- if (oldBlock < newBlock - 1) {
- [consoleText sprintf:"size of blocks %d through %d = %d\n",
- oldBlock, newBlock - 1, oldSize];
- } else {
- [consoleText sprintf:"size of block %d = %d\n", oldBlock, oldSize];
- }
-
- oldBlock = newBlock;
- oldSize = newSize;
- }
- } else {
- if (newSize || newBlock == blockCount) {
- if (oldBlock < newBlock - 1) {
- [consoleText sprintf:"blocks %d through %d do not exist\n",
- oldBlock, newBlock - 1];
- } else {
- if (newBlock > 1)
- [consoleText sprintf:"block %d does not exist\n", oldBlock];
- }
-
- oldBlock = newBlock;
- oldSize = newSize;
- }
- }
- }
- }
-
- [consoleText sprintf:"total of block sizes = %d\n\n", totalSize];
- [consoleText sprintf:"resident size = %d, ", [store residentSize]];
- [consoleText sprintf:"apparent size = %d\n", [store apparentSize]];
- stat(FILENAME, &fileStats);
- [consoleText sprintf:"%ld disk blocks allocated, ", fileStats.st_blocks];
- [consoleText sprintf:"file size = %ld\n", fileStats.st_size];
- [consoleText sprintf:"storage efficiency = %.2f%\n",
- (100.0 * totalSize) / fileStats.st_size];
- [countField setIntValue:[store capacity]];
- if ([handleField intValue] > [store capacity])
- [handleField setIntValue:[store capacity]];
-
- [consoleText sprintf:"\n"];
- return self;
- }
-
- - run:sender
- {
- pingCount = 0;
- if ([handleField intValue] > [store capacity])
- [handleField setIntValue:[store capacity]];
-
- [self ping:sender];
- return self;
- }
-
- - stop:sender
- {
- pingCount = [recordField intValue];
- return self;
- }
-
- - step:sender
- {
- pingCount = 0;
- [recordField setIntValue:1];
- if ([handleField intValue] > [store capacity])
- [handleField setIntValue:[store capacity]];
-
- [self ping:sender];
- return self;
- }
-
- - abort:sender
- {
- [consoleText sprintf:"aborting... "];
- NXPing();
- [store abortTransaction];
- [consoleText sprintf:"done.\n"];
- return self;
- }
-
- - commit:sender
- {
- [consoleText sprintf:"committing... "];
- NXPing();
- [store commitTransaction];
- [consoleText sprintf:"done.\n"];
- return self;
- }
-
- - compact:sender
- {
- [store commitTransaction];
- [consoleText sprintf:"compacting... "];
- NXPing();
- [store compact];
- [consoleText sprintf:"done.\n"];
- return self;
- }
-
- - empty:sender
- {
- [store commitTransaction];
- [consoleText sprintf:"emptying... "];
- NXPing();
- [store empty];
- [consoleText sprintf:"done.\n"];
- return self;
- }
-
- - reset:sender
- {
- [consoleText clear:self];
- unlink(FILENAME);
- store = [[IXStoreFile alloc] initWithFile:FILENAME];
- [store enableExceptions:NO];
- [store startTransaction];
- [consoleText sprintf:"created " FILENAME "\n"];
- [self commit:self];
- [self size:self];
- return self;
- }
-
- - clear:sender
- {
- [consoleText clear:self];
- return self;
- }
-
- @end
-