1/*
2** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3** Distributed under the terms of the Haiku License.
4*/
5
6
7#include <BlockMap.h>
8
9#include <string.h>
10#include <stdlib.h>
11#include <stdio.h>
12
13
14static const off_t kSize = 262144;	// 4096 * 262144 == 1 GB of file size
15static const int32 kLoops = 4096;	// 4096 * 4096 == 16 MB in cache (completely arbitrary which will never be the case)
16
17
18int32
19offset_in_array(off_t *array, int32 maxSize, off_t offset)
20{
21	for (int32 i = 0; i < maxSize; i++) {
22		if (array[i] == offset)
23			return i;
24	}
25
26	return B_ENTRY_NOT_FOUND;
27}
28
29
30int
31main(int argc, char **argv)
32{
33	BlockMap map(kSize);
34
35	status_t status = map.InitCheck();
36	if (status != B_OK) {
37		fprintf(stderr, "map creation failed: %s\n", strerror(status));
38		return 1;
39	}
40
41	printf("Adding %ld offsets from 0 to %Ld...\n", kLoops, kSize);
42
43	off_t offsets[kLoops];
44	for (int32 i = 0; i < kLoops; i++) {
45		off_t offset;
46		do {
47			offset = rand() * kSize / RAND_MAX;
48		} while (offset_in_array(offsets, i, offset) >= B_OK);
49
50		offsets[i] = offset;
51		map.Set(offsets[i], i + 1);
52	}
53
54	printf("Testing all offsets in the map...\n");
55
56	for (off_t offset = 0; offset < kSize; offset++) {
57		// look for offset in array
58		int32 index = offset_in_array(offsets, kLoops, offset);
59
60		addr_t address;
61		if (map.Get(offset, address) == B_OK) {
62			if (index >= 0) {
63				if (address != (uint32)index + 1)
64					fprintf(stderr, "  offset %Ld contains wrong address %lx, should have been %lx\n", offset, address, index + 1);
65			} else
66				fprintf(stderr, "  offset %Ld found in map but never added\n", offset);
67		} else {
68			if (index >= 0)
69				fprintf(stderr, "  offset %Ld not found in map but should be there\n", offset);
70		}
71	}
72
73	printf("Remove last offset...\n");
74
75	// remove last offset
76	map.Remove(offsets[kLoops - 1]);
77	addr_t address;
78	if (map.Get(offsets[kLoops - 1], address) == B_OK)
79		fprintf(stderr, "  Removing offset %Ld failed (got address %lx)!\n", offsets[kLoops - 1], address);
80
81	// remove offsets in the middle
82	off_t start = kSize / 4;
83	off_t num = kSize / 2;
84	off_t end = start + num;
85
86	printf("Remove all offsets from %Ld to %Ld (and add bounds check offsets)...\n", start, end);
87
88	bool startWall[3] = {false};
89	for (int32 i = 0; i < 3; i++) {
90		if (offset_in_array(offsets, kLoops, start - 1 + i) < B_OK) {
91			startWall[i] = true;
92			map.Set(start - 1 + i, i + 1);
93		}
94	}
95
96	bool endWall[3] = {false};
97	for (int32 i = 0; i < 3; i++) {
98		if (offset_in_array(offsets, kLoops, end - 1 + i) < B_OK) {
99			endWall[i] = true;
100			map.Set(end - 1 + i, i + 1);
101		}
102	}
103
104	map.Remove(start, num);
105
106	printf("Testing all offsets in the map...\n");
107
108	for (off_t offset = 0; offset < kSize; offset++) {
109		// look for offset in array
110		int32 index = offset_in_array(offsets, kLoops - 1, offset);
111
112		addr_t address;
113		if (map.Get(offset, address) == B_OK) {
114			if (offset >= start && offset < end) {
115				fprintf(stderr, "  should not contain removed offset %Ld:%lx!\n", offset, address);
116			} else if (index >= 0) {
117				if (address != (uint32)index + 1)
118					fprintf(stderr, "  offset %Ld contains wrong address %lx, should have been %lx\n", offset, address, index + 1);
119			} else {
120				if (offset >= start -1 && offset <= start + 1) {
121					// start && start + 1 must not be in the map anymore
122					if (offset >= start && offset <= start + 1)
123						fprintf(stderr, "  start wall %Ld in map\n", offset);
124				} else if (offset >= end - 1 && offset <= end + 1) {
125					// end - 1 must not be in the map anymore
126					if (offset == end - 1)
127						fprintf(stderr, "  end wall %Ld in map\n", offset);
128				} else
129					fprintf(stderr, "  offset %Ld found in map but never added\n", offset);
130			}
131		} else {
132			if (index >= 0 && (offset < start || offset >= end))
133				fprintf(stderr, "  offset %Ld not found in map but should be there\n", offset);
134
135			if (offset == start - 1 && startWall[offset - start - 1])
136				fprintf(stderr, "  start wall %Ld not in map\n", offset);
137			else if (offset >= end && offset <= end + 1 && endWall[offset - end - 1])
138				fprintf(stderr, "  end wall %Ld not in map\n", offset);
139		}
140	}
141
142	return 0;
143}
144