bool 
disk_storage::put_meta(const tile_protocol &tile, const std::string &buf) const {
  pair<string, int> foo = xyz_to_meta(dir_, tile.x, tile.y, tile.z, tile.style);

  if (foo.second == 0) {
    fs::path tmp = fs::path(dir_) / fs::unique_path();

    try {
      fs::path p(foo.first);
      // create directory for metatile to go in.
      fs::create_directories(p.parent_path());

      // write first to temporary location
      {
        fs::ofstream out(tmp); 
        out << buf;
      }

      // now copy that file atomically into position
      fs::rename(tmp, p);

      return true;

    } catch (const fs::filesystem_error &e) {
       LOG_ERROR(boost::format("Filesystem error: %1%") % e.what());
    }

  } else {
#ifdef RENDERMQ_DEBUG
     LOG_ERROR("Attempt to save tile at non-metatile boundary.");
#endif
  }
  return false;    
}
shared_ptr<tile_storage::handle> 
disk_storage::get(const tile_protocol &tile) const {
  if (data_locked) {
    throw runtime_error("Multiple use of disk_storage::data_cache not allowed.");
  }

  pair<string, int> foo = xyz_to_meta(dir_, tile.x, tile.y, tile.z, tile.style);
  try {
    fs::path p(foo.first);

    if (fs::exists(p)) {
      std::time_t t = fs::last_write_time(p);
      int ret = read_from_meta(dir_, tile.x, tile.y, tile.z, tile.style, 
                               data_cache.c_array(), data_cache.size(), 
                               tile.format);
      
      if (ret > 0) {
        return shared_ptr<tile_storage::handle>(new handle(t, ret, *this));
      }
    }

  } catch (const fs::filesystem_error &e) {
     LOG_ERROR(boost::format("Filesystem error: %1%") % e.what());
  }

  return shared_ptr<tile_storage::handle>(new null_handle());
}
示例#3
0
   void metaTile::save(std::string const& tile_dir, std::string const& hostname)
   {
      int ox, oy, limit;
      size_t offset;
      struct entry offsets[METATILE * METATILE];
      struct meta_layout m;
      memset(&m, 0, sizeof(m));
      memset(&offsets, 0, sizeof(offsets));

      std::pair<std::string, int> metatile = xyz_to_meta(tile_dir, x_, y_, z_, style_);
      std::stringstream ss;
      ss << metatile.first << "." << std::string(hostname) << "." << pthread_self();
      std::string tmp(ss.str());

      boost::filesystem::path p0(tmp);
      boost::filesystem::create_directories(p0.parent_path());

      std::ofstream file(tmp.c_str(), std::ios::out | std::ios::binary | std::ios::trunc);

      // Create and write header
      m.count = METATILE * METATILE;
      memcpy(m.magic, META_MAGIC, strlen(META_MAGIC));
      m.x = x_;
      m.y = y_;
      m.z = z_;
      file.write((const char *)&m, sizeof(m));

      offset = header_size;
      limit = get_meta_dimensions(z_);

      // Generate offset table
      for(ox = 0; ox < limit; ox++)
      {
         for(oy = 0; oy < limit; oy++)
         {
            int mt = xyz_to_meta_offset(x_ + ox, y_ + oy, z_);
            offsets[mt].offset = offset;
            offsets[mt].size = tile[ox][oy].size();
            offset += offsets[mt].size;
         }
      }
      file.write((const char *)&offsets, sizeof(offsets));

      // Write tiles
      for(ox = 0; ox < limit; ox++)
      {
         for(oy = 0; oy < limit; oy++)
         {
            file.write((const char *)tile[ox][oy].data(), tile[ox][oy].size());
         }
      }

      file.close();
      rename(tmp.c_str(), metatile.first.c_str());
   }
