NetworkFile: change waitForFilePiece behaviour to only wait once - consumers must handle looping behaviour themselves.

This commit is contained in:
Nekojimi 2025-10-02 00:09:55 +01:00
parent 1131d47dc0
commit 6685e6fd7e

View file

@ -25,7 +25,7 @@ public class NetworkFile extends NetworkFSNode
private File localFile = null; private File localFile = null;
private final SortedSet<ObjectID> peersWithCopy = new TreeSet<>(); private final SortedSet<ObjectID> peersWithCopy = new TreeSet<>();
// private final Map<Peer, PeerFileState> fileStates = new HashMap<>(); // private final Map<Peer, PeerFileState> fileStates = new HashMap<>();
private BitSet pieces = new BitSet(); private BitSet pieces = new BitSet();
// private List<FilePiece> pieces = new ArrayList<>(); // private List<FilePiece> pieces = new ArrayList<>();
@ -70,14 +70,14 @@ public class NetworkFile extends NetworkFSNode
if (after.containsKey("hash")) if (after.containsKey("hash"))
hash = HexFormat.of().parseHex(after.get("hash")); hash = HexFormat.of().parseHex(after.get("hash"));
if (after.containsKey("pieceSize")) if (after.containsKey("pieceSize"))
pieceSize = Long.parseLong(after.get("pieceSize")); pieceSize = Long.parseLong(after.get("pieceSize"));
if (after.containsKey("peersWithCopy")) if (after.containsKey("peersWithCopy"))
{ {
peersWithCopy.clear(); peersWithCopy.clear();
String[] peers = after.get("peersWithCopy").split(","); String[] peers = after.get("peersWithCopy").split(",");
for (String peer: peers) for (String peer : peers)
{ {
peersWithCopy.add(new ObjectID(Long.parseUnsignedLong(peer,16))); peersWithCopy.add(new ObjectID(Long.parseUnsignedLong(peer, 16)));
} }
} }
} }
@ -122,7 +122,7 @@ public class NetworkFile extends NetworkFSNode
else else
localFile = new File(localFilePath); localFile = new File(localFilePath);
peersWithCopy.clear(); peersWithCopy.clear();
peersWithCopy.addAll(((List<Object>)map.get("peersWithCopy")).stream().map(Util::unconditionalNumberToLong).map(ObjectID::new).toList()); peersWithCopy.addAll(((List<Object>) map.get("peersWithCopy")).stream().map(Util::unconditionalNumberToLong).map(ObjectID::new).toList());
} }
public File getLocalFile() public File getLocalFile()
@ -132,7 +132,9 @@ public class NetworkFile extends NetworkFSNode
/** /**
* Retreives the local file used for storing file data, or if it doesn't exist, creates it. * Retreives the local file used for storing file data, or if it doesn't exist, creates it.
*
* @return a File object for the (potentially new) file storage. * @return a File object for the (potentially new) file storage.
*
* @throws IOException if the file could not be created due to an IO error. * @throws IOException if the file could not be created due to an IO error.
*/ */
public File getOrCreateLocalFile() throws IOException public File getOrCreateLocalFile() throws IOException
@ -146,7 +148,9 @@ public class NetworkFile extends NetworkFSNode
{ {
localFile = new File(tempDirectory, getName()); localFile = new File(tempDirectory, getName());
// localFile = File.createTempFile("FriendCloud", getNetworkPath()); // localFile = File.createTempFile("FriendCloud", getNetworkPath());
localFile.createNewFile(); boolean created = localFile.createNewFile();
if (created)
System.out.println("NetworkFile: Created local file " + localFile.getAbsolutePath() + " for " + getObjectID());
} }
return localFile; return localFile;
} }
@ -237,34 +241,25 @@ public class NetworkFile extends NetworkFSNode
/** /**
* Waits for a certain piece of the file to become available, or for a timeout to expire. * Waits for a certain piece of the file to become available, or for a timeout to expire.
* @param pieceIdx the index of the piece to wait for. Note: <=0 means "don't wait at all", not "wait forever". *
* @param pieceIdx the index of the piece to wait for. Note: <=0 means "don't wait at all", not "wait forever".
* @param timeoutMs the amount of time, in milliseconds, to wait. * @param timeoutMs the amount of time, in milliseconds, to wait.
* @return true if the piece is available (haspiece(pieceIdx) will return true), false if the timeout was reached. * @throws InterruptedException if the waiting was interrupted.
*
* @return true if the piece is available (hasPiece(pieceIdx) will return true), false if the timeout was reached.
*/ */
public boolean waitForFilePiece(int pieceIdx, long timeoutMs) public boolean waitForFilePiece(int pieceIdx, long timeoutMs) throws InterruptedException
{ {
synchronized (pieces) synchronized (pieces)
{ {
if (hasPiece(pieceIdx)) if (hasPiece(pieceIdx))
return true; return true;
while (timeoutMs > 0) System.out.println("NetworkFile: waiting " + timeoutMs + "ms for piece " + pieceIdx + " of file " + name);
pieces.wait(timeoutMs);
if (hasPiece(pieceIdx))
{ {
long startTime = System.currentTimeMillis(); System.out.println("NetworkFile: got piece we were waiting for.");
try return true;
{
System.out.println("NetworkFile: waiting "+ timeoutMs + "ms for piece " + pieceIdx + " of file " + name);
pieces.wait(timeoutMs);
if (hasPiece(pieceIdx))
{
System.out.println("NetworkFile: got piece we were waiting for.");
return true;
}
} catch (InterruptedException ignored)
{
}
long endTime = System.currentTimeMillis();
long timeWaited = (endTime - startTime);
timeoutMs -= timeWaited;
} }
} }
System.err.println("Timed out waiting for piece!"); System.err.println("Timed out waiting for piece!");
@ -286,11 +281,17 @@ public class NetworkFile extends NetworkFSNode
public enum StorageType public enum StorageType
{ {
/** The file will be stored as a complete file in the storage directory under it's own name and file path. */ /**
* The file will be stored as a complete file in the storage directory under it's own name and file path.
*/
COMPLETE, COMPLETE,
/** The file will be stored as a complete file in a temporary directory. It will be deleted when the computer restarts. */ /**
* The file will be stored as a complete file in a temporary directory. It will be deleted when the computer restarts.
*/
TEMPORARY_COMPLETE, TEMPORARY_COMPLETE,
/** Each piece of the file will be stored permanently in an individual piece file, in the pieces subdirectory. */ /**
* Each piece of the file will be stored permanently in an individual piece file, in the pieces subdirectory.
*/
PIECES, PIECES,
} }
} }