Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-03-05 18:13:41 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-03-05 18:13:41 +0300
commit4f764637e6603d8dee324031944772db05c11058 (patch)
tree52ff24339fda8a2964559520e506a193e70f08e5 /source/blender/blenloader
parent3a7b420ec66d2fa64814997f205f8d307fce8436 (diff)
Undo optimization: now big chunks of memory are not written as single
memory blocks anymore, but smaller fixed size blocks, so that diffing can be more effective. For example helps in sculpt mode when making only local changes to the mesh, previously it would copy the whole MVert array for each undo step.
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r--source/blender/blenloader/intern/readfile.c53
-rw-r--r--source/blender/blenloader/intern/writefile.c30
2 files changed, 55 insertions, 28 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index ca25f2f0cef..f93b95843d4 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -858,6 +858,7 @@ static int fd_read_from_memfile(FileData *filedata, void *buffer, int size)
static unsigned int seek= 1<<30; /* the current position */
static unsigned int offset= 0; /* size of previous chunks */
static MemFileChunk *chunk=NULL;
+ unsigned int chunkoffset, readsize, totread;
if(size==0) return 0;
@@ -875,29 +876,39 @@ static int fd_read_from_memfile(FileData *filedata, void *buffer, int size)
}
if(chunk) {
- /* first check if it's on the end if current chunk */
- if( seek-offset == chunk->size) {
- offset+= chunk->size;
- chunk= chunk->next;
- }
-
- /* debug, should never happen */
- if(chunk==NULL) {
- printf("illegal read, chunk zero\n");
- return 0;
- }
- else if( (seek-offset)+size > chunk->size) {
- size= chunk->size - (seek-offset);
- printf("chunk too large, clipped to %d\n", size);
- }
-
- memcpy(buffer, chunk->buf + (seek-offset), size);
- filedata->seek += size;
- seek+= size;
-
- return (size);
+ totread= 0;
+
+ do {
+ /* first check if it's on the end if current chunk */
+ if(seek-offset == chunk->size) {
+ offset+= chunk->size;
+ chunk= chunk->next;
+ }
+
+ /* debug, should never happen */
+ if(chunk==NULL) {
+ printf("illegal read, chunk zero\n");
+ return 0;
+ }
+
+ chunkoffset= seek-offset;
+ readsize= size-totread;
+
+ /* data can be spread over multiple chunks, so clamp size
+ * to within this chunk, and then it will read further in
+ * the next chunk */
+ if(chunkoffset+readsize > chunk->size)
+ readsize= chunk->size-chunkoffset;
+
+ memcpy(buffer + totread, chunk->buf+chunkoffset, readsize);
+ totread += readsize;
+ filedata->seek += readsize;
+ seek += readsize;
+ } while(totread < size);
+ return totread;
}
+
return 0;
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 0804ec9689c..6fcb5312da8 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -187,7 +187,10 @@ Important to know is that 'streaming' has been added to files, for Blender Publi
#include <errno.h>
-/* ********* my write, buffered writing with minimum 50k chunks ************ */
+/* ********* my write, buffered writing with minimum size chunks ************ */
+
+#define MYWRITE_BUFFER_SIZE 100000
+#define MYWRITE_MAX_CHUNK 32768
typedef struct {
struct SDNA *sdna;
@@ -216,7 +219,7 @@ static WriteData *writedata_new(int file)
wd->file= file;
- wd->buf= MEM_mallocN(100000, "wd->buf");
+ wd->buf= MEM_mallocN(MYWRITE_BUFFER_SIZE, "wd->buf");
return wd;
}
@@ -256,12 +259,13 @@ int mywfile;
* @warning Talks to other functions with global parameters
*/
-#define MYWRITE_FLUSH NULL
+#define MYWRITE_FLUSH NULL
static void mywrite( WriteData *wd, void *adr, int len)
{
if (wd->error) return;
+ /* flush helps compression for undo-save */
if(adr==MYWRITE_FLUSH) {
if(wd->count) {
writedata_do_write(wd, wd->buf, wd->count);
@@ -272,21 +276,33 @@ static void mywrite( WriteData *wd, void *adr, int len)
wd->tot+= len;
- if(len>50000) {
+ /* if we have a single big chunk, write existing data in
+ * buffer and write out big chunk in smaller pieces */
+ if(len>MYWRITE_MAX_CHUNK) {
if(wd->count) {
writedata_do_write(wd, wd->buf, wd->count);
wd->count= 0;
}
- writedata_do_write(wd, adr, len);
+
+ do {
+ int writelen= MIN2(len, MYWRITE_MAX_CHUNK);
+ writedata_do_write(wd, adr, writelen);
+ adr = (char*)adr + writelen;
+ len -= writelen;
+ } while(len > 0);
+
return;
}
- if(len+wd->count>99999) {
+
+ /* if data would overflow buffer, write out the buffer */
+ if(len+wd->count>MYWRITE_BUFFER_SIZE-1) {
writedata_do_write(wd, wd->buf, wd->count);
wd->count= 0;
}
+
+ /* append data at end of buffer */
memcpy(&wd->buf[wd->count], adr, len);
wd->count+= len;
-
}
/**