CSenshi

GABOOO

Oct 6th, 2019
674
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using namespace std;
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <sys/mman.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <string.h>
  8. #include "imdb.h"
  9.  
  10. const char *const imdb::kActorFileName = "actordata";
  11. const char *const imdb::kMovieFileName = "moviedata";
  12.  
  13. imdb::imdb(const string &directory)
  14. {
  15.   const string actorFileName = directory + "/" + kActorFileName;
  16.   const string movieFileName = directory + "/" + kMovieFileName;
  17.  
  18.   actorFile = acquireFileMap(actorFileName, actorInfo);
  19.   movieFile = acquireFileMap(movieFileName, movieInfo);
  20. }
  21.  
  22. bool imdb::good() const
  23. {
  24.   return !((actorInfo.fd == -1) ||
  25.            (movieInfo.fd == -1));
  26. }
  27.  
  28. struct key_credits
  29. {
  30.   string player;
  31.   const void *data;
  32. };
  33.  
  34. struct key_cast
  35. {
  36.   film movie;
  37.   const void *data;
  38. };
  39.  
  40. static int cmp_credits(const void *m1, const void *m2)
  41. {
  42.   // elem1
  43.   struct key_credits kc = *(key_credits *)m1;
  44.   string elem1 = kc.player;
  45.  
  46.   // elem2
  47.   int offset = *(int *)m2;
  48.   string elem2 = string((char *)kc.data + offset);
  49.  
  50.   return elem1.compare(elem2);
  51. }
  52.  
  53. static int cmp_cast(const void *m1, const void *m2)
  54. {
  55.   // elem1
  56.   struct key_cast kc = *(key_cast *)m1;
  57.   film elem1 = kc.movie;
  58.  
  59.   // elem2
  60.   int offset = *(int *)m2;
  61.   string movie_name = string((char *)kc.data + offset);
  62.   char year_byte = *((char *)kc.data + offset + movie_name.size() + 1);
  63.   int year = 1900 + year_byte;
  64.   film elem2 = {movie_name, year};
  65.  
  66.   if (elem1 == elem2)
  67.     return 0;
  68.   if (elem1 < elem2)
  69.     return -1;
  70.   return 1;
  71. }
  72.  
  73. // you should be implementing these two methods right here...
  74. bool imdb::getCredits(const string &player, vector<film> &films) const
  75. {
  76.   // binary search
  77.   int total_actors = *(int *)actorFile;
  78.   key_credits kc = {player, actorFile};
  79.   void *base = (char *)actorFile + sizeof(int);
  80.   void *res = bsearch(&kc, base, total_actors, sizeof(int), cmp_credits);
  81.  
  82.   if (!res)
  83.     return false;
  84.  
  85.   // actor info
  86.   int off = *(int *)res;
  87.   void *base_act = (char *)actorFile + off;
  88.  
  89.   // actor name
  90.   char *actor_name = (char *)base_act;
  91.   int cur_off = strlen(actor_name) + 1;
  92.   cur_off += cur_off % 2;
  93.  
  94.   // movie count
  95.   short count = *(short *)((char *)base_act + cur_off);
  96.   cur_off += 2;
  97.   cur_off += (cur_off) % 4;
  98.  
  99.   // movie iteration
  100.   int *movie_offsets = (int *)((char *)base_act + cur_off);
  101.  
  102.   for (int i = 0; i < count; i++)
  103.   {
  104.     int off = movie_offsets[i];
  105.  
  106.     // name
  107.     char *movie_name = (char *)movieFile + off;
  108.     off += strlen(movie_name) + 1;
  109.  
  110.     // year
  111.     char year_byte = *((char *)movieFile + off);
  112.     int year = 1900 + year_byte;
  113.  
  114.     film cur_film = {string(movie_name), year};
  115.  
  116.     films.push_back(cur_film);
  117.   }
  118.   return true;
  119. }
  120. bool imdb::getCast(const film &movie, vector<string> &players) const
  121. {
  122.   // binary search
  123.   int total_movies = *(int *)movieFile;
  124.   key_cast kc = {movie, movieFile};
  125.   void *base = (char *)movieFile + sizeof(int);
  126.   void *res = bsearch(&kc, base, total_movies, sizeof(int), cmp_cast);
  127.  
  128.   // check if exists
  129.   if (!res)
  130.   {
  131.     players.clear();
  132.     return false;
  133.   }
  134.  
  135.   // movie info
  136.   int off = *(int *)res;
  137.   void *base_movie = (char *)movieFile + off;
  138.  
  139.   // movie name
  140.   char *movie_name = (char *)base_movie;
  141.   int cur_off = strlen(movie_name) + 1;
  142.  
  143.   // movie year
  144.   char year_byte = *((char *)base_movie + cur_off);
  145.   cur_off += 1;
  146.   cur_off += cur_off % 2;
  147.  
  148.   // actor count
  149.   short count = *(short *)((char *)base_movie + cur_off);
  150.   cur_off += 2;
  151.   cur_off += (cur_off) % 4;
  152.  
  153.   // actor iteration
  154.   int *actor_offsets = (int *)((char *)base_movie + cur_off);
  155.   for (int i = 0; i < count; i++)
  156.   {
  157.     int off = actor_offsets[i];
  158.  
  159.     //name
  160.     char *actor_name = (char *)actorFile + off;
  161.     players.push_back(string(actor_name));
  162.   }
  163.   return true;
  164. }
  165.  
  166. imdb::~imdb()
  167. {
  168.   releaseFileMap(actorInfo);
  169.   releaseFileMap(movieInfo);
  170. }
  171.  
  172. // ignore everything below... it's all UNIXy stuff in place to make a file look like
  173. // an array of bytes in RAM..
  174. const void *imdb::acquireFileMap(const string &fileName, struct fileInfo &info)
  175. {
  176.   struct stat stats;
  177.   stat(fileName.c_str(), &stats);
  178.   info.fileSize = stats.st_size;
  179.   info.fd = open(fileName.c_str(), O_RDONLY);
  180.   return info.fileMap = mmap(0, info.fileSize, PROT_READ, MAP_SHARED, info.fd, 0);
  181. }
  182.  
  183. void imdb::releaseFileMap(struct fileInfo &info)
  184. {
  185.   if (info.fileMap != NULL)
  186.     munmap((char *)info.fileMap, info.fileSize);
  187.   if (info.fd != -1)
  188.     close(info.fd);
  189. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×