--- /dev/null
+package CloudStore::dedup;
+use warnings;
+use strict;
+use autodie;
+
+sub path_md5 {
+ my ( $path, $md5 ) = @_;
+
+ my $pool = 'md5'; # FIXME sharding?
+ mkdir $pool unless -e $pool;
+
+ if ( -e "$pool/$md5" ) {
+ warn "dedup hit $md5 $path\n";
+ my $dedup = $path . '.dedup';
+ rename $path, $dedup;
+ link "$pool/$md5", $path;
+ unlink $dedup;
+ } else {
+ link $path, "$pool/$md5";
+ }
+}
+
+sub path_remove {
+ my ( $path ) = @_;
+
+ my ( undef, undef, undef, $nlink ) = stat $path;
+
+ warn "nlink $path $nlink";
+}
+
+my $empty_md5 = " " x 32;
+
+sub data {
+ my $data = shift;
+
+ my $path = "users/$data->{login}/blob/$data->{file}";
+
+ return if -d $path;
+
+ if ( $data->{md5} ne $empty_md5 ) {
+ path_md5 $path => $data->{md5};
+ } else {
+ path_remove $path;
+ }
+}
+
+1;
use lib 'lib';
use CloudStore::JSON;
+use CloudStore::dedup;
my $dir = $ENV{RSYNC_DIR} || '/srv/cloudstore';
my $port = $ENV{RSYNC_PORT} || 6501;
print ">>> data ",dump( \%data ) if $ENV{DEBUG};
+ CloudStore::dedup::data \%data;
+
my $json = CloudStore::JSON::rsync_transfer \%data;
$gearman->dispatch_background( 'rsync_transfer' => $json );
--- /dev/null
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use Test::More tests => 3;
+use Data::Dump qw(dump);
+
+use lib 'lib';
+
+use_ok 'CloudStore::dedup';
+
+my $md5 = "51ce99ec40129bfe1fd11d65b346d15e";
+my $file = "users/test/blob/foo";
+
+my $r;
+
+ok( $r = CloudStore::dedup::path_md5( $file, "test1-$md5" ), 'path_md5' );
+diag dump($r);
+
+ok( $r = CloudStore::dedup::path_remove( $file ), 'path_remove' );
+diag dump($r);
+