From 6a27b548fdbe226da94b870cde7a14dd11710098 Mon Sep 17 00:00:00 2001 From: Drew Short Date: Sat, 5 Mar 2016 00:48:47 -0600 Subject: [PATCH] Introduced the concept of a cache_version so that we can change the cache style without segfaulting existing deployments. --- Cargo.toml | 2 +- src/cache.rs | 80 +++++++++++++++++++++++++++++++++++++++++++++------- src/hash.rs | 11 +++----- src/lib.rs | 10 +++++-- 4 files changed, 83 insertions(+), 20 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 89ae2d7..eb2b3ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pihash" -version = "0.2.4" +version = "0.2.5" authors = ["Drew Short "] description = "A simple library for generating perceptual hashes for images and comparing images based on their perceptual hashes." repository = "https://github.com/warricksothr/Perceptual-Image-Hashing/" diff --git a/src/cache.rs b/src/cache.rs index 5325ac6..b3de76a 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -3,27 +3,45 @@ // Licensed under the MIT license. // This file may not be copied, modified, or distributed except according to those terms. -extern crate image; -extern crate sha1; -extern crate flate2; - -use self::image::ImageBuffer; -use self::sha1::Sha1; -use self::flate2::Compression; -use self::flate2::write::ZlibEncoder; -use self::flate2::read::ZlibDecoder; +use super::image; +use super::image::ImageBuffer; +use super::sha1::Sha1; +use super::flate2::Compression; +use super::flate2::write::ZlibEncoder; +use super::flate2::read::ZlibDecoder; use std::str::FromStr; use std::path::Path; use std::fs::{File, create_dir_all, remove_dir_all}; use std::io::{Read, Error, Write}; use std::option::Option; use std::result::Result; +use super::rustc_serialize::json; pub const CACHE_DIR: &'static str = "./.hash_cache"; const CACHED_IMAGE_EXT: &'static str = "png"; const CACHED_MATRIX_EXT: &'static str = "dft"; // Caching version information const CACHE_VERSION: u32 = 1; +const CACHE_METADATA_FILE: &'static str = "cache.meta"; + +#[derive(RustcDecodable, RustcEncodable)] +struct CacheMetadata { + cache_version: u32, +} + +impl Default for CacheMetadata { + fn default() -> CacheMetadata { CacheMetadata { cache_version: CACHE_VERSION } } +} + +impl PartialEq for CacheMetadata { + fn eq(&self, other: &CacheMetadata) -> bool { + self.cache_version == other.cache_version + } + + fn ne(&self, other: &CacheMetadata) -> bool { + !self.eq(&other) + } +} /** * Structure to hold implementation of the cache @@ -41,7 +59,49 @@ impl<'a> Cache<'a> { * Create the required directories for the cache */ pub fn init(&self) -> Result<(), Error> { - create_dir_all(self.cache_dir) + match create_dir_all(self.cache_dir) { + Ok(_) => { + let metadata_path_str = format!("{}/{}", self.cache_dir, CACHE_METADATA_FILE); + let metadata_path = Path::new(&metadata_path_str); + let current_metadata: CacheMetadata = Default::default(); + match File::open(&metadata_path) { + Ok(mut file) => { + // Metadata file exists, compare them + let mut loaded_metadata_string = String::new(); + let _ = file.read_to_string(&mut loaded_metadata_string); + let loaded_metadata: CacheMetadata = match json::decode(&loaded_metadata_string) { + Ok(data) => data, + Err(_) => CacheMetadata { cache_version: 0 }, + }; + + // If they match, continue + if current_metadata != loaded_metadata { + // If they don't wipe the cache to start new + match remove_dir_all(self.cache_dir) { + Ok(_) => { + match create_dir_all(self.cache_dir) { + Ok(_) => (), + Err(e) => println!("Error: {}", e), + } + }, + Err(e) => println!("Error: {}", e), + }; + }; + } + // Metadata file doesn't exist, do nothing assume all is well, create new metadata file + Err(_) => {}, + }; + let encoded_cache_metadata = json::encode(¤t_metadata).unwrap(); + match File::create(&metadata_path) { + Ok(mut file) => { + let _ = file.write(&encoded_cache_metadata.as_bytes()); + Ok(()) + }, + Err(e) => Err(e) + } + }, + Err(e) => Err(e), + } } /** diff --git a/src/hash.rs b/src/hash.rs index 92b641c..2b25edd 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -3,15 +3,12 @@ // Licensed under the MIT license. // This file may not be copied, modified, or distributed except according to those terms. -// Pull in the image processing crate -extern crate image; -extern crate dft; -extern crate complex; - use std::path::Path; use std::f64; -use self::image::{GenericImage, Pixel, FilterType}; -use self::dft::Transform; +use super::image; +use super::image::{GenericImage, Pixel, FilterType}; +use super::dft; +use super::dft::Transform; use cache::Cache; // Used to get ranges for the precision of rounding floats diff --git a/src/lib.rs b/src/lib.rs index eff1010..032ed30 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,11 +3,17 @@ // Licensed under the MIT license. // This file may not be copied, modified, or distributed except according to those terms. +extern crate libc; +extern crate rustc_serialize; +extern crate image; +extern crate dft; +extern crate complex; +extern crate sha1; +extern crate flate2; + mod hash; mod cache; -extern crate libc; - use std::path::Path; use hash::PerceptualHash; use std::ffi::CStr;