CS计算机代考程序代写 cache #include

#include
#include #include
#include
#include

#include “../common/contextmanager.h”
#include “../common/crypto.h”
#include “../common/err.h”
#include “../common/file.h”
#include “../common/net.h”
#include “../common/pool.h”

#include “parsing.h”
#include “storage.h”

using namespace std;

/// arg_t represents the command-line arguments to the server
struct arg_t {
int port; // The port on which to listen
string datafile; // The file for storing all data
string keyfile; // The file holding the AES key
int threads = 1; // Number of threads for the server to use
size_t num_buckets = 1024; // Number of buckets for the server’s hash tables
size_t quota_interval = 60; // Seconds over which a quota is enforced
size_t quota_up = 1048576; // K/V upload quota (bytes/interval)
size_t quota_down = 1048576; // K/V download quota (bytes/interval)
size_t quota_req = 16; // K/V request quota (requests/interval)
size_t top_size = 4; // Number of keys to track for TOP queries
string admin_name = “”; // Name of the administrator

/// Construct an arg_t from the command-line arguments to the program
///
/// @param argc The number of command-line arguments passed to the program
/// @param argv The list of command-line arguments
///
/// @throw An intmd5eger exception (1) if an invalid argument is given, or if
/// `-h` is passed in
arg_t(int argc, char **argv) {
long opt;
while ((opt = getopt(argc, argv, “p:f:k:ht:b:i:u:d:r:o:a:”)) != -1) {
switch (opt) {
case ‘p’:
port = atoi(optarg);
break;
case ‘f’:
datafile = string(optarg);
break;
case ‘k’:
keyfile = string(optarg);
break;
case ‘t’:
threads = atoi(optarg);
break;
case ‘b’:
num_buckets = atoi(optarg);
break;
case ‘i’:
quota_interval = atoi(optarg);
break;
case ‘u’:
quota_up = atoi(optarg);
break;
case ‘d’:
quota_down = atoi(optarg);
break;
case ‘r’:
quota_req = atoi(optarg);
break;
case ‘o’:
top_size = atoi(optarg);
break;
case ‘a’:
admin_name = string(optarg);
break;
default: // on any error, print a help message. This case subsumes `-h`
throw 1;
return;
}
}
}

/// Display a help message to explain how the command-line parameters for this
/// program work
///
/// @progname The name of the program
static void usage(char *progname) {
cout << basename(progname) << ": company user directory server\n" << " -p [int] Port on which to listen for incoming connections\n" << " -f [string] File for storing all data\n" << " -k [string] Basename of file for storing the server's RSA keys\n" << " -t [int] # of threads that server should use\n" << " -b [int] # of buckets for the server's hash tables\n" << " -i [int] Quota interval (seconds)\n" << " -u [int] Upload quota (MB/interval)\n" << " -d [int] Download quota (MB/interval)\n" << " -r [int] Request quota (requests/interval)\n" << " -o [int] Size of the TOP key cache\n" << " -a [string] Specify name of admin user\n" << " -h Print help (this message)\n"; } }; int main(int argc, char **argv) { // Parse the command-line arguments // // NB: It would be better not to put the arg_t on the heap, but then we'd need // an extra level of nesting for the body of the rest of this function. arg_t *args; try { args = new arg_t(argc, argv); } catch (int i) { arg_t::usage(argv[0]); return 1; } // print the configuration cout << "Listening on port " << args->port << " using (key/data) = (" << args->keyfile << ", " << args->datafile << ")\n"; // If the key files don't exist, create them and then load the private key. RSA *pri = init_RSA(args->keyfile);
if (pri == nullptr)
return -1;
ContextManager r([&]() { RSA_free(pri); });

// load the public key file contents
auto pub = load_entire_file(args->keyfile + “.pub”);
if (pub.size() == 0)
return 1;

// If the data file exists, load the data into a Storage object. Otherwise,
// create an empty Storage object.
Storage storage(args->datafile, args->num_buckets);
auto res = storage.load_file();
if (!res.succeeded)
return intErr(1, res.msg.c_str());
cout << res.msg << endl; // Start listening for connections. int sd = create_server_socket(args->port);
ContextManager csd([&]() { close(sd); });
// Create a thread pool that will invoke parse_request (from a pool thread)
// each time a new socket is given to it.
thread_pool pool(args->threads, [&](int sd) {
return parse_request(sd, pri, pub, storage);
});

// Start accepting connections and passing them to the pool.
accept_client(sd, pool);

// The program can’t exit until all threads in the pool are done.
pool.await_shutdown();
storage.shutdown();
delete args;
cout << "Server terminated\n"; }