fixing data_out_
[swift-upb.git] / hashtree.h
1 /*
2  *  hashtree.h
3  *  serp++
4  *
5  *  Created by Victor Grishchenko on 3/6/09.
6  *  Copyright 2009 Delft University of Technology. All rights reserved.
7  *
8  */
9 #ifndef P2TP_SHA1_HASH_TREE_H
10 #define P2TP_SHA1_HASH_TREE_H
11 #include "bin64.h"
12 #include "bins.h"
13 #include <string.h>
14 #include <string>
15
16 namespace p2tp {
17
18
19 struct Sha1Hash {
20         uint8_t bits[20];
21
22         Sha1Hash() { memset(bits,0,20); }
23         Sha1Hash(const Sha1Hash& left, const Sha1Hash& right);
24         Sha1Hash(const char* str, size_t length=-1);
25         Sha1Hash(const uint8_t* data, size_t length);
26         Sha1Hash(bool hex, const char* hash);
27         
28         std::string     hex() const;
29         bool    operator == (const Sha1Hash& b) const
30                 { return 0==memcmp(bits,b.bits,SIZE); }
31         bool    operator != (const Sha1Hash& b) const { return !(*this==b); }
32     const char* operator * () const { return (char*) bits; }
33         
34         const static Sha1Hash ZERO;
35         const static size_t SIZE;
36 };
37
38
39 class HashTree {
40
41     /** Merkle hash tree: root */
42         Sha1Hash        root_hash_;
43     Sha1Hash        *hashes_;
44     /** Merkle hash tree: peak hashes */
45     Sha1Hash        peak_hashes_[64];
46     bin64_t         peaks_[64];
47     int             peak_count_;
48     /** File descriptor to put hashes to */
49         int             fd_;
50     int             hash_fd_;
51     /** Whether to re-hash files. */
52     bool            data_recheck_;
53     /** Base size, as derived from the hashes. */
54     size_t          size_;
55     size_t          sizek_;
56     /** Part of the tree currently checked. */
57     size_t          complete_;
58     size_t          completek_;
59     bins            ack_out_;
60     
61 protected:
62     
63     void            Submit();
64     void            RecoverProgress();
65     Sha1Hash        DeriveRoot();
66     bool            OfferPeakHash (bin64_t pos, const Sha1Hash& hash);
67     
68 public:
69         
70         HashTree (const char* file_name, const Sha1Hash& root=Sha1Hash::ZERO, 
71               const char* hash_filename=NULL);
72     
73     /** Offer a hash; returns true if it verified; false otherwise.
74      Once it cannot be verified (no sibling or parent), the hash
75      is remembered, while returning false. */
76     bool            OfferHash (bin64_t pos, const Sha1Hash& hash);
77     /** Offer data; the behavior is the same as with a hash:
78      accept or remember or drop. Returns true => ACK is sent. */
79     bool            OfferData (bin64_t bin, const char* data, size_t length);
80     /** Not implemented yet. */
81     int             AppendData (char* data, int length) ;
82     
83     int             file_descriptor () const { return fd_; }
84     int             peak_count () const { return peak_count_; }
85     bin64_t         peak (int i) const { return peaks_[i]; }
86     const Sha1Hash& peak_hash (int i) const { return peak_hashes_[i]; }
87     bin64_t         peak_for (bin64_t pos) const;
88     const Sha1Hash& hash (bin64_t pos) const {return hashes_[pos];}
89     const Sha1Hash& root_hash () const { return root_hash_; }
90     uint64_t        size () const { return size_; }
91     uint64_t        size_kilo () const { return sizek_; }
92     uint64_t        complete () const { return complete_; }
93     uint64_t        complete_kilo () const { return completek_; }
94     uint64_t        seq_complete () ;
95     bool            is_complete () 
96         { return size_ && complete_==size_; }
97     bins&           ack_out () { return ack_out_; }
98         
99         ~HashTree ();
100
101         
102 };
103
104 }
105
106 #endif