author | Alberto Bertogli
<albertito@gmail.com> 2004-07-15 02:22:37 UTC |
committer | Alberto Bertogli
<albertito@gmail.com> 2007-07-15 13:16:22 UTC |
parent | 5f75224ba811ae25b550112cc6216a760feaf589 |
doc/guide.lyx | +648 | -0 |
doc/guide.txt | +317 | -0 |
doc/libjio.3 | +3 | -0 |
doc/libjio.lyx | +20 | -27 |
diff --git a/doc/guide.lyx b/doc/guide.lyx new file mode 100644 index 0000000..a6adff3 --- /dev/null +++ b/doc/guide.lyx @@ -0,0 +1,648 @@ +#LyX 1.3 created this file. For more info see http://www.lyx.org/ +\lyxformat 221 +\textclass article +\language english +\inputencoding auto +\fontscheme default +\graphics default +\paperfontsize default +\papersize Default +\paperpackage a4 +\use_geometry 0 +\use_amsmath 0 +\use_natbib 0 +\use_numerical_citations 0 +\paperorientation portrait +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\defskip medskip +\quotes_language english +\quotes_times 2 +\papercolumns 1 +\papersides 1 +\paperpagestyle default + +\layout Title + +libjio Programmer's Guide +\layout Author + +Alberto Bertogli (albertogli@telpin.com.ar) +\layout Standard + + +\begin_inset LatexCommand \tableofcontents{} + +\end_inset + + +\layout Section + +Introduction +\layout Standard + +This small document attempts serve as a guide to the programmer who wants + to make use of the library. + It's not a replacement for the man page or reading the code; but it's a + good starting point for everyone who wants to get involved with it. +\layout Standard + +The library is not complex to use at all, and the interfaces were designed + to be as intuitive as possible, so the text is structured as a guide to + present the reader all the common structures and functions the way they're + normally used. +\layout Section + +Definitions +\layout Standard + +This is a library which provides a journaled transaction-oriented I/O API. + You've probably read this a hundred times already in the documents, and + if you haven't wondered yet what on earth does this mean you should be + reading something else! +\layout Standard + +We say this is a transaction-oriented API because we make transactions the + center of our operations, and journaled because we use a journal (which + takes the form of a directory with files on it) to guarantee coherency + even after a crash at any point. +\layout Standard + +Here we think a transaction as a list of +\emph on +(buffer, length, offset) +\emph default + to be applied to a file. + That triple is called an +\emph on +operation +\emph default +, so we can say that a transaction represent an ordered group of operations + on the same file +\emph on +. +\layout Standard + +The act of +\emph on +committing +\emph default + a transaction means writing all the elements of the list; and +\emph on +rollbacking +\emph default + means to undo a previous commit, and leave the data just as it was before + doing the commit. +\begin_inset Foot +collapsed false + +\layout Standard + +While all this definitions may seem obvious to some people, it requires + special attention because there are a lot of different definitions, and + it's not that common to see +\begin_inset Quotes eld +\end_inset + +transaction +\begin_inset Quotes erd +\end_inset + + applied to file I/O (it's a term used mostly on database stuff), so it's + important to clarify before continuing. +\end_inset + + +\layout Standard + +It's important to note that the library not only provides a convenient and + easy API to perform this kind of operations, but provides a lot of guarantees + while doing this. + The most relevant and useful is that at any point of time, even if we crash + horribly, a transaction will be either fully applied or not applied at + all. + You should not ever see partial transactions or any kind of data corruption. +\layout Standard + +To achieve this, the library uses what is called a +\emph on +journal +\emph default +, a very vague (and fashionable) term we use to describe a set of auxiliary + files that get created to store temporary data at several stages. + The proper definition and how we use them is outside the scope of this + document, and you as a programmer shouldn't need to deal with it. + In case you're curious, it's described in a bit more detail in another + text which talks about how the library works internally. + Now let's get real. +\layout Section + +The data types +\layout Standard + +To understand any library, it's essential to be confident in the knowledge + of their data structures and how they relate each other. + In libjio we have two basic structures which have a very strong relationship, + and represent the essential objects we deal with. + Note that you normally don't manipulate them directly, because they have + their own initializer functions, but they are the building blocks for the + rest of the text, which, once this is understood, is obvious and self-evident. +\layout Standard + +The first structure we face is +\family typewriter +struct\SpecialChar ~ +jfs +\family default +, called the +\emph on +file structure +\emph default +, and it represents an open file, just like a regular file descriptor or + a +\family typewriter +FILE\SpecialChar ~ +* +\family default +. +\layout Standard + +Then you find +\family typewriter +struct\SpecialChar ~ +jtrans +\family default +, called the +\emph on +transaction structure +\emph default +, which represents a single transaction. + You can have as many transactions as you want, and operate on all of them + simultaneously without problems; the library is entirely thread safe so + there's no need to worry about that. +\layout Section + +The basic functions +\layout Standard + +Now that we've described our data types, let's see how we can really operate + with the library. + +\layout Standard + +First of all, as with regular I/O, you need to open your files. + This is done with +\family typewriter +jopen() +\family default +, which looks a lot like +\family typewriter +open() +\family default + but takes a file structure instead of a file descriptor (this will be very + common among all the functions), and adds a new parameter +\emph on +jflags +\emph default + that can be used to modify some subtle library behaviour we'll see later, + and it's normally not used. +\layout Standard + +We have a happy file structure open now, and the next thing to do would + be to create a transaction. + This is what +\family typewriter +jtrans_init() +\family default + is for: it takes a file structure and a transaction structure and initializes + the latter, leaving it ready to use. +\layout Standard + +So we have our transaction, let's add a write operation to it; to do this + we use +\family typewriter +jtrans_add() +\family default +. + We could keep on adding operations to the transaction by keep on calling + +\family typewriter +jtrans_add() +\family default + as many times as we want. +\layout Standard + +Finally, we decide to apply our transaction to the file, that is, write + all the operations we've added. + And this is the easiest part: we call +\family typewriter +jtrans_commit() +\family default +, and that's it! +\layout Standard + +When we're done using the file, we call +\family typewriter +jclose() +\family default +, just like we call +\family typewriter +close() +\family default +. +\layout Standard + +Let's put it all together and code a nice +\begin_inset Quotes eld +\end_inset + +hello world +\begin_inset Quotes erd +\end_inset + + program (return values are ignored for simplicity): +\layout LyX-Code + +char buf[] = "Hello world!"; +\layout LyX-Code + +struct jfs file; +\layout LyX-Code + +struct jtrans trans; +\newline + +\newline + +\layout LyX-Code + +jopen(&file, "filename", O_RDWR | O_CREAT, 0600, 0); +\layout LyX-Code + +jtrans_init(&file, &trans); +\newline + +\newline + +\layout LyX-Code + +jtrans_add(&trans, buf, strlen(buf), 0); +\newline + +\newline + +\layout LyX-Code + +jtrans_commit(&trans); +\newline + +\newline + +\layout LyX-Code + +jclose(&file); +\layout Standard + +As we've seen, we open the file and initialize the structure with +\family typewriter +jopen() +\family default + (with the parameter +\emph on +jflags +\emph default + being the last 0)and +\family typewriter +jtrans_init() +\family default +, then add an operation with +\family typewriter +jtrans_add() +\family default + (the last 0 is the offset, in this case the beginning of the file), commit + the transaction with +\family typewriter +jtrans_commit() +\family default +, and finally close the file with +\family typewriter +jclose() +\family default +. +\layout Section + +Advanced functions +\layout Subsection + +Interaction with reads +\begin_inset LatexCommand \label{sub:Interaction-with-reads} + +\end_inset + + +\layout Standard + +So far we've seen how to use the library to perform writes, but what about + reads? The only and main issue with reads is that, because we provide transacti +on atomicity, a read must never be able to +\begin_inset Quotes eld +\end_inset + +see +\begin_inset Quotes erd +\end_inset + + a transaction partially applied. + This is achieved internally by using fine-grained file locks; but you shouldn't + mind about it if you use the functions the library gives you because they + take care of all the locking. +\layout Standard + +This set of functions are very similar to the UNIX ones ( +\family typewriter +read() +\family default +, +\family typewriter +readv() +\family default +, etc.); and in fact are named after them: they're called +\family typewriter +jread() +\family default +, +\family typewriter +jreadv() +\family default + and +\family typewriter +jpread() +\family default +; and have the same parameters except for the first one, which instead of + a file descriptor is a file structure +\begin_inset Foot +collapsed false + +\layout Standard + +In fact, this set of functions is a part of what is called the +\begin_inset Quotes eld +\end_inset + +UNIX API +\begin_inset Quotes erd +\end_inset + +, which is described below. +\end_inset + +. + Bear in mind that transactions are only visible by reads +\emph on +after +\emph default + you commit them with +\family typewriter +jtrans_commit() +\family default +. +\layout Subsection + +Rollback +\layout Standard + +There is a very nice and important feature in transactions, that allow them + to be +\begin_inset Quotes eld +\end_inset + +undone +\begin_inset Quotes erd +\end_inset + +, which means that you can undo a transaction and leave the file just as + it was the moment before applying it. + The action of undoing it is called to +\emph on +rollback +\emph default +, and the function is called +\family typewriter +jtrans_rollback() +\family default +, which takes the transaction as the only parameter. +\layout Standard + +Be aware that rollbacking a transaction can be dangerous if you're not careful + and cause you a lot of troubles. + For instance, consider you have two transactions (let's call them 1 and + 2, and assume they were applied in that order) that modify the same offset, + and you rollback transaction 1; then 2 would be lost. + It is not an dangerous operation itself, but its use requires care and + thought. +\layout Subsection + +Integrity checking and recovery +\layout Standard + +An essential part of the library is taking care of recovering from crashes + and be able to assure a file is consistent. + When you're working with the file, this is taking care of; but what when + you first open it? To answer that question, the library provides you with + a function named +\family typewriter +jfsck() +\family default +, which checks the integrity of a file and makes sure that everything is + consistent. + It must be called +\begin_inset Quotes eld +\end_inset + +offline +\begin_inset Quotes erd +\end_inset + +, that is when you are not actively committing and rollbacking; it is normally + done before calling +\family typewriter +jopen() +\family default +. + Another good practise is call jfsck_cleanup() after calling jfsck() to + make sure we're starting up with a fresh clean journal. + After both calls, it is safe to assume that the file is and ready to use. +\layout Standard + +You can also do this manually with an utility named +\emph on +jiofsck +\emph default +, which can be used from the shell to perform the checking and cleanup. +\layout Subsection + +Lingering transactions +\layout Standard + +If you need to increase performance, you can use lingering transactions. + In this mode, transactions take up more disk space but allows you to do + the synchronous write only once, making commits much faster. + To use them, just add +\family typewriter +J_LINGER +\family default + to the jflags parameter in +\family typewriter +jopen() +\family default +. + It is very wise to call +\family typewriter +jsync() +\family default + frequently to avoid using up too much space. +\layout Section + +Disk layout +\layout Standard + +The library creates a single directory for each file opened, named after + it. + So if we open a file +\begin_inset Quotes eld +\end_inset + +output +\begin_inset Quotes erd +\end_inset + +, a directory named +\begin_inset Quotes eld +\end_inset + +.output.jio +\begin_inset Quotes erd +\end_inset + + will be created. + We call it the +\emph on +journal directory +\emph default +, and it's used internally by the library to save temporary data; you shouldn't + modify any of the files that are inside it, or move it while it's in use. + It doesn't grow much (it only uses space for transactions that are in the + process of committing) and gets automatically cleaned while working with + it so you can (and should) ignore it. + Besides that, the file you work with has no special modification and is + just like any other file, all the internal stuff is kept isolated on the + journal directory. +\layout Section + +Other APIs +\layout Standard + +We're all used to do things our way, and when we learn something new it's + often better if it looks alike what we already know. + With this in mind, the library comes with two sets of APIs that look a + lot like traditional, well known ones. + Bear in mind that they are not as powerful as the transaction API that + is described above, and they can't provide the same functionality in a + lot of cases; however for a lot of common and simple use patterns they + are good enough. +\layout Subsection + +UNIX API +\layout Standard + +There is a set of functions that emulate the UNIX API ( +\family typewriter +read() +\family default +, +\family typewriter +write() +\family default +, and so on) which make each operation a transaction. + This can be useful if you don't need to have the full power of the transactions + but only to provide guarantees between the different functions. + They are a lot like the normal UNIX functions, but instead of getting a + file descriptor as their first parameter, they get a file structure. + You can check out the manual page to see the details, but they work just + like their UNIX version, only that they preserve atomicity and thread-safety + +\emph on +within each call +\emph default +. +\layout Standard + +In particular, the group of functions related to reading (which was described + above in +\begin_inset LatexCommand \ref{sub:Interaction-with-reads} + +\end_inset + +) are extremely useful because they take care of the locking needed for + the library proper behaviour. + You should use them instead of the regular calls. +\layout Standard + +The full function list is available on the man page and I won't reproduce + it here; however the naming is quite simple: just prepend a 'j' to all + the names: +\family typewriter +jread() +\family default +, +\family typewriter +jwrite() +\family default +, etc. +\layout Subsection + +ANSI C API +\layout Standard + +Besides the UNIX API you can find an ANSI C API, which emulates the traditional + +\family typewriter +fread() +\family default +, +\family typewriter +fwrite() +\family default +, etc. + They're still in development and has not been tested carefully, so I won't + spend time documenting them. + Let me know if you need them. +\layout Section + +Where to go from here +\layout Standard + +If you're still interested in learning more, you can find some small and + clean samples are in the +\begin_inset Quotes eld +\end_inset + +samples +\begin_inset Quotes erd +\end_inset + + directory (full.c is a simple and complete one), other more advanced examples + can be found in the web page, as well as modifications to well known software + to make use of the library. + For more information about the inner workings of the library, you can read + the +\begin_inset Quotes eld +\end_inset + +libjio +\begin_inset Quotes erd +\end_inset + + document, and the source code. +\the_end diff --git a/doc/guide.txt b/doc/guide.txt new file mode 100644 index 0000000..bcc0b01 --- /dev/null +++ b/doc/guide.txt @@ -0,0 +1,317 @@ +libjio Programmer's Guide + +Alberto Bertogli (albertogli@telpin.com.ar) + +Table of Contents + +1 Introduction +2 Definitions +3 The data types +4 The basic functions +5 Advanced functions + 5.1 Interaction with reads + 5.2 Rollback + 5.3 Integrity checking and recovery + 5.4 Lingering transactions +6 Disk layout +7 Other APIs + 7.1 UNIX API + 7.2 ANSI C API +8 Where to go from here + + + +1 Introduction + +This small document attempts serve as a guide to the +programmer who wants to make use of the library. It's +not a replacement for the man page or reading the code; +but it's a good starting point for everyone who wants +to get involved with it. + +The library is not complex to use at all, and the +interfaces were designed to be as intuitive as +possible, so the text is structured as a guide to +present the reader all the common structures and +functions the way they're normally used. + +2 Definitions + +This is a library which provides a journaled +transaction-oriented I/O API. You've probably read this +a hundred times already in the documents, and if you +haven't wondered yet what on earth does this mean you +should be reading something else! + +We say this is a transaction-oriented API because we +make transactions the center of our operations, and +journaled because we use a journal (which takes the +form of a directory with files on it) to guarantee +coherency even after a crash at any point. + +Here we think a transaction as a list of (buffer, +length, offset) to be applied to a file. That triple is +called an operation, so we can say that a transaction +represent an ordered group of operations on the same file. + +The act of committing a transaction means writing all +the elements of the list; and rollbacking means to undo +a previous commit, and leave the data just as it was +before doing the commit.While all this definitions may seem obvious to some +people, it requires special attention because there are +a lot of different definitions, and it's not that +common to see "transaction" applied to file I/O (it's a +term used mostly on database stuff), so it's important +to clarify before continuing. + +It's important to note that the library not only +provides a convenient and easy API to perform this kind +of operations, but provides a lot of guarantees while +doing this. The most relevant and useful is that at any +point of time, even if we crash horribly, a transaction +will be either fully applied or not applied at all. You +should not ever see partial transactions or any kind of +data corruption. + +To achieve this, the library uses what is called a +journal, a very vague (and fashionable) term we use to +describe a set of auxiliary files that get created to +store temporary data at several stages. The proper +definition and how we use them is outside the scope of +this document, and you as a programmer shouldn't need +to deal with it. In case you're curious, it's described +in a bit more detail in another text which talks about +how the library works internally. Now let's get real. + +3 The data types + +To understand any library, it's essential to be +confident in the knowledge of their data structures and +how they relate each other. In libjio we have two basic +structures which have a very strong relationship, and +represent the essential objects we deal with. Note that +you normally don't manipulate them directly, because +they have their own initializer functions, but they are +the building blocks for the rest of the text, which, +once this is understood, is obvious and self-evident. + +The first structure we face is struct jfs, called the +file structure, and it represents an open file, just +like a regular file descriptor or a FILE *. + +Then you find struct jtrans, called the transaction +structure, which represents a single transaction. You +can have as many transactions as you want, and operate +on all of them simultaneously without problems; the +library is entirely thread safe so there's no need to +worry about that. + +4 The basic functions + +Now that we've described our data types, let's see how +we can really operate with the library. + +First of all, as with regular I/O, you need to open +your files. This is done with jopen(), which looks a +lot like open() but takes a file structure instead of a +file descriptor (this will be very common among all the +functions), and adds a new parameter jflags that can be +used to modify some subtle library behaviour we'll see +later, and it's normally not used. + +We have a happy file structure open now, and the next +thing to do would be to create a transaction. This is +what jtrans_init() is for: it takes a file structure +and a transaction structure and initializes the latter, +leaving it ready to use. + +So we have our transaction, let's add a write operation +to it; to do this we use jtrans_add(). We could keep on +adding operations to the transaction by keep on calling +jtrans_add() as many times as we want. + +Finally, we decide to apply our transaction to the +file, that is, write all the operations we've added. +And this is the easiest part: we call jtrans_commit(), +and that's it! + +When we're done using the file, we call jclose(), just +like we call close(). + +Let's put it all together and code a nice "hello world" +program (return values are ignored for simplicity): + +char buf[] = "Hello world!"; + +struct jfs file; + +struct jtrans trans; + + + +jopen(&file, "filename", O_RDWR | O_CREAT, 0600, 0); + +jtrans_init(&file, &trans); + + + +jtrans_add(&trans, buf, strlen(buf), 0); + + + +jtrans_commit(&trans); + + + +jclose(&file); + +As we've seen, we open the file and initialize the +structure with jopen() (with the parameter jflags being +the last 0)and jtrans_init(), then add an operation +with jtrans_add() (the last 0 is the offset, in this +case the beginning of the file), commit the transaction +with jtrans_commit(), and finally close the file with jclose(). + +5 Advanced functions + +5.1 Interaction with reads<sub:Interaction-with-reads> + +So far we've seen how to use the library to perform +writes, but what about reads? The only and main issue +with reads is that, because we provide transaction +atomicity, a read must never be able to "see" a +transaction partially applied. This is achieved +internally by using fine-grained file locks; but you +shouldn't mind about it if you use the functions the +library gives you because they take care of all the locking. + +This set of functions are very similar to the UNIX ones +(read(), readv(), etc.); and in fact are named after +them: they're called jread(), jreadv() and jpread(); +and have the same parameters except for the first one, +which instead of a file descriptor is a file structureIn fact, this set of functions is a part of what is +called the "UNIX API", which is described below. +. Bear in mind that transactions are only visible by +reads after you commit them with jtrans_commit(). + +5.2 Rollback + +There is a very nice and important feature in +transactions, that allow them to be "undone", which means +that you can undo a transaction and leave the file just +as it was the moment before applying it. The action of +undoing it is called to rollback, and the function is +called jtrans_rollback(), which takes the transaction +as the only parameter. + +Be aware that rollbacking a transaction can be +dangerous if you're not careful and cause you a lot of +troubles. For instance, consider you have two +transactions (let's call them 1 and 2, and assume they +were applied in that order) that modify the same +offset, and you rollback transaction 1; then 2 would be +lost. It is not an dangerous operation itself, but its +use requires care and thought. + +5.3 Integrity checking and recovery + +An essential part of the library is taking care of +recovering from crashes and be able to assure a file is +consistent. When you're working with the file, this is +taking care of; but what when you first open it? To +answer that question, the library provides you with a +function named jfsck(), which checks the integrity of a +file and makes sure that everything is consistent. It +must be called "offline", that is when you are not +actively committing and rollbacking; it is normally +done before calling jopen(). Another good practise is +call jfsck_cleanup() after calling jfsck() to make sure +we're starting up with a fresh clean journal. After +both calls, it is safe to assume that the file is and +ready to use. + +You can also do this manually with an utility named +jiofsck, which can be used from the shell to perform +the checking and cleanup. + +5.4 Lingering transactions + +If you need to increase performance, you can use +lingering transactions. In this mode, transactions take +up more disk space but allows you to do the synchronous +write only once, making commits much faster. To use +them, just add J_LINGER to the jflags parameter in +jopen(). It is very wise to call jsync() frequently to +avoid using up too much space. + +6 Disk layout + +The library creates a single directory for each file +opened, named after it. So if we open a file "output", a +directory named ".output.jio" will be created. We call it +the journal directory, and it's used internally by the +library to save temporary data; you shouldn't modify +any of the files that are inside it, or move it while +it's in use. It doesn't grow much (it only uses space +for transactions that are in the process of committing) +and gets automatically cleaned while working with it so +you can (and should) ignore it. Besides that, the file +you work with has no special modification and is just +like any other file, all the internal stuff is kept +isolated on the journal directory. + +7 Other APIs + +We're all used to do things our way, and when we learn +something new it's often better if it looks alike what +we already know. With this in mind, the library comes +with two sets of APIs that look a lot like traditional, +well known ones. Bear in mind that they are not as +powerful as the transaction API that is described +above, and they can't provide the same functionality in +a lot of cases; however for a lot of common and simple +use patterns they are good enough. + +7.1 UNIX API + +There is a set of functions that emulate the UNIX API +(read(), write(), and so on) which make each operation +a transaction. This can be useful if you don't need to +have the full power of the transactions but only to +provide guarantees between the different functions. +They are a lot like the normal UNIX functions, but +instead of getting a file descriptor as their first +parameter, they get a file structure. You can check out +the manual page to see the details, but they work just +like their UNIX version, only that they preserve +atomicity and thread-safety within each call. + +In particular, the group of functions related to +reading (which was described above in [sub:Interaction-with-reads]) are extremely +useful because they take care of the locking needed for +the library proper behaviour. You should use them +instead of the regular calls. + +The full function list is available on the man page and +I won't reproduce it here; however the naming is quite +simple: just prepend a 'j' to all the names: jread(), +jwrite(), etc. + +7.2 ANSI C API + +Besides the UNIX API you can find an ANSI C API, which +emulates the traditional fread(), fwrite(), etc. +They're still in development and has not been tested +carefully, so I won't spend time documenting them. Let +me know if you need them. + +8 Where to go from here + +If you're still interested in learning more, you can +find some small and clean samples are in the "samples" +directory (full.c is a simple and complete one), other +more advanced examples can be found in the web page, as +well as modifications to well known software to make +use of the library. For more information about the +inner workings of the library, you can read the "libjio" +document, and the source code. diff --git a/doc/libjio.3 b/doc/libjio.3 index 99036bb..6965444 100644 --- a/doc/libjio.3 +++ b/doc/libjio.3 @@ -22,6 +22,8 @@ libjio - A library for Journaled I/O .BI "int jtruncate(struct jfs *" fs ", off_t " lenght " ); +.BI "int jsync(struct jfs *" fs " ); + .BI "int jclose(struct jfs *" fs " ); .BI "void jtrans_init(struct jfs *" fs " , struct jtrans *" ts " ); @@ -185,4 +187,5 @@ albertogli@telpin.com.ar. .BR pread (2), .BR pwrite (2), .BR ftruncate (2), +.BR fsync (2), .BR close (2) diff --git a/doc/libjio.lyx b/doc/libjio.lyx index 0503ecd..8c4081e 100644 --- a/doc/libjio.lyx +++ b/doc/libjio.lyx @@ -56,6 +56,8 @@ This document explains the design of the library, how it works internally ways, it provides (or at least tries to =) an insight view on how the library performs its job, which can be very valuable knowledge when working with it. + It assumes that there is some basic knowledge about how the library is + used, which can be found in the manpage or in the programmer's guide. \layout Standard To the user, libjio provides two groups of functions, one UNIX-alike that @@ -83,7 +85,7 @@ write() The following sections describe different concepts and procedures that the library bases its work on. It's not intended to be a replace to reading the source code: please do - so if you have any doubts, it's not big at all (less than 800 lines, including + so if you have any doubts, it's not big at all (less than 1500 lines, including comments) and I hope it's readable enough. If you think that's not the case, please let me know and I'll try to give you a hand. @@ -131,18 +133,12 @@ The transaction file is composed of two main parts: the header and the payload. \layout Standard The header holds basic information about the transaction itself, including - the ID, some flags, the offset to commit to and the lenght of the data. - The payload holds the data, in three parts: user-defined data, previous - data, and real data. -\layout Standard - -User-defined data is not used by the library itself, but it's a space where - the user can save private data that can be useful later. - Previous data is saved by the library prior applying the commit, so transaction -s can be rollbacked. - Real data is just the data to save to the disk, and it is saved because - if a crash occurs when while we are applying the transaction we can recover - gracefuly. + the ID, some flags, and the amount of operations it includes. + Then the payload has all the operations one after the other, divided in + two parts: the first one includes static information about the operation + (the lenght of the data, the offset of the file where it should be applied, + etc.) and the data itself, which is saved by the library prior applying + the commit, so transactions can be rollbacked. \layout Section The commit procedure @@ -165,7 +161,7 @@ safely \emph default , means that after a commit has been done we can assume the data will not get lost and can be retrieved, unless of course some major event happens - (like a hardware failure). + (like a physical hard disk crash). For us, this means that the data was effectively written to the disk and if a crash occurs after the commit operation has returned, the operation will be complete and data will be available from the file. @@ -175,7 +171,7 @@ The latter, \emph on atomically \emph default -, warantees that the operation is either completely done, or not done at +, guarantees that the operation is either completely done, or not done at all. This is a really common word, specially if you have worked with multiprocessing , and should be quite familiar. @@ -193,7 +189,7 @@ jtrans_commit() : \layout Itemize -Lock the section where the commit takes place +Lock the file offsets where the commit takes place \layout Itemize Open the transaction file @@ -202,10 +198,7 @@ Open the transaction file Write the header \layout Itemize -Write the user data (if any) -\layout Itemize - -Read the previous data from the file +Read all the previous data from the file \layout Itemize Write the previous data in the transaction @@ -220,7 +213,7 @@ Mark the transaction as commited by setting a flag in the header Unlink the transaction file \layout Itemize -Unlock the section where the commit takes place +Unlock the offsets where the commit takes place \layout Standard This may look as a lot of steps, but they're not as much as it looks like @@ -245,8 +238,8 @@ undo and straightforward. \layout Standard -In the previous section we said that each transaction held, besides the - data to commit to the disk, the data that was on it before commiting. +In the previous section we said that each transaction held the data that + was on it before commiting. That data is saved precisely to be able to rollback. So, to rollback a transaction all that has to be done is recover that \begin_inset Quotes eld @@ -332,15 +325,15 @@ In any case, after making the recovery you can simply remove the journal transaction atomicity was preserved. \layout Section -High-level functions +UNIX API \layout Standard We call \emph on -high-level functions +UNIX API \emph default - to the ones provided by the library that emulate the good old unix file - manipulation calls. + to the functions provided by the library that emulate the good old UNIX + file manipulation calls. Most of them are just wrappers around commits, and implement proper locking when operating in order to allow simultaneous operations (either across threads or processes).