-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DSS-client C API update #93
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1308,6 +1308,23 @@ namespace dss { | |
return ret; | ||
} | ||
|
||
extern "C" int PutObject(DSSClient c, void* key_name, int key_len, char* src_file) | ||
{ | ||
Client *client = (Client*) c; | ||
if (client == nullptr || (char*) key_name == nullptr){ | ||
return -1; | ||
} | ||
std::string key_str ((char*) key_name, key_len); | ||
int ret = -1; | ||
|
||
try { | ||
ret = client->PutObject(key_str.c_str(), src_file); | ||
} catch(...) { | ||
printf("Exception caught in PutObject - %s\n", key_str.c_str()); | ||
} | ||
return ret; | ||
} | ||
|
||
extern "C" int DeleteObject(DSSClient c, void* key_name, int key_len) | ||
{ | ||
Client *client = (Client*) c; | ||
|
@@ -1323,7 +1340,90 @@ namespace dss { | |
printf("Exception caught in DeleteObject for %s\n", key_str.c_str()); | ||
} | ||
return ret; | ||
} | ||
|
||
extern "C" int ListObjects(DSSClient c, char* prefix, char* delimit, char* keys, int cur_pg) | ||
{ | ||
Client *client = (Client*) c; | ||
if (client == nullptr){ | ||
printf("the DSS client cannot be a null pointer.\n"); | ||
return FAILURE; | ||
} | ||
if (keys == nullptr){ | ||
printf("the buffer to store keys cannot be a null pointer.\n"); | ||
return FAILURE; | ||
} | ||
if (cur_pg == -1){ // for the first page of list | ||
client->list_objs = client->GetObjects(prefix, delimit); | ||
} | ||
if (client->list_objs->GetObjKeys() < 0) { // reached the end of the pages for LIST | ||
return END_OF_LIST; | ||
} | ||
std::string keys_concat = ""; | ||
for (std::string key: client->list_objs->GetPage()){ | ||
keys_concat += key + "\n"; // seperate each key by line assuming there is no "\n" in the object name or directory name or delimiter | ||
} | ||
if (keys_concat == "") return END_OF_LIST; | ||
keys[keys_concat.length()] = '\0'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any possibility to get length of the key during the for loop at line 1363 itself? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, we can accumulate and get the sum of key lengths. |
||
strncpy(keys, keys_concat.c_str(), keys_concat.length()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If above case doesn't work, you can store the keys_concat.length() in a variable and use that instead of computing length multiple times thereby introducing latency |
||
if (keys[keys_concat.length()] != '\0') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above for computing length |
||
printf("the buffer overflow for storing keys\n"); | ||
return FAILURE; | ||
} | ||
return cur_pg + 1; | ||
} | ||
|
||
extern "C" int DeleteAll(DSSClient c, char* prefix, char* delimit) | ||
{ | ||
Client *client = (Client*) c; | ||
if (client == nullptr){ | ||
printf("the DSS client cannot be a null pointer.\n"); | ||
return FAILURE; | ||
} | ||
if (prefix == nullptr){ | ||
printf("the prefix cannot be a null pointer.\n"); | ||
return FAILURE; | ||
} | ||
if (delimit == nullptr){ | ||
printf("the delimiter cannot be a null pointer.\n"); | ||
return FAILURE; | ||
} | ||
uint32_t pg_size = DSS_PAGINATION_DEFAULT; | ||
int max_key_len = 1024; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better to hash define this value (1024) as S3_MAX_KEY_SIZE_LIMIT at the top or in the header file for easy change in the future |
||
char* keys = (char*) malloc(sizeof(char) * max_key_len * pg_size); | ||
int pg; | ||
while (true){ | ||
pg = ListObjects(client, prefix, delimit, keys, -1); // list the very first page | ||
if (pg == FAILURE){ | ||
printf("ListObjects failed for prefix=\"%s\" and delimit=\"%s\".\n", prefix, delimit); | ||
printf("DeleteAll failed for prefix=\"%s\" and delimit=\"%s\".\n", prefix, delimit); | ||
free(keys); | ||
return FAILURE; | ||
} | ||
if (pg == END_OF_LIST) break; | ||
std::stringstream all_keys(keys); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can check whether strtok or stringstream is efficient and use it accordingly. |
||
std::string each_key; | ||
while (std::getline(all_keys, each_key, '\n')){ // retrieve each key by line | ||
try { | ||
if (client->DeleteObject(each_key.c_str()) < 0 ){ // delete the very first page listed | ||
printf("DeleteObject failed for %s.\n", each_key.c_str()); | ||
free(keys); | ||
return FAILURE; | ||
} | ||
// printf("Deleting %s\n", each_key.c_str()); | ||
} catch(...) { | ||
printf("Exception caught in DeleteObject for %s.\n", each_key.c_str()); | ||
free(keys); | ||
return FAILURE; | ||
} | ||
} | ||
} | ||
free(keys); | ||
return 0; | ||
} | ||
extern "C" int GetPageSize() { | ||
return DSS_PAGINATION_DEFAULT; | ||
} | ||
|
||
} // namespace dss | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
#include <fcntl.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
#include <dirent.h> | ||
|
||
#include "dss.h" | ||
|
||
|
@@ -18,13 +19,55 @@ int hexdump(unsigned char* buff, int size) | |
return 0; | ||
} | ||
|
||
int putRecursive(DSSClient c, char *basePath) | ||
{ | ||
int i; | ||
char path[1000]; | ||
struct dirent *dp; | ||
DIR *dir = opendir(basePath); | ||
|
||
if (!dir){ | ||
return 0; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation needs to be fixed |
||
|
||
while ((dp = readdir(dir)) != NULL) | ||
{ | ||
if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) | ||
{ | ||
strcpy(path, basePath); | ||
strcat(path, "/"); | ||
strcat(path, dp->d_name); | ||
// printf("%s\n", path); | ||
FILE* fp = fopen(path, "r"); | ||
if (fp == NULL) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation issues |
||
return 0; | ||
} | ||
fseek(fp, 0L, SEEK_END); | ||
// calculating the size of the file | ||
long int fsize = ftell(fp); | ||
if (dp->d_type == DT_REG && fsize > 0){ // PutObject does not support empty files | ||
if (PutObject(c, (void*) path, strlen(path), path) < 0 ){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fclose needs to be done |
||
printf("PutObject - %s failed.\n", path); | ||
return -1; | ||
} | ||
} | ||
if (putRecursive(c, path) < 0) return -1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rather than going into the function putRecursive to check whether dir or not, you can add else case. Since you are already checking regular file in the top and you have dp->d_type handy. |
||
} | ||
} | ||
closedir(dir); | ||
return 0; | ||
} | ||
|
||
int main(int argc, char* argv[]) { | ||
DSSClient *c; | ||
int fd = -1; | ||
int ret = -1; | ||
int size = 1024*1024; | ||
unsigned char* buff; | ||
unsigned char* buff1; | ||
int cur_page = -1; | ||
int max_key_len = 1024; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use hash-define variable as mentioned above |
||
char* keys_list; | ||
char obj_name[256]; | ||
char uuid[] = "12345"; | ||
|
||
|
@@ -38,8 +81,9 @@ int main(int argc, char* argv[]) { | |
printf("Invalid endpoint URL\n"); | ||
return -1; | ||
} | ||
if (argc == 5) | ||
if (argc >= 5) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why >= is required? If so, then the usage should be updated properly |
||
size = atoi(argv[4]) * 1024; | ||
|
||
buff = (unsigned char*)calloc(1, size); | ||
buff1 = (unsigned char*)calloc(1, size); | ||
|
||
|
@@ -77,10 +121,50 @@ int main(int argc, char* argv[]) { | |
ret = DeleteObject(c, (void*) obj_name, strlen(obj_name)); | ||
printf("Object testfile1 deleted\n"); | ||
|
||
// upload objects with a directory structure to test LIST | ||
if (putRecursive(c, "/etc") < 0 ){ | ||
printf("Uploading directory failed.\n"); | ||
goto out; | ||
} | ||
//test the LIST | ||
keys_list = (char*) malloc(sizeof(char) * max_key_len * GetPageSize()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since sizeof(char) is 1, you can see if this is really required. This may be applicable at the top as well. |
||
if (keys_list == NULL) { | ||
printf("malloc failed for allocating buffer to store the LIST results\n"); | ||
goto out; | ||
} | ||
while (1){ | ||
cur_page = ListObjects(c, "", "", keys_list, cur_page); // List all objects with prefix "" | ||
if (cur_page == FAILURE){ | ||
printf("ListObjects failed.\n"); | ||
goto out; | ||
} | ||
if (cur_page == END_OF_LIST) break; | ||
printf("page index = %d:\n[%s]\n", cur_page, keys_list); | ||
} | ||
//test the DeleteAll | ||
ret = DeleteAll(c, "etc", ""); | ||
if (ret < 0) { | ||
printf("DeleteAll failed.\n"); | ||
goto out; | ||
} | ||
//retest the LIST after DeleteAll | ||
printf("After DeleteAll:\n"); | ||
cur_page = -1; | ||
while (1){ | ||
cur_page = ListObjects(c, "", "", keys_list, cur_page); // List all objects with prefix="" | ||
if (cur_page == FAILURE){ | ||
printf("ListObjects failed.\n"); | ||
goto out; | ||
} | ||
if (cur_page == END_OF_LIST) break; | ||
printf("page index = %d:\n[%s]\n", cur_page, keys_list); | ||
} | ||
|
||
out: | ||
if (fd != -1) | ||
close(fd); | ||
free(buff); | ||
free(buff1); | ||
free(keys_list); | ||
return ret; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cpp + operator is very expensive when you have lot of objects. Rather than that, you can fall back to standard and efficient C based code. But this requires key_buffer_size to be passed as a variable