From: Marco Costalba <hidden> Date: 2016-06-15 22:44:09
When decompressing a zlib stream use this
helpers instead of calling low level zlib
function.
This patch introduces the necessary framework,
still no code change.
This is the first step in generalizing compress and
decompress functions avoiding zlib directly calls.
Signed-off-by: Marco Costalba <redacted>
---
Makefile | 4 ++--
compress.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
compress.h | 12 ++++++++++++
3 files changed, 72 insertions(+), 2 deletions(-)
create mode 100644 compress.c
create mode 100644 compress.h
From: Marco Costalba <hidden> Date: 2016-06-15 22:44:09
These are the 'easy' ones, where a signgle step
compression is requested so that we can use only
one call to compress_all()
Signed-off-by: Marco Costalba <redacted>
---
archive-zip.c | 28 +++-------------------------
builtin-pack-objects.c | 19 +++----------------
diff.c | 22 +++++-----------------
index-pack.c | 20 +++-----------------
4 files changed, 14 insertions(+), 75 deletions(-)
@@ -409,9 +410,7 @@ static unsigned long write_object(struct sha1file *f,*/if(!to_reuse){-z_streamstream;-unsignedlongmaxsize;-void*out;+unsignedchar*out=NULL;if(!usable_delta){buf=read_sha1_file(entry->idx.sha1,&obj_type,&size);if(!buf)
@@ -432,19 +431,7 @@ static unsigned long write_object(struct sha1file *f,OBJ_OFS_DELTA:OBJ_REF_DELTA;}/* compress the data to store and put compressed length in datalen */-memset(&stream,0,sizeof(stream));-deflateInit(&stream,pack_compression_level);-maxsize=deflateBound(&stream,size);-out=xmalloc(maxsize);-/* Compress it */-stream.next_in=buf;-stream.avail_in=size;-stream.next_out=out;-stream.avail_out=maxsize;-while(deflate(&stream,Z_FINISH)==Z_OK)-/* nothing */;-deflateEnd(&stream);-datalen=stream.total_out;+datalen=compress_all(pack_compression_level,buf,size,&out);/**Theobjectheaderisabyteof'type'followedbyzeroor
From: Marco Costalba <hidden> Date: 2016-06-15 22:44:09
Here is slightly more difficult, in particular
a xrealloc() has been substituted with a
free() + xmalloc() to keep the code simple.
Signed-off-by: Marco Costalba <redacted>
---
fast-import.c | 45 +++++++++++++++------------------------------
1 files changed, 15 insertions(+), 30 deletions(-)
@@ -141,6 +141,7 @@ Format of STDIN stream:#include"builtin.h"#include"cache.h"+#include"compress.h"#include"object.h"#include"blob.h"#include"tree.h"
@@ -997,13 +998,13 @@ static int store_object(unsignedchar*sha1out,uintmax_tmark){-void*out,*delta;+unsignedchar*out,*delta;structobject_entry*e;unsignedcharhdr[96];unsignedcharsha1[20];unsignedlonghdrlen,deltalen;SHA_CTXc;-z_streams;+intout_size;hdrlen=sprintf((char*)hdr,"%s %lu",typename(type),(unsignedlong)dat->len)+1;
@@ -1039,24 +1040,15 @@ static int store_object(}elsedelta=NULL;-memset(&s,0,sizeof(s));-deflateInit(&s,pack_compression_level);-if(delta){-s.next_in=delta;-s.avail_in=deltalen;-}else{-s.next_in=(void*)dat->buf;-s.avail_in=dat->len;-}-s.avail_out=deflateBound(&s,s.avail_in);-s.next_out=out=xmalloc(s.avail_out);-while(deflate(&s,Z_FINISH)==Z_OK)-/* nothing */;-deflateEnd(&s);+if(delta)+out_size=compress_all(pack_compression_level,delta,deltalen,&out);+else+out_size=compress_all(pack_compression_level,+(unsignedchar*)dat->buf,dat->len,&out);/* Determine if we should auto-checkpoint. */-if((pack_size+60+s.total_out)>max_packsize-||(pack_size+60+s.total_out)<pack_size){+if((pack_size+60+out_size)>max_packsize+||(pack_size+60+out_size)<pack_size){/* This new object needs to *not* have the current pack_id. */e->pack_id=pack_id+1;
@@ -1066,16 +1058,9 @@ static int store_object(if(delta){free(delta);delta=NULL;--memset(&s,0,sizeof(s));-deflateInit(&s,pack_compression_level);-s.next_in=(void*)dat->buf;-s.avail_in=dat->len;-s.avail_out=deflateBound(&s,s.avail_in);-s.next_out=out=xrealloc(out,s.avail_out);-while(deflate(&s,Z_FINISH)==Z_OK)-/* nothing */;-deflateEnd(&s);+free(out);+out_size=compress_all(pack_compression_level,+(unsignedchar*)dat->buf,dat->len,&out);}}
@@ -1108,8 +1093,8 @@ static int store_object(pack_size+=hdrlen;}-write_or_die(pack_data->pack_fd,out,s.total_out);-pack_size+=s.total_out;+write_or_die(pack_data->pack_fd,out,out_size);+pack_size+=out_size;free(out);free(delta);
From: Marco Costalba <hidden> Date: 2016-06-15 22:44:09
A multistep compress is required here, so
we need the full arsenal of compress helpers.
Signed-off-by: Marco Costalba <redacted>
---
http-push.c | 22 ++++++++--------------
1 files changed, 8 insertions(+), 14 deletions(-)
@@ -491,31 +492,24 @@ static void start_put(struct transfer_request *request)hdrlen=sprintf(hdr,"%s %lu",typename(type),len)+1;/* Set it up */-memset(&stream,0,sizeof(stream));-deflateInit(&stream,zlib_compression_level);-size=deflateBound(&stream,len+hdrlen);+size=compress_alloc(&stream,zlib_compression_level,len+hdrlen);strbuf_init(&request->buffer.buf,size);request->buffer.posn=0;/* Compress it */-stream.next_out=(unsignedchar*)request->buffer.buf.buf;-stream.avail_out=size;+compress_start(&stream,(void*)hdr,hdrlen,+(unsignedchar*)request->buffer.buf.buf,size);/* First header.. */-stream.next_in=(void*)hdr;-stream.avail_in=hdrlen;-while(deflate(&stream,0)==Z_OK)-/* nothing */;+compress_next(&stream,Z_NO_FLUSH);/* Then the data itself.. */stream.next_in=unpacked;stream.avail_in=len;-while(deflate(&stream,Z_FINISH)==Z_OK)-/* nothing */;-deflateEnd(&stream);-free(unpacked);+compress_next(&stream,Z_FINISH);-request->buffer.buf.len=stream.total_out;+request->buffer.buf.len=compress_free(&stream);+free(unpacked);request->url=xmalloc(strlen(remote->url)+strlen(request->lock->token)+51);
From: Marco Costalba <hidden> Date: 2016-06-15 22:44:09
A multistep compress is required here, so
we need the full arsenal of compress helpers.
Signed-off-by: Marco Costalba <redacted>
---
sha1_file.c | 41 ++++++++++++-----------------------------
1 files changed, 12 insertions(+), 29 deletions(-)
@@ -2102,33 +2103,23 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha}/* Set it up */-memset(&stream,0,sizeof(stream));-deflateInit(&stream,zlib_compression_level);-size=8+deflateBound(&stream,len+hdrlen);+size=8+compress_alloc(&stream,zlib_compression_level,len+hdrlen);compressed=xmalloc(size);/* Compress it */-stream.next_out=compressed;-stream.avail_out=size;+compress_start(&stream,(unsignedchar*)hdr,hdrlen,compressed,size);/* First header.. */-stream.next_in=(unsignedchar*)hdr;-stream.avail_in=hdrlen;-while(deflate(&stream,0)==Z_OK)-/* nothing */;+compress_next(&stream,Z_NO_FLUSH);/* Then the data itself.. */stream.next_in=buf;stream.avail_in=len;-ret=deflate(&stream,Z_FINISH);+ret=compress_next(&stream,Z_FINISH);if(ret!=Z_STREAM_END)die("unable to deflate new object %s (%d)",sha1_to_hex(sha1),ret);-ret=deflateEnd(&stream);-if(ret!=Z_OK)-die("deflateEnd on object %s failed (%d)",sha1_to_hex(sha1),ret);--size=stream.total_out;+size=compress_free(&stream);if(write_buffer(fd,compressed,size)<0)die("unable to write sha1 file");
@@ -2163,30 +2154,22 @@ static void *repack_object(const unsigned char *sha1, unsigned long *objsize)hdrlen=sprintf(hdr,"%s %lu",typename(type),len)+1;/* Set it up */-memset(&stream,0,sizeof(stream));-deflateInit(&stream,zlib_compression_level);-size=deflateBound(&stream,len+hdrlen);+size=compress_alloc(&stream,zlib_compression_level,len+hdrlen);buf=xmalloc(size);/* Compress it */-stream.next_out=buf;-stream.avail_out=size;+compress_start(&stream,(unsignedchar*)hdr,hdrlen,buf,size);/* First header.. */-stream.next_in=(void*)hdr;-stream.avail_in=hdrlen;-while(deflate(&stream,0)==Z_OK)-/* nothing */;+compress_next(&stream,Z_NO_FLUSH);/* Then the data itself.. */stream.next_in=unpacked;stream.avail_in=len;-while(deflate(&stream,Z_FINISH)==Z_OK)-/* nothing */;-deflateEnd(&stream);-free(unpacked);+compress_next(&stream,Z_FINISH);-*objsize=stream.total_out;+*objsize=compress_free(&stream);+free(unpacked);returnbuf;}
From: Marco Costalba <hidden> Date: 2016-06-15 22:44:09
In this case decompression helper conversion is
quite similar and not too complex, so they go
togheter.
Also in index-pack.c pass correct arguments
to decompress_next_from().
Signed-off-by: Marco Costalba <redacted>
---
builtin-pack-objects.c | 14 ++++++--------
builtin-unpack-objects.c | 22 +++++++++-------------
index-pack.c | 4 +++-
3 files changed, 18 insertions(+), 22 deletions(-)
@@ -61,23 +62,20 @@ static void use(int bytes)staticvoid*get_data(unsignedlongsize){z_streamstream;-void*buf=xmalloc(size);+unsignedchar*buf=xmalloc(size);;-memset(&stream,0,sizeof(stream));--stream.next_out=buf;-stream.avail_out=size;-stream.next_in=fill(1);-stream.avail_in=len;-inflateInit(&stream);+decompress_alloc(&stream);+decompress_into(&stream,buf,size);for(;;){-intret=inflate(&stream,0);+/* fill() modifies len, so be sure is evaluated as first */+void*tmp=fill(1);+intret=decompress_next_from(&stream,tmp,len,Z_NO_FLUSH);use(len-stream.avail_in);if(stream.total_out==size&&ret==Z_STREAM_END)break;if(ret!=Z_OK){-error("inflate returned %d\n",ret);+error("decompress returned %d\n",ret);free(buf);buf=NULL;if(!recover)
@@ -85,10 +83,8 @@ static void *get_data(unsigned long size)has_errors=1;break;}-stream.next_in=fill(1);-stream.avail_in=len;}-inflateEnd(&stream);+decompress_free(&stream);returnbuf;}
@@ -173,7 +173,9 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size)decompress_into(&stream,buf,size);for(;;){-intret=decompress_next_from(&stream,fill(1),input_len,Z_NO_FLUSH);+/* fill() modifies len, so be sure is evaluated as first */+void*tmp=fill(1);+intret=decompress_next_from(&stream,tmp,input_len,Z_NO_FLUSH);use(input_len-stream.avail_in);if(stream.total_out==size&&ret==Z_STREAM_END)break;
From: Marco Costalba <hidden> Date: 2016-06-15 22:44:09
This is "The King".
It is the most difficult file to convert and some
decompression functions have been created just for it.
Anyhow the lines of code removed (45) far surpass the
ones added (26).
Signed-off-by: Marco Costalba <redacted>
---
sha1_file.c | 71 +++++++++++++++++++++-------------------------------------
1 files changed, 26 insertions(+), 45 deletions(-)
@@ -1079,16 +1079,11 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lonenumobject_typetype;/* Get the data stream */-memset(stream,0,sizeof(*stream));-stream->next_in=map;-stream->avail_in=mapsize;-stream->next_out=buffer;-stream->avail_out=bufsiz;+decompress_alloc(stream);+decompress_into(stream,buffer,bufsiz);-if(legacy_loose_object(map)){-inflateInit(stream);-returninflate(stream,0);-}+if(legacy_loose_object(map))+returndecompress_next_from(stream,map,mapsize,Z_NO_FLUSH);/*
@@ -1105,9 +1100,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lonmapsize-=used;/* Set up the stream for the rest.. */-stream->next_in=map;-stream->avail_in=mapsize;-inflateInit(stream);+decompress_from(stream,map,mapsize);/* And generate the fake traditional header */stream->total_out=1+snprintf(buffer,bufsiz,"%s %lu",
@@ -1233,20 +1225,18 @@ unsigned long get_size_from_delta(struct packed_git *p,unsignedchardelta_head[20],*in;z_streamstream;intst;+unsignedintin_size=0;-memset(&stream,0,sizeof(stream));-stream.next_out=delta_head;-stream.avail_out=sizeof(delta_head);+decompress_alloc(&stream);+decompress_into(&stream,delta_head,sizeof(delta_head));-inflateInit(&stream);do{-in=use_pack(p,w_curs,curpos,&stream.avail_in);-stream.next_in=in;-st=inflate(&stream,Z_FINISH);+in=use_pack(p,w_curs,curpos,&in_size);+st=decompress_next_from(&stream,in,in_size,Z_FINISH);curpos+=stream.next_in-in;}while((st==Z_OK||st==Z_BUF_ERROR)&&stream.total_out<sizeof(delta_head));-inflateEnd(&stream);+decompress_free(&stream);if((st!=Z_STREAM_END)&&stream.total_out!=sizeof(delta_head))die("delta data unpack-initial failed");
@@ -1323,7 +1313,7 @@ static int packed_delta_info(struct packed_git *p,/* We choose to only get the type of the base object and*ignorepotentiallycorruptpackfilethatexpectsthedelta*basedonabasewithawrongsize.Thissavestonsof-*inflate()calls.+*decompress()calls.*/if(sizep)*sizep=get_size_from_delta(p,w_curs,curpos);
From: Marco Costalba <hidden> Date: 2016-06-15 22:44:09
Conversion for both files is very similar
and in both cases I have added a FIXME where
I would have added an additional decompress_free()
The corresponding deflateEnd() call is not present in
the original code, so I left the line commented out.
Signed-off-by: Marco Costalba <redacted>
---
http-push.c | 21 +++++++++------------
http-walker.c | 22 +++++++++-------------
2 files changed, 18 insertions(+), 25 deletions(-)
@@ -305,11 +302,11 @@ static void start_fetch_loose(struct transfer_request *request)}unlink(prevfile);-/* Reset inflate/SHA1 if there was an error reading the previous temp+/* Reset decompress/SHA1 if there was an error reading the previous tempfile;alsorewindtothebeginningofthelocalfile.*/if(prev_read==-1){-memset(&request->stream,0,sizeof(request->stream));-inflateInit(&request->stream);+// FIXME should we need decompress_free() here?+decompress_alloc(&request->stream);SHA1_Init(&request->c);if(prev_posn>0){prev_posn=0;
@@ -735,7 +732,7 @@ static void finish_request(struct transfer_request *request)if(request->http_code==416)fprintf(stderr,"Warning: requested range invalid; we may already have all the data.\n");-inflateEnd(&request->stream);+decompress_free(&request->stream);SHA1_Final(request->real_sha1,&request->c);if(request->zret!=Z_STREAM_END){unlink(request->tmpfile);
@@ -179,11 +175,11 @@ static void start_object_request(struct walker *walker,}unlink(prevfile);-/* Reset inflate/SHA1 if there was an error reading the previous temp+/* Reset decompress/SHA1 if there was an error reading the previous tempfile;alsorewindtothebeginningofthelocalfile.*/if(prev_read==-1){-memset(&obj_req->stream,0,sizeof(obj_req->stream));-inflateInit(&obj_req->stream);+// FIXME should we need decompress_free() here?+decompress_alloc(&obj_req->stream);SHA1_Init(&obj_req->c);if(prev_posn>0){prev_posn=0;
From: Marco Costalba <hidden> Date: 2016-06-15 22:44:09
Also let the caller to xmalloc() the buffer
int compress_start()
Signed-off-by: Marco Costalba <redacted>
---
compress.c | 19 +++++++++----------
1 files changed, 9 insertions(+), 10 deletions(-)
From: Marco Costalba <hidden> Date: 2016-06-15 22:44:09
Only in two places is possible to really simplify
deflate code with the all_in_one decompress_all()
Signed-off-by: Marco Costalba <redacted>
---
builtin-apply.c | 23 +++++++++--------------
index-pack.c | 30 +++++++-----------------------
2 files changed, 16 insertions(+), 37 deletions(-)
@@ -169,24 +169,18 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size)z_streamstream;void*buf=xmalloc(size);-memset(&stream,0,sizeof(stream));-stream.next_out=buf;-stream.avail_out=size;-stream.next_in=fill(1);-stream.avail_in=input_len;-inflateInit(&stream);+decompress_alloc(&stream);+decompress_into(&stream,buf,size);for(;;){-intret=inflate(&stream,0);+intret=decompress_next_from(&stream,fill(1),input_len,Z_NO_FLUSH);use(input_len-stream.avail_in);if(stream.total_out==size&&ret==Z_STREAM_END)break;if(ret!=Z_OK)-bad_object(offset,"inflate returned %d",ret);-stream.next_in=fill(1);-stream.avail_in=input_len;+bad_object(offset,"decompress returned %d",ret);}-inflateEnd(&stream);+decompress_free(&stream);returnbuf;}
From: Marco Costalba <hidden> Date: 2016-06-15 22:44:09
Decompressing turns out to be more difficult then
comrpessing.
Helpers are more because more are the way
zlib deflate() is used in git.
This patch just introduces the helpers,
still no code change.
Signed-off-by: Marco Costalba <redacted>
---
compress.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
compress.h | 17 ++++++++++++-
2 files changed, 97 insertions(+), 1 deletions(-)
@@ -55,3 +59,80 @@ unsigned long compress_all(int level, unsigned char *in,}returncompress_free(&stream);}+++/*+*Decompressionhelpers+*/++intdecompress_alloc(z_stream*stream)+{+memset(stream,0,sizeof(*stream));+returninflateInit(stream);+}++intdecompress_from(z_stream*stream,unsignedchar*in,unsignedlongin_size)+{+stream->next_in=in;+stream->avail_in=in_size;+returnZ_OK;+}++intdecompress_into(z_stream*stream,unsignedchar*out,unsignedlongout_size)+{+stream->next_out=out;+stream->avail_out=out_size;+returnZ_OK;+}++intdecompress_next(z_stream*stream,intflush)+{+returninflate(stream,flush);+}++intdecompress_next_from(z_stream*stream,unsignedchar*in,unsignedlongin_size,intflush)+{+decompress_from(stream,in,in_size);+returninflate(stream,flush);+}++intdecompress_next_into(z_stream*stream,unsignedchar*out,unsignedlongout_size,intflush)+{+decompress_into(stream,out,out_size);+returninflate(stream,flush);+}++unsignedlongdecompress_free(z_stream*stream)+{+inflateEnd(stream);+returnstream->total_out;+}++unsignedlongdecompress_all(unsignedchar*in,unsignedlongin_size,+unsignedchar*out,unsignedlongout_size)+{+/* caller should check for return value != 0 */++z_streamstream;+intst;++if(decompress_alloc(&stream)!=Z_OK)+return0;++if(decompress_from(&stream,in,in_size)!=Z_OK+||decompress_into(&stream,out,out_size)!=Z_OK)+gotofail;++do{+st=decompress_next(&stream,Z_FINISH);+}while(st==Z_OK);++if(st!=Z_STREAM_END)+gotofail;++returndecompress_free(&stream);++fail:+decompress_free(&stream);+return0;+}
From: Junio C Hamano <hidden> Date: 2016-06-15 22:44:10
Marco Costalba [off-list ref] writes:
When decompressing a zlib stream use this
helpers instead of calling low level zlib
function.
This patch introduces the necessary framework,
still no code change.
This is the first step in generalizing compress and
decompress functions avoiding zlib directly calls.
(Cosmetic)
Your log message lines are wrapped a bit too short, while some
of the patch lines are too long.
This returns Z_OK unconditionally and most callers do not even
bother checking the return value. Shouldn't this be of type
void?
Especially the use of this in if() conditional, after [06/11]
changes its use in compress_all(), looks quite ugly.
From: Junio C Hamano <hidden> Date: 2016-06-15 22:44:10
Marco Costalba [off-list ref] writes:
Here is slightly more difficult, in particular
a xrealloc() has been substituted with a
free() + xmalloc() to keep the code simple.
Signed-off-by: Marco Costalba <redacted>
---
fast-import.c | 45 +++++++++++++++------------------------------
1 files changed, 15 insertions(+), 30 deletions(-)
I'll let Shawn comment on this. The realloc() does not seem to
be using the contents in the buffer from the previous round, so
I suspect that a free() followed by an independent alloc() would
be an improvement when the later call uses much larger buffer
than the previous one, but would be a waste if the later one
needs smaller buffer.
From: Junio C Hamano <hidden> Date: 2016-06-15 22:44:10
Marco Costalba [off-list ref] writes:
quoted hunk
A multistep compress is required here, so
we need the full arsenal of compress helpers.
Signed-off-by: Marco Costalba <redacted>
---
http-push.c | 22 ++++++++--------------
1 files changed, 8 insertions(+), 14 deletions(-)
From: Junio C Hamano <hidden> Date: 2016-06-15 22:44:10
Marco Costalba [off-list ref] writes:
quoted hunk
These are the 'easy' ones, where a signgle step
compression is requested so that we can use only
one call to compress_all()
Signed-off-by: Marco Costalba <redacted>
---
archive-zip.c | 28 +++-------------------------
builtin-pack-objects.c | 19 +++----------------
diff.c | 22 +++++-----------------
index-pack.c | 20 +++-----------------
4 files changed, 14 insertions(+), 75 deletions(-)
From: Junio C Hamano <hidden> Date: 2016-06-15 22:44:10
Marco Costalba [off-list ref] writes:
Also let the caller to xmalloc() the buffer
int compress_start()
This is meant to be an improvement for [01/11] and I think
should be done from the beginning by squashing into it.
Haven't looked at the decompression side yet. Help in reviewing
this series from others are appreciated.
From: Shawn O. Pearce <hidden> Date: 2016-06-15 22:44:10
Junio C Hamano [off-list ref] wrote:
Marco Costalba [off-list ref] writes:
quoted
Here is slightly more difficult, in particular
a xrealloc() has been substituted with a
free() + xmalloc() to keep the code simple.
Signed-off-by: Marco Costalba <redacted>
---
fast-import.c | 45 +++++++++++++++------------------------------
1 files changed, 15 insertions(+), 30 deletions(-)
I'll let Shawn comment on this. The realloc() does not seem to
be using the contents in the buffer from the previous round, so
I suspect that a free() followed by an independent alloc() would
be an improvement when the later call uses much larger buffer
than the previous one, but would be a waste if the later one
needs smaller buffer.
Junio is correct, that xrealloc isn't using the contents of the
buffer from the last round, which makes any memcpy it might do
internally due to movement to a larger buffer an utter waste.
In this new version we are probably always free'ing a buffer of a
much smaller size than we are then later allocating (or in the old
version xrealloc'ing to) because we are switching from a delta to
full content. Its most likely the delta is way smaller, so I'd
guess the malloc implementation is mostly going to another buffer.
In short, Marco's change will most likely do better.
But this is all academic wanking. We're talking about this xrealloc
(or free/xmalloc pair) happening only when we switch packfiles,
which in fast-import is usually every 4 GiB of output. That's a
*lot* of data to write. Who cares how many extra microseconds we
spend to perform this buffer change; we probably hit it only once
every 15-30 minutes, depending on how fast your system is able to
transfer 4 GiB of data out of the source and into a packfile.
--
Shawn.
From: Junio C Hamano <hidden> Date: 2016-06-15 22:44:10
Overall, everything looks quite nicely done.
The same comments as the compression side to "*_alloc()" apply.
Perhaps call them "setup" and "finalize" or something?