示例#4
0
文件: daemon.c 项目: plepe/mod_tile
void item_load(struct item *item, const struct protocol *req) {
    char path[PATH_MAX];
    struct stat buf;
    xyz_to_meta(path, sizeof(path), HASH_PATH, req->xmlname, req->x, req->y, req->z);
    if(!stat(path, &buf)) {
	// save time of old tile
	item->old_mtime=buf.st_mtime;
    }
    else {
	// no tile
	item->old_mtime=0;
    }
}
bool 
disk_storage::expire(const tile_protocol &tile) const {
  pair<string, int> foo = xyz_to_meta(dir_, tile.x, tile.y, tile.z, tile.style);
  try {
    fs::path p(foo.first);
    
    if (fs::exists(p)) {
      // indicate that a tile has expired by setting its time to the 
      // unix epoch. it's not perfect, but things very rarely are.
      fs::last_write_time(p, std::time_t(0));

      return true;
    }

  } catch (const fs::filesystem_error &e) {
     LOG_ERROR(boost::format("Filesystem error: %1%") % e.what());
  }
  
  return false;
}
bool 
disk_storage::get_meta(const tile_protocol &tile, std::string &data) const {
  pair<string, int> foo = xyz_to_meta(dir_, tile.x, tile.y, tile.z, tile.style);
  try {
    fs::path p(foo.first);

    if (fs::exists(p) && fs::is_regular_file(p)) {
      // if its expired we signal as such
      std::time_t t = fs::last_write_time(p);
      if(t == 0)
         return false;
      uintmax_t size = fs::file_size(p);
      fs::ifstream in(p);
      data.resize(size);
      // ooh, evil. cast away the const...
      in.read((char *)data.data(), size);
      return bool(in);
    }
  } catch (const fs::filesystem_error &e) {
     LOG_ERROR(boost::format("Filesystem error: %1%") % e.what());
  }

  return false;
}
示例#7
0
   int read_from_meta(std::string const& tile_dir, int x, int y, int z, std::string const &style, unsigned char* buf,
            size_t sz, int fmt)
   {
      char header[4096];
      std::pair<std::string, int> metatile = xyz_to_meta(tile_dir, x, y, z, style);

      int fd = open(metatile.first.c_str(), O_RDONLY);
      if(fd < 0)
         return -1;

      unsigned pos = 0;
      while(pos < sizeof(header))
      {
         size_t len = sizeof(header) - pos;
         int got = read(fd, header + pos, len);
         if(got < 0)
         {
            close(fd);
            return -2;
         }
         else
            if(got > 0)
            {
               pos += got;
            }
            else
            {
               break;
            }
      }

      // search for the correct format metatile header.
      size_t n_header = 0;
      struct meta_layout *m = NULL;
      do
      {
         m = (struct meta_layout *)(header + n_header * metaTile::header_size);
         if(pos < (n_header + 1) * metaTile::header_size)
         {
            LOG_ERROR(boost::format("Meta file %1% too small to contain header") % metatile.first);
            return -3;
         }
         if(memcmp(m->magic, META_MAGIC, strlen(META_MAGIC)))
         {
            LOG_WARNING(boost::format("Meta file %1% header magic mismatch") % metatile.first);
            return -4;
         }
         ++n_header;
      }while(m->fmt != fmt);

      // Currently this code only works with fixed metatile sizes (due to xyz_to_meta above)
      if(m->count != (METATILE * METATILE))
      {
         LOG_WARNING(boost::format("Meta file %1% header bad count %2% != %3%")
                     % metatile.first % m->count % (METATILE * METATILE));
         return -5;
      }

      size_t file_offset = m->index[metatile.second].offset;
      size_t tile_size = m->index[metatile.second].size;

      if(lseek(fd, file_offset, SEEK_SET) < 0)
      {
         LOG_ERROR(boost::format("Meta file %1% seek error %2%") % metatile.first % m->count);
         return -6;
      }
      if(tile_size > sz)
      {
         LOG_WARNING(boost::format("Truncating tile %1% to fit buffer of %1%") % tile_size % sz);
         tile_size = sz;
      }
      pos = 0;
      while(pos < tile_size)
      {
         size_t len = tile_size - pos;
         int got = read(fd, buf + pos, len);
         if(got < 0)
         {
            close(fd);
            return -7;
         }
         else
            if(got > 0)
            {
               pos += got;
            }
            else
            {
               break;
            }
      }
      close(fd);
      return pos;
   }
