1 package CloudStore::Couchbase;
7 use File::Path qw(make_path);
10 use Digest::MD5 qw(md5_base64);
11 use Data::Dump qw(dump);
24 foreach my $bucket ( keys %$buckets ) {
25 my $port = $buckets->{$bucket};
26 my $server = new Cache::Memcached {
27 'servers' => [ "127.0.0.1:$port" ],
28 'debug' => $ENV{DEBUG},
29 # 'compress_threshold' => 10_000,
31 #$server->set_servers($array_ref);
32 #$server->set_compress_threshold(10_000);
33 $server->enable_compress(0);
34 $self->{$bucket} = $server;
38 warn "# new ",dump $self;
44 my ($self,$data) = @_;
45 $self->{session}->decr( $data->{login} . ':usage' => $data->{size} );
49 my ($self,$data) = @_;
50 $self->{session}->incr( $data->{login} . ':usage' => $data->{size} );
54 my ($self,$data) = @_;
55 $self->{session}->get( $data->{login} . ':usage' );
60 #md5_base64( $data->{login} . '/' . $data->{file} );
61 $data->{login} . ':' . $data->{file};
65 my ($self,$data) = @_;
67 my $json = encode_json $data;
68 $self->{files}->set( $k => $json );
73 my ($self,$data) = @_;
75 if ( my $json = $self->{files}->get($k) ) {
76 return decode_json $json;
81 my ( $self,$data ) = @_;
83 if ( my $old = $self->file_get( $data ) ) {
84 $self->usage_decr( $data );
87 $self->new_file($data);
91 my ( $self,$data ) = @_;
92 $self->file_set($data);
93 $self->usage_incr($data);
97 my ( $self, $data ) = @_;
98 $self->usage_decr( $data );
100 $self->{files}->delete( $k );
104 my ( $self, $data ) = @_;
109 my ( $self,$data ) = @_;
111 my $blob = "users/$data->{login}/blob";
112 my $path = "$blob/$data->{file}";
114 if ( $data->{itemize} =~ m/^[c>]([fd])/ ) { # received change/create
117 if ( $type eq 'f' ) {
118 $self->modify_file( $data );
119 $self->dedup( $data, $path );
120 } elsif ( $type eq 'd' ) {
121 $self->make_dir( $data );
123 die "unknown type $type ", dump $data;
125 } elsif ( $data->{itemize} =~ m/\*deleting/ ) {
126 $self->remove_file($data);
132 my ( $path, $md5 ) = @_;
134 my $pool = 'md5'; # FIXME sharding?
135 mkdir $pool unless -e $pool;
137 if ( -e "$pool/$md5" ) {
138 warn "dedup hit $md5 $path\n";
139 my $dedup = $path . '.dedup';
140 rename $path, $dedup;
141 link "$pool/$md5", $path;
144 link $path, "$pool/$md5";
148 my $empty_md5 = " " x 32;
151 my ( $self, $data, $path ) = @_;
153 if ( $data->{file} =~ /^(.+\/)?md5sum$/ ) {
156 warn "IMPORT ", $data->{file}, "\n";
157 open(my $md5sum, '<', $path);
160 my ( $md5, $file ) = split(/\s+/,$_,2);
161 if ( ! -e "md5/$md5" ) {
162 warn "MISSING $md5 $file\n";
165 my $new = "users/$data->{login}/blob/$dir$file";
167 # create path from md5sum file
168 my $only_dir = $1 if $new =~ m{^(.+)/[^/]+$};
169 make_path $only_dir unless -d $only_dir;
170 $imported += link "md5/$md5", $new;
172 login => $data->{login},
173 host => $data->{host},
174 file => $dir . $file,
178 $self->new_file($fake);
179 warn "fake ",dump($fake);
181 md5pool $new => $md5;
184 print "INFO imported $imported files from ",dump($data);
187 if ( $data->{md5} ne $empty_md5 ) {
188 md5pool $path => $data->{md5};