001    package edu.harvard.deas.hyperenc;
002    
003    import java.security.MessageDigest;
004    import java.util.List;
005    
006    
007    //TODO shuffler, digest, and source don't really belong in this class
008    
009    /**
010     * Stores unreconciled pages and corresponding hash values, reconciled pages,
011     * system blocks, and encryption blocks for a single contact.
012     * <p>
013     * TODO describe the contained (abstract) data structures more carefully
014     * <p>
015     * <b>Thread safety:</b> Implementations of this class must be
016     * <i>unconditionally thread-safe</i>; concurrent access by multiple threads
017     * should be safe without the need for external synchronization.
018     */
019    public abstract class HyperStorage {
020      // INSERTION INTO STORAGE
021    
022      /**
023       * Adds a system block. Each system block is comprised of
024       * {@link HyperCollector#NUM_SYSBLOCKS} subblocks.
025       * @param block Data for block.
026       * @return ID number for block.
027       */
028      public abstract int addSysBlock(byte [][] block);
029    
030      /**
031       * Adds an encryption block.
032       * @param block Data for block.  
033       * @return ID number for block.
034       */
035      public abstract int addEncBlock(byte [] block);
036    
037      /**
038       * Adds a page of randomness that has yet to be reconciled, along with its
039       * hash.
040       * 
041       * @param id
042       *        ID number for the Page. This is the same as the ID for the block
043       *        from which it was generated.
044       * @param page
045       *        The unreconciled page.
046       * @param hash
047       *        The hash of <code>page</code>.
048       */
049      public abstract void addUPage(int id, byte [] page, byte [] hash);
050    
051      /**
052       * Store a page that has been reconciled. The page is placed at the end of a
053       * FIFO queue, so there is no ID (unlike unreconciled pages).
054       * 
055       * @param page
056       *        The reconciled page.
057       */
058      public abstract void addRPage(byte [] page);
059    
060      // QUERY ABOUT STORAGE
061    
062      /**
063       * Gets a List of IDs of available system blocks. The list is a copy; callers
064       * are free to mutate the returned list.
065       * 
066       * @return List of IDs of system blocks.
067       */
068      public abstract List<Integer> getSysBlockList();
069    
070      /**
071       * Gets a List of IDs of available encryption blocks. The list is a copy;
072       * callers are free to mutate the returned list.
073       * 
074       * @return List of IDs of encryption blocks.
075       */
076      public abstract List<Integer> getEncBlockList();
077    
078      /**
079       * Gets a List of IDs of available unreconciled pages. The list is a copy;
080       * callers are free to mutate the returned list. The list can also be used as
081       * a List of IDs for all unreconciled page hashes, because every page has a
082       * hash stored with the same ID.
083       * 
084       * @return List of IDs of unreconciled pages.
085       */
086      public abstract List<Integer> getUPageList();
087    
088      // RETRIEVAL FROM STORAGE
089    
090      /**
091       * Retrieve the system block with the given ID.
092       * @param id ID number of desired system block.
093       * @return The system block with the given ID (or null if no such block).
094       */ 
095      public abstract byte [][] getSysBlock(int id);
096    
097      /**
098       * Retrieve the encryption block with the given ID.
099       * @param id ID number of desired encryption block.
100       * @return The encryption block with the given ID (or null if no such block).
101       */
102      public abstract byte [] getEncBlock(int id);
103    
104      /**
105       * Retrieve the unreconciled page with the given ID.
106       * @param id ID of desired page.
107       * @return The unreconciled page with the given ID (or null if no such page).
108       */
109      public abstract byte [] getUPage(int id);
110    
111      /**
112       * Retrieve hash of the unreconciled page with the given ID.
113       * @param id ID of desired page.
114       * @return The hash of the page with the given ID (or null if no such page).
115       */
116      public abstract byte [] getUHash(int id);
117    
118      // REMOVAL FROM STORAGE
119      
120      /**
121       * Removes and returns system block with the given ID.
122       * @param id ID of block.
123       * @return system block with the given ID
124       */
125      public abstract byte[][] remSysBlock(int id);
126    
127      /**
128       * Removes and returns encryption block with the given ID.
129       * @param id ID of block.
130       * @return encryption block with the given ID
131       */
132      public abstract byte[] remEncBlock(int id);
133    
134      /**
135       * Removes and returns all the encryption blocks with the given IDs. This is
136       * an atomic, all-or-nothing operation: if <i>all</i> of the specified block
137       * IDs exist in this storage, then they are all removed and returned. If any
138       * of the specified IDs is missing, <i>no blocks are removed</i>, and a
139       * BlockMissingException is thrown.
140       * 
141       * @param idlist
142       *        a list of integer encryption block IDs
143       * @return a list containing the encryption blocks with the corresponding IDs,
144       *         in the same order in which the IDs were given
145       * @throws BlockMissingException
146       *         if any of the specified IDs are missing. The IDs of the missing
147       *         blocks can be accessed from the <code>getMissingIDList</code>
148       *         method of BlockMissingException.
149       */
150      public abstract List<byte[]> remEncBlockList(List<Integer> idlist)
151        throws BlockMissingException;
152    
153      /**
154       * Removes and returns unreconciled page with the given ID, and remove the
155       * corresponding hash.
156       * @param id
157       *        ID of page.
158       * @return unreconciled page with the given ID
159       */
160      public abstract byte[] remUPage(int id);
161    
162      /**
163       * Removes and returns the first reconciled page from the FIFO queue.
164       * @return a reconciled page (or <code>null</code> if there are none)
165       */
166      public abstract byte[] remRPage();
167    
168      // Specialized tools for accessing data
169      
170      /**
171       * @return The number of system blocks contained in this HyperStorage.
172       */
173      public abstract int numSysBlocks();
174      
175      /**
176       * @return The number of encryption blocks contained in this HyperStorage.
177       */
178      public abstract int numEncBlocks();
179      
180      /**
181       * @return The number of unreconciled pages contained in this HyperStorage.
182       */
183      public abstract int numUPages();
184      
185      /**
186       * @return The number of reconciled pages contained in this HyperStorage.
187       */
188      public abstract int numRPages();
189      
190      // PROPERTIES
191      /**
192       * Get the communication partner for this HyperStorage
193       * @return the contact with whom this HyperStorage's blocks and pages are used
194       *         to communicate
195       */
196      public abstract Contact getContact();
197    
198      /**
199       * The direction of communication for this HyperStorage. If MASTER, this
200       * storage's blocks and pages are used for outgoing communication: sending
201       * messages to the partner (as given by <code>getContact()</code>). If SLAVE,
202       * this storage is used for incoming communication: receiving messages from
203       * the partner.
204       * 
205       * @return the direction of communication for this storage
206       */
207      public abstract Direction getDirection();
208    
209      /**
210       * Gets the stored RandomSource object for this HyperStorage. This
211       * RandomSource object is used to create pages.
212       * 
213       * @return The RandomSource for this HyperStorage.
214       */
215      public abstract RandomSource getSource();
216    
217      /**
218       * Gets the stored MessageDigest object for this HyperStorage. This
219       * MessageDigest object is a component of the hash function used to compute
220       * the hash of a page.
221       * 
222       * @return The MessageDigest for this HyperStorage.
223       */
224      public abstract MessageDigest getDigest();
225      
226      /**
227       * @return The PageShuffler for this HyperStorage.
228       */
229      public abstract PageShuffler getShuffler();
230    }