示例#8
0
int main(int argc, char **argv)
{
    const char *spath = RENDER_SOCKET;
    int fd;
    struct sockaddr_un addr;
    int ret=0;
    int z;
    int c;
    char name[PATH_MAX];
    struct timeval start, end;
    struct timeval start_all, end_all;
    int num, num_all = 0;
    const char * mapname = "default";
    int verbose = 0;

    while (1) {
        int option_index = 0;
        static struct option long_options[] = {
            {"socket", 1, 0, 's'},
            {"map", 1, 0, 'm'},
            {"verbose", 0, 0, 'v'},
            {"help", 0, 0, 'h'},
            {0, 0, 0, 0}
        };

        c = getopt_long(argc, argv, "hvs:m:", long_options, &option_index);
        if (c == -1)
            break;

        switch (c) {
            case 's':   /* -s, --socket */
                spath = strdup(optarg);
                break;
            case 'm':   /* -m, --map */
                mapname=strdup(optarg);
                break;
            case 'v':   /* -v, --verbose */
                verbose=1;
                break;
            case 'h':   /* -h, --help */
                fprintf(stderr, "Usage: speedtest [OPTION] ...\n");
                fprintf(stderr, "  -m, --map=MAP        render tiles in this map (defaults to '" XMLCONFIG_DEFAULT "')\n");
                fprintf(stderr, "  -s, --socket=SOCKET  unix domain socket name for contacting renderd\n");
                return -1;
            default:
                fprintf(stderr, "unhandled char '%c'\n", c);
                break;
        }
    }


  
    
    fprintf(stderr, "Rendering client\n");

    fd = socket(PF_UNIX, SOCK_STREAM, 0);
    if (fd < 0) {
        fprintf(stderr, "failed to create unix socket\n");
        exit(2);
    }

    bzero(&addr, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, spath, sizeof(addr.sun_path));

    if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        fprintf(stderr, "socket connect failed for: %s\n", spath);
        close(fd);
        exit(3);
    }

    // Render something to counter act the startup costs
    // of obtaining the Postgis table extents

    printf("Initial startup costs\n");
    gettimeofday(&start, NULL);
    process_loop(fd, 0,0,0,mapname);
    gettimeofday(&end, NULL);
    display_rate(start, end, 1);

    gettimeofday(&start_all, NULL);

    for (z=minZoom; z<=maxZoom; z++) {
        double px0 = boundx0;
        double py0 = boundy1;
        double px1 = boundx1;
        double py1 = boundy0;
        gprj.fromLLtoPixel(px0, py0, z);
        gprj.fromLLtoPixel(px1, py1, z);

        int x, xmin, xmax;
        xmin = (int)(px0/256.0);
        xmax = (int)(px1/256.0);

        int y, ymin, ymax;
        ymin = (int)(py0/256.0);
        ymax = (int)(py1/256.0);

        num = (xmax - xmin + 1) * (ymax - ymin + 1);
//        if (!num) {
//            printf("No tiles at zoom(%d)\n", z);
//            continue;
//        }

        printf("\nZoom(%d) Now rendering %d tiles\n", z, num);
        num_all += num;
        gettimeofday(&start, NULL);

        for (x=xmin; x<=xmax; x++) {
            for (y=ymin; y<=ymax; y++) {
                struct stat s;
                xyz_to_meta(name, sizeof(name), HASH_PATH, XMLCONFIG_DEFAULT, x, y, z);
                if (stat(name, &s) < 0) {
                // File doesn't exist
                    ret = process_loop(fd, x, y, z, mapname);
                }
                //printf(".");
                fflush(NULL);
            }
        }
        //printf("\n");
        gettimeofday(&end, NULL);
        display_rate(start, end, num);
    }
    gettimeofday(&end_all, NULL);
    printf("\nTotal for all tiles rendered\n");
    display_rate(start_all, end_all, num_all);

    close(fd);
    return ret;
}