[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r8951 - gnunet/src/fs
From: |
gnunet |
Subject: |
[GNUnet-SVN] r8951 - gnunet/src/fs |
Date: |
Sat, 5 Sep 2009 15:39:13 -0600 |
Author: grothoff
Date: 2009-09-05 15:39:13 -0600 (Sat, 05 Sep 2009)
New Revision: 8951
Modified:
gnunet/src/fs/fs.h
gnunet/src/fs/fs_download.c
Log:
towards having download
Modified: gnunet/src/fs/fs.h
===================================================================
--- gnunet/src/fs/fs.h 2009-09-05 21:01:12 UTC (rev 8950)
+++ gnunet/src/fs/fs.h 2009-09-05 21:39:13 UTC (rev 8951)
@@ -877,6 +877,14 @@
GNUNET_SCHEDULER_TaskIdentifier task;
/**
+ * What was the size of the file on disk that we're downloading
+ * before we started? Used to detect if there is a point in
+ * checking an existing block on disk for matching the desired
+ * content. 0 if the file did not exist already.
+ */
+ uint64_t old_file_size;
+
+ /**
* What is the first offset that we're interested
* in?
*/
Modified: gnunet/src/fs/fs_download.c
===================================================================
--- gnunet/src/fs/fs_download.c 2009-09-05 21:01:12 UTC (rev 8950)
+++ gnunet/src/fs/fs_download.c 2009-09-05 21:39:13 UTC (rev 8951)
@@ -23,9 +23,9 @@
* @author Christian Grothoff
*
* TODO:
- * - process replies
+ * - offset calculations
* - callback signaling
- * - check if blocks exist already
+ * - check if blocks exist already (can wait)
* - location URI suppport (can wait)
* - persistence (can wait)
*/
@@ -37,8 +37,67 @@
#define DEBUG_DOWNLOAD GNUNET_YES
+/**
+ * We're storing the IBLOCKS after the
+ * DBLOCKS on disk (so that we only have
+ * to truncate the file once we're done).
+ *
+ * Given the offset of a block (with respect
+ * to the DBLOCKS) and its depth, return the
+ * offset where we would store this block
+ * in the file.
+ *
+ * @param fsize overall file size
+ * @param off offset of the block in the file
+ * @param depth depth of the block in the tree
+ * @param treedepth maximum depth of the tree
+ * @return off for DBLOCKS (depth == treedepth),
+ * otherwise an offset past the end
+ * of the file that does not overlap
+ * with the range for any other block
+ */
+static uint64_t
+compute_disk_offset (uint64_t fsize,
+ uint64_t off,
+ unsigned int depth,
+ unsigned int treedepth)
+{
+ if (depth == treedepth)
+ return off;
+ return 42; // FIXME
+}
/**
+ * Given a file of the specified treedepth and
+ * a block at the given offset and depth,
+ * calculate the offset for the CHK at
+ * the given index.
+ *
+ * @param offset the offset of the first
+ * DBLOCK in the subtree of the
+ * identified IBLOCK
+ * @param depth the depth of the IBLOCK in the tree
+ * @param treedepth overall depth of the tree
+ * @param i which CHK in the IBLOCK are we
+ * talking about
+ * @return offset if i=0, otherwise an appropriately
+ * larger value (i.e., if depth = treedepth-1,
+ * the returned value should be offset+DBLOCK_SIZE)
+ */
+static uint64_t
+compute_dblock_offset (uint64_t offset,
+ unsigned int depth,
+ unsigned int treedepth,
+ unsigned int i)
+{
+ GNUNET_assert (depth < treedepth);
+ if (i == 0)
+ return offset;
+ return 42; // FIXME
+}
+
+
+/**
* Schedule the download of the specified
* block in the tree.
*
@@ -57,8 +116,31 @@
unsigned int depth)
{
struct DownloadRequest *sm;
+ uint64_t off;
- // FIXME: check if block exists on disk!
+ off = compute_disk_offset (GNUNET_ntohll (dc->uri->data.chk.file_length),
+ offset,
+ depth,
+ dc->treedepth);
+ if ( (dc->old_file_size > off) &&
+ (dc->handle != NULL) &&
+ (off ==
+ GNUNET_DISK_file_seek (dc->handle,
+ off,
+ GNUNET_DISK_SEEK_SET) ) )
+ {
+ // FIXME: check if block exists on disk!
+ // (read block, encode, compare with
+ // query; if matches, simply return)
+ }
+ if (depth < dc->treedepth)
+ {
+ // FIXME: try if we could
+ // reconstitute this IBLOCK
+ // from the existing blocks on disk (can wait)
+ // (read block(s), encode, compare with
+ // query; if matches, simply return)
+ }
sm = GNUNET_malloc (sizeof (struct DownloadRequest));
sm->chk = *chk;
sm->offset = offset;
@@ -103,7 +185,12 @@
struct GNUNET_CRYPTO_AesSessionKey skey;
struct GNUNET_CRYPTO_AesInitializationVector iv;
char pt[size];
+ uint64_t off;
+ size_t app;
+ unsigned int i;
+ struct ContentHashKey *chk;
+ // FIXME: check that size is as big as expected, otherwise ignore!!!
GNUNET_CRYPTO_hash (data, size, &query);
sm = GNUNET_CONTAINER_multihashmap_get (dc->active,
&query);
@@ -122,10 +209,62 @@
&skey,
&iv,
pt);
- // FIXME: save to disk
+ /* save to disk */
+ if ( (NULL != dc->handle) &&
+ ( (sm->depth == dc->treedepth) ||
+ (0 == (dc->options & GNUNET_FS_DOWNLOAD_NO_TEMPORARIES)) ) )
+ {
+ off = compute_disk_offset (GNUNET_ntohll (dc->uri->data.chk.file_length),
+ sm->offset,
+ sm->depth,
+ dc->treedepth);
+ GNUNET_assert (off !=
+ GNUNET_DISK_file_seek (dc->handle,
+ off,
+ GNUNET_DISK_SEEK_SET) );
+ GNUNET_DISK_file_write (dc->handle,
+ pt,
+ size);
+ }
// FIXME: make persistent
+
+ if (sm->depth == dc->treedepth)
+ {
+ app = size;
+ if (sm->offset < dc->offset)
+ {
+ /* starting offset begins in the middle of pt,
+ do not count first bytes as progress */
+ GNUNET_assert (app > (dc->offset - sm->offset));
+ app -= (dc->offset - sm->offset);
+ }
+ if (sm->offset + size > dc->offset + dc->length)
+ {
+ /* end of block is after relevant range,
+ do not count last bytes as progress */
+ GNUNET_assert (app > (sm->offset + size) - (dc->offset + dc->length));
+ app -= (sm->offset + size) - (dc->offset + dc->length);
+ }
+ dc->completed += app;
+ }
// FIXME: call progress callback
- // FIXME: trigger next block (if applicable)
+ if (sm->depth == dc->treedepth)
+ return;
+ GNUNET_assert (0 == (size % sizeof(struct ContentHashKey)));
+ chk = (struct ContentHashKey*) pt;
+ for (i=0;i<(size / sizeof(struct ContentHashKey));i++)
+ {
+ off = compute_dblock_offset (sm->offset,
+ sm->depth,
+ dc->treedepth,
+ i);
+ if ( (off + DBLOCK_SIZE >= dc->offset) &&
+ (off < dc->offset + dc->length) )
+ schedule_block_download (dc,
+ &chk[i],
+ off,
+ sm->depth + 1);
+ }
}
@@ -363,6 +502,10 @@
if (NULL != filename)
{
dc->filename = GNUNET_strdup (filename);
+ if (GNUNET_YES == GNUNET_DISK_file_test (filename))
+ GNUNET_DISK_file_size (filename,
+ &dc->old_file_size,
+ GNUNET_YES);
dc->handle = GNUNET_DISK_file_open (filename,
GNUNET_DISK_OPEN_READWRITE |
GNUNET_DISK_OPEN_CREATE,
@@ -581,61 +724,6 @@
return ret;
}
-/**
- * DOWNLOAD children of this GNUNET_EC_IBlock.
- *
- * @param node the node that should be downloaded
- */
-static void
-iblock_download_children (const struct Node *node,
- const char *data, unsigned int size)
-{
- struct GNUNET_GE_Context *ectx = node->ctx->ectx;
- int i;
- struct Node *child;
- unsigned int childcount;
- const GNUNET_EC_ContentHashKey *chks;
- unsigned int levelSize;
- unsigned long long baseOffset;
-
- GNUNET_GE_ASSERT (ectx, node->level > 0);
- childcount = size / sizeof (GNUNET_EC_ContentHashKey);
- if (size != childcount * sizeof (GNUNET_EC_ContentHashKey))
- {
- GNUNET_GE_BREAK (ectx, 0);
- return;
- }
- if (node->level == 1)
- {
- levelSize = GNUNET_ECRS_DBLOCK_SIZE;
- baseOffset =
- node->offset / sizeof (GNUNET_EC_ContentHashKey) *
- GNUNET_ECRS_DBLOCK_SIZE;
- }
- else
- {
- levelSize =
- sizeof (GNUNET_EC_ContentHashKey) * GNUNET_ECRS_CHK_PER_INODE;
- baseOffset = node->offset * GNUNET_ECRS_CHK_PER_INODE;
- }
- chks = (const GNUNET_EC_ContentHashKey *) data;
- for (i = 0; i < childcount; i++)
- {
- child = GNUNET_malloc (sizeof (struct Node));
- child->ctx = node->ctx;
- child->chk = chks[i];
- child->offset = baseOffset + i * levelSize;
- GNUNET_GE_ASSERT (ectx, child->offset < node->ctx->total);
- child->level = node->level - 1;
- GNUNET_GE_ASSERT (ectx, (child->level != 0) ||
- ((child->offset % GNUNET_ECRS_DBLOCK_SIZE) == 0));
- if (GNUNET_NO == check_node_present (child))
- add_request (child);
- else
- GNUNET_free (child); /* done already! */
- }
-}
-
#endif
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r8951 - gnunet/src/fs,
gnunet <=