-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbranch.c
More file actions
164 lines (137 loc) · 4.09 KB
/
Copy pathbranch.c
File metadata and controls
164 lines (137 loc) · 4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <inttypes.h>
#include "teller.h"
#include "account.h"
#include "error.h"
#include "debug.h"
#include "branch.h"
/*
* allocate and initialize each branch.
*/
int
Branch_Init(Bank *bank, int numBranches, int numAccounts,
AccountAmount initialAmount)
{
bank->numberBranches = numBranches;
bank->branches = malloc(numBranches * sizeof(Branch));
if (bank->branches == NULL) {
return -1;
}
int accountsPerBranch = numAccounts / numBranches;
for (int i = 0; i < numBranches; i++) {
Branch *branch = &bank->branches[i];
branch->branchID = i;
branch->balance = 0;
branch->numberAccounts = accountsPerBranch;
branch->accounts = (Account *) malloc(accountsPerBranch * sizeof(Account));
sem_init(&(branch->branchLocker), 0, 1);
if (branch->accounts == NULL) {
return -1;
}
for (int k = 0; k < accountsPerBranch; k++) {
Account_Init(bank, &branch->accounts[k], k, i, initialAmount);
branch->balance += branch->accounts[k].balance;
}
}
return 0;
}
/*
* update the balance of a branch.
*/
int
Branch_UpdateBalance(Bank *bank, BranchID branchID, AccountAmount change)
{
assert(bank->branches); Y;
if (branchID >= bank->numberBranches) {
return -1;
}
AccountAmount oldBalance = bank->branches[branchID].balance; Y;
bank->branches[branchID].balance = oldBalance + change; Y;
return 0;
}
/*
* get the balance of the branch
*/
int
Branch_Balance(Bank *bank, BranchID branchID, AccountAmount *balance)
{
assert(bank->branches);
if (branchID >= bank->numberBranches) {
return -1;
}
*balance = bank->branches[branchID].balance; Y;
/* It should be the case that the balance of a branch matches the sum
* of all the accounts in the branch. The following routine validates
* this assumption but is far too expense to run in normal operation.
*/
/* assert(Branch_Validate(bank, branchID) == 0); */
return 0;
}
/*
* validate the branch by checking its branchID and making sure that
* its balance equals the sum of balances of all accounts inside
* the branch.
*/
int
Branch_Validate(Bank *bank, BranchID branchID)
{
assert(bank->branches);
if (branchID >= bank->numberBranches) {
return -1;
}
Branch *branch = &bank->branches[branchID];
AccountAmount total = 0;
for (int a = 0; a < branch->numberAccounts; a++) {
total += branch->accounts[a].balance;
}
if (total != branch->balance) {
fprintf(stderr, "Branch balance mismatch. "
"Computer value is %"PRId64", but stored value is %"PRId64"\n",
total, branch->balance);
return -1;
}
return 0;
}
/*
* Compare all data inside two branches to see if they are exactly the same.
*/
int
Branch_Compare(Branch *branch1, Branch *branch2)
{
int err = 0;
BranchID branch1ID = branch1->branchID;
BranchID branch2ID = branch2->branchID;
if (branch1->numberAccounts != branch2->numberAccounts) {
fprintf(stderr, "Branches %"PRIu64" and %"PRIu64" mismatch in numberAccounts "
"(%d and %d, respectively).\n",
branch1ID, branch2ID,
branch1->numberAccounts,
branch2->numberAccounts);
err = -1;
}
if (branch1->balance != branch2->balance) {
fprintf(stderr, "Branches %"PRIu64" and %"PRIu64" mismatch in balance "
"(%"PRId64" and %"PRId64", respectively).\n",
branch1ID, branch2ID,
branch1->balance, branch2->balance);
err = -1;
}
for (int i = 0; i < branch1->numberAccounts; i++) {
assert(branch1->accounts[i].accountNumber ==
branch2->accounts[i].accountNumber);
if (branch1->accounts[i].balance != branch2->accounts[i].balance) {
fprintf(stderr,
"Branch %"PRIu64" and %"PRIu64" mismatch in account 0x%"PRIx64" balance "
"(%"PRId64" and %"PRId64", respectively).\n",
branch1ID, branch2ID,
branch1->accounts[i].accountNumber,
branch1->accounts[i].balance,
branch2->accounts[i].balance);
err = -1;
}
}
return err;
}