SQLite4
Check-in [2377f4f991]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add lsmapi.wiki. And the script that generates it from lsm.h - tool/mklsmapi.tcl.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2377f4f9912342e85bf0adccfe29015555526185
User & Date: dan 2012-11-13 18:44:08
Context
2012-11-13
20:16
Further documentation updates. check-in: 414ed6da4e user: dan tags: trunk
18:44
Add lsmapi.wiki. And the script that generates it from lsm.h - tool/mklsmapi.tcl. check-in: 2377f4f991 user: dan tags: trunk
14:03
Add table of contents to lsmusr.wiki. check-in: 71b26d318d user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/lsm.h.

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129


130
131
132
133
134
135
136







137
138
139
140
141
142
143







144


145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249










250

251


252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379


380

381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411
412


413
414
415
416
417
418
419
...
428
429
430
431
432
433
434



















































































































































435
436
437
438
439
440
441
...
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595

596
597
598
599
  /****** other ****************************************************/
  int (*xSleep)(lsm_env*, int microseconds);

  /* New fields may be added in future releases, in which case the
  ** iVersion value will increase. */
};

/*
** The compression library interface.
*/
struct lsm_compress {
  int nByte;                 /* Size of this structure in bytes */
  int iVersion;              /* Version number of this structure (1) */

  /* Compression library functions */
  void *pCtx;
  int (*xBound)(void *, int nSrc);
  int (*xCompress)(void *, char *, int *, const char *, int);
  int (*xUncompress)(void *, char *, int *, const char *, int);

  /* New fields may be added in future releases, in which case the
  ** iVersion value will increase. */
};

/* 
** Values that may be passed as the second argument to xMutexStatic. 
*/
#define LSM_MUTEX_GLOBAL 1
#define LSM_MUTEX_HEAP   2

/*
** Return a pointer to the default LSM run-time environment
*/
lsm_env *lsm_default_env(void);

/*
** Error codes.
*/
#define LSM_OK         0
#define LSM_ERROR      1
#define LSM_BUSY       5
#define LSM_NOMEM      7
#define LSM_IOERR     10
#define LSM_CORRUPT   11
#define LSM_FULL      13
#define LSM_CANTOPEN  14
#define LSM_PROTOCOL  15
#define LSM_MISUSE    21

/* 


** Open and close a connection to a named database.
*/
int lsm_new(lsm_env*, lsm_db **ppDb);
int lsm_open(lsm_db *pDb, const char *zFilename);
int lsm_close(lsm_db *pDb);

/*







** Return a pointer to the environment used by the database connection 
** passed as the first argument. Assuming the argument is valid, this 
** function always returns a valid environment pointer - it cannot fail.
*/
lsm_env *lsm_get_env(lsm_db *pDb);

/*







** Configure a database connection.


*/
int lsm_config(lsm_db *, int, ...);

/*
** The following values may be passed as the second argument to lsm_config().
**
**   LSM_CONFIG_WRITE_BUFFER
**     A read/write integer parameter. This value determines the maximum amount
**     of space (in bytes) used to accumulate writes in main-memory before 
**     they are flushed to a level 0 segment.
**
**   LSM_CONFIG_PAGE_SIZE
**     A read/write integer parameter. This parameter may only be set before
**     lsm_open() has been called.
**
**   LSM_CONFIG_BLOCK_SIZE
**     A read/write integer parameter. This parameter may only be set before
**     lsm_open() has been called.
**
**   LSM_CONFIG_LOG_SIZE
**     A read/write integer parameter.
**
**   LSM_CONFIG_SAFETY
**     A read/write integer parameter. Valid values are 0, 1 (the default) 
**     and 2. This parameter determines how robust the database is in the
**     face of a system crash (e.g. a power failure or operating system 
**     crash). As follows:
**
**       0 (off):    No robustness. A system crash may corrupt the database.
**
**       1 (normal): Some robustness. A system crash may not corrupt the
**                   database file, but recently committed transactions may
**                   be lost following recovery.
**
**       2 (full):   Full robustness. A system crash may not corrupt the
**                   database file. Following recovery the database file
**                   contains all successfully committed transactions.
**
**   LSM_CONFIG_AUTOWORK
**     A read/write integer parameter.
**
**   LSM_CONFIG_AUTOCHECKPOINT
**     A read/write integer parameter.
**
**   LSM_CONFIG_MMAP
**     A read/write integer parameter. True to use mmap() to access the 
**     database file. False otherwise.
**
**   LSM_CONFIG_USE_LOG
**     A read/write boolean parameter. True (the default) to use the log
**     file normally. False otherwise.
**
**   LSM_CONFIG_NMERGE
**     A read/write integer parameter. The minimum number of segments to
**     merge together at a time. Default value 4.
**
**   LSM_CONFIG_MAX_FREELIST
**     A read/write integer parameter. The maximum number of free-list 
**     entries that are stored in a database checkpoint (the others are
**     stored elsewhere in the database).
**
**     There is no reason for an application to configure or query this
**     parameter. It is only present because configuring a small value
**     makes certain parts of the lsm code easier to test.
**
**   LSM_CONFIG_MULTIPLE_PROCESSES
**     A read/write boolean parameter. This parameter may only be set before
**     lsm_open() has been called. If true, the library uses shared-memory
**     and posix advisory locks to co-ordinate access by clients from within
**     multiple processes. Otherwise, if false, all database clients must be 
**     located in the same process. The default value is true.
**
**   LSM_CONFIG_SET_COMPRESSION
**     Set the compression methods used to compress and decompress database
**     content. The argument to this option should be a pointer to a structure
**     of type lsm_compress. The lsm_config() method takes a copy of the 
**     structures contents.
**
**     This option may only be used before lsm_open() is called. Invoking it
**     after lsm_open() has been called results in an LSM_MISUSE error.
**
**   LSM_CONFIG_GET_COMPRESSION
**     Query the compression methods used to compress and decompress database
**     content.
*/
#define LSM_CONFIG_WRITE_BUFFER        1
#define LSM_CONFIG_PAGE_SIZE           2
#define LSM_CONFIG_SAFETY              3
#define LSM_CONFIG_BLOCK_SIZE          4
#define LSM_CONFIG_AUTOWORK            5
#define LSM_CONFIG_LOG_SIZE            6
#define LSM_CONFIG_MMAP                7
#define LSM_CONFIG_USE_LOG             8
#define LSM_CONFIG_NMERGE              9
#define LSM_CONFIG_MAX_FREELIST       10
#define LSM_CONFIG_MULTIPLE_PROCESSES 11
#define LSM_CONFIG_AUTOCHECKPOINT     12

#define LSM_CONFIG_SET_COMPRESSION    13
#define LSM_CONFIG_GET_COMPRESSION    14

#define LSM_SAFETY_OFF    0
#define LSM_SAFETY_NORMAL 1
#define LSM_SAFETY_FULL   2













/*


** Invoke the memory allocation functions that belong to environment
** pEnv. Or the system defaults if no memory allocation functions have 
** been registered.
*/
void *lsm_malloc(lsm_env*, size_t);
void *lsm_realloc(lsm_env*, void *, size_t);
void lsm_free(lsm_env*, void *);

/*
** Configure a callback to which debugging and other messages should 
** be directed. Only useful for debugging lsm.
*/
void lsm_config_log(lsm_db *, void (*)(void *, int, const char *), void *);

/*
** Configure a callback that is invoked if the database connection ever
** writes to the database file.
*/
void lsm_config_work_hook(lsm_db *, void (*)(lsm_db *, void *), void *);

/*
** Query a database connection for operational statistics or data.
*/
int lsm_info(lsm_db *, int, ...);

/*
** The following values may be passed as the second argument to lsm_info().
**
**   LSM_INFO_NWRITE
**     The third parameter should be of type (int *). The location pointed
**     to by the third parameter is set to the number of 4KB pages written to
**     the database file during the lifetime of this connection. 
**
**   LSM_INFO_NREAD
**     The third parameter should be of type (int *). The location pointed
**     to by the third parameter is set to the number of 4KB pages read from
**     the database file during the lifetime of this connection.
**
**   LSM_INFO_DB_STRUCTURE
**     The third argument should be of type (char **). The location pointed
**     to is populated with a pointer to a nul-terminated string containing
**     the string representation of a Tcl data-structure reflecting the 
**     current structure of the database file. Specifically, the current state
**     of the worker snapshot. The returned string should be eventually freed 
**     by the caller using lsm_free().
**
**     The returned list contains one element for each level in the database,
**     in order from most to least recent. Each element contains a 
**     single element for each segment comprising the corresponding level,
**     starting with the lhs segment, then each of the rhs segments (if any)
**     in order from most to least recent.
**
**     Each segment element is itself a list of 6 integer values, as follows:
**
**        1. First page of segment
**        2. Last page of segment
**        3. Root page of segment (if applicable).
**        4. Total number of pages in segment.

**
**   LSM_INFO_ARRAY_STRUCTURE
**     There should be two arguments passed following this option (i.e. a 
**     total of four arguments passed to lsm_info()). The first argument 
**     should be the page number of the first page in a database array 
**     (perhaps obtained from an earlier INFO_DB_STRUCTURE call). The second 
**     trailing argument should be of type (char **). The location pointed 
**     to is populated with a pointer to a nul-terminated string that must 
**     be eventually freed using lsm_free() by the caller.
**
**     The output string contains the text representation of a Tcl list of
**     integers. Each pair of integers represent a range of pages used by
**     the identified array. For example, if the array occupies database
**     pages 993 to 1024, then pages 2048 to 2777, then the returned string
**     will be "993 1024 2048 2777".
**
**     If the specified integer argument does not correspond to the first
**     page of any database array, LSM_ERROR is returned and the output
**     pointer is set to a NULL value.
**
**   LSM_INFO_LOG_STRUCTURE
**     The third argument should be of type (char **). The location pointed
**     to is populated with a pointer to a nul-terminated string containing
**     the string representation of a Tcl data-structure. The returned 
**     string should be eventually freed by the caller using lsm_free().
**
**     The Tcl structure returned is a list of six integers that describe
**     the current structure of the log file.
**
**   LSM_INFO_ARRAY_PAGES
**
**     
**
**   LSM_INFO_PAGE_ASCII_DUMP
**     As with LSM_INFO_ARRAY_STRUCTURE, there should be two arguments passed
**     with calls that specify this option - an integer page number and a
**     (char **) used to return a nul-terminated string that must be later
**     freed using lsm_free(). In this case the output string is populated
**     with a human-readable description of the page content.
**
**     If the page cannot be decoded, it is not an error. In this case the
**     human-readable output message will report the systems failure to 
**     interpret the page data.
**
**   LSM_INFO_PAGE_HEX_DUMP
**     This argument is similar to PAGE_ASCII_DUMP, except that keys and
**     values are represented using hexadecimal notation instead of ascii.
**
**   LSM_INFO_FREELIST
**     The third argument should be of type (char **). The location pointed
**     to is populated with a pointer to a nul-terminated string containing
**     the string representation of a Tcl data-structure. The returned 
**     string should be eventually freed by the caller using lsm_free().
**
**     The Tcl structure returned is a list containing one element for each
**     free block in the database. The element itself consists of two 
**     integers - the block number and the id of the snapshot that freed it.
*/
#define LSM_INFO_NWRITE           1
#define LSM_INFO_NREAD            2
#define LSM_INFO_DB_STRUCTURE     3
#define LSM_INFO_LOG_STRUCTURE    4
#define LSM_INFO_ARRAY_STRUCTURE  5
#define LSM_INFO_PAGE_ASCII_DUMP  6
#define LSM_INFO_PAGE_HEX_DUMP    7
#define LSM_INFO_FREELIST         8
#define LSM_INFO_ARRAY_PAGES      9


/* 


** Open and close transactions and nested transactions.

**
** lsm_begin()
**   Used to open transactions and sub-transactions. A successful call to 
**   lsm_begin() ensures that there are at least iLevel nested transactions 
**   open. To open a top-level transaction, pass iLevel==1. To open a 
**   sub-transaction within the top-level transaction, iLevel==2. Passing 
**   iLevel==0 is a no-op.
**
** lsm_commit()
**   Used to commit transactions and sub-transactions. A successful call 
**   to lsm_commit() ensures that there are at most iLevel nested 
**   transactions open. To commit a top-level transaction, pass iLevel==0. 
**   To commit all sub-transactions inside the main transaction, pass
**   iLevel==1.
**
** lsm_rollback()
**   Used to roll back transactions and sub-transactions. A successful call 
**   to lsm_rollback() restores the database to the state it was in when
**   the iLevel'th nested sub-transaction (if any) was first opened. And then
**   closes transactions to ensure that there are at most iLevel nested
**   transactions open.
**

**   Passing iLevel==0 rolls back and closes the top-level transaction.
**   iLevel==1 also rolls back the top-level transaction, but leaves it
**   open. iLevel==2 rolls back the sub-transaction nested directly inside
**   the top-level transaction (and leaves it open).
*/
int lsm_begin(lsm_db *pDb, int iLevel);
int lsm_commit(lsm_db *pDb, int iLevel);
int lsm_rollback(lsm_db *pDb, int iLevel);

/* 


** Write a new value into the database. If a value with a duplicate key 
** already exists it is replaced.
*/
int lsm_insert(lsm_db*, const void *pKey, int nKey, const void *pVal, int nVal);

/*
** Delete a value from the database. No error is returned if the specified
................................................................................
**
** Return LSM_OK if successful, or an LSM error code otherwise.
*/
int lsm_delete_range(lsm_db *, 
    const void *pKey1, int nKey1, const void *pKey2, int nKey2
);




















































































































































/*
** The lsm_tree_size() function reports on the current state of the 
** in-memory tree data structure. 
**
** At any time, there are either one or two tree structures held in shared
** memory that new database clients will access (there may also be additional 
** tree structures being used by older clients - this API does not provide
................................................................................
**
** RACE CONDITION:
**   Describe the race condition this function is subject to. Or remove
**   it somehow.
*/
int lsm_ckpt_size(lsm_db *, int *pnByte);

/*
** This function is called by a thread to work on the database structure.
*/
int lsm_work(lsm_db *pDb, int nMerge, int nPage, int *pnWrite);

int lsm_flush(lsm_db *pDb);

/*
** Attempt to checkpoint the current database snapshot. Return an LSM
** error code if an error occurs or LSM_OK otherwise.
**
** If the current snapshot has already been checkpointed, calling this 
** function is a no-op. In this case if pnByte is not NULL, *pnByte is
** set to 0. Or, if the current snapshot is successfully checkpointed
** by this function and pbCkpt is not NULL, *pnByte is set to the number
** of bytes written to the database file since the previous checkpoint
** (the same measure as returned by lsm_ckpt_size()).
*/
int lsm_checkpoint(lsm_db *pDb, int *pnByte);

/*
** Open and close a database cursor.
*/
int lsm_csr_open(lsm_db *pDb, lsm_cursor **ppCsr);
int lsm_csr_close(lsm_cursor *pCsr);

/* 
** If the fourth parameter is LSM_SEEK_EQ, LSM_SEEK_GE or LSM_SEEK_LE,
** this function searches the database for an entry with key (pKey/nKey). 
** If an error occurs, an LSM error code is returned. Otherwise, LSM_OK.
**
** If no error occurs and the requested key is present in the database, the
** cursor is left pointing to the entry with the specified key. Or, if the 
** specified key is not present in the database the state of the cursor 
** depends on the value passed as the final parameter, as follows:
**
**   LSM_SEEK_EQ:
**     The cursor is left at EOF (invalidated). A call to lsm_csr_valid()
**     returns non-zero.
**
**   LSM_SEEK_LE:
**     The cursor is left pointing to the largest key in the database that
**     is smaller than (pKey/nKey). If the database contains no keys smaller
**     than (pKey/nKey), the cursor is left at EOF.
**
**   LSM_SEEK_GE:
**     The cursor is left pointing to the smallest key in the database that
**     is larger than (pKey/nKey). If the database contains no keys larger
**     than (pKey/nKey), the cursor is left at EOF.
**
** If the fourth parameter is LSM_SEEK_LEFAST, this function searches the
** database in a similar manner to LSM_SEEK_LE, with two differences:
**
**   1) Even if a key can be found (the cursor is not left at EOF), the
**      lsm_csr_value() function may not be used (attempts to do so return
**      LSM_MISUSE).
**
**   2) The key that the cursor is left pointing to may be one that has 
**      been recently deleted from the database. In this case it is guaranteed
**      that the returned key is larger than any key currently in the database
**      that is less than or equal to (pKey/nKey).
**
** LSM_SEEK_LEFAST requests are intended to be used to allocate database
** keys.
*/
int lsm_csr_seek(lsm_cursor *pCsr, const void *pKey, int nKey, int eSeek);

/*
** Values that may be passed as the fourth argument to lsm_csr_seek().
*/
#define LSM_SEEK_LEFAST   -2
#define LSM_SEEK_LE       -1
#define LSM_SEEK_EQ        0
#define LSM_SEEK_GE        1

int lsm_csr_first(lsm_cursor *pCsr);
int lsm_csr_last(lsm_cursor *pCsr);

/*
** Advance the specified cursor to the next or previous key in the database.
** Return LSM_OK if successful, or an LSM error code otherwise.
**
** Functions lsm_csr_seek(), lsm_csr_first() and lsm_csr_last() are "seek"
** functions. Whether or not lsm_csr_next and lsm_csr_prev may be called
** successfully also depends on the most recent seek function called on
** the cursor. Specifically:
**
**   * At least one seek function must have been called on the cursor.
**
**   * To call lsm_csr_next(), the most recent call to a seek function must
**     have been either lsm_csr_first() or a call to lsm_csr_seek() specifying
**     LSM_SEEK_GE. 
**
**   * To call lsm_csr_prev(), the most recent call to a seek function must
**     have been either lsm_csr_first() or a call to lsm_csr_seek() specifying
**     LSM_SEEK_GE. 
**
** Otherwise, if the above conditions are not met when lsm_csr_next or 
** lsm_csr_prev is called, LSM_MISUSE is returned and the cursor position
** remains unchanged.
*/
int lsm_csr_next(lsm_cursor *pCsr);
int lsm_csr_prev(lsm_cursor *pCsr);

/* 
** Retrieve data from a database cursor.
*/
int lsm_csr_valid(lsm_cursor *pCsr);
int lsm_csr_key(lsm_cursor *pCsr, const void **ppKey, int *pnKey);
int lsm_csr_value(lsm_cursor *pCsr, const void **ppVal, int *pnVal);

/*
** If no error occurs, this function compares the database key passed via
** the pKey/nKey arguments with the key that the cursor passed as the first
** argument currently points to. If the cursors key is less than, equal to
** or greater than pKey/nKey, *piRes is set to less than, equal to or greater
** than zero before returning. LSM_OK is returned in this case.
**
** Or, if an error occurs, an LSM error code is returned and the final 
** value of *piRes is undefined. If the cursor does not point to a valid
** key when this function is called, LSM_MISUSE is returned.
*/
int lsm_csr_cmp(lsm_cursor *pCsr, const void *pKey, int nKey, int *piRes);


#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif /* ifndef _LSM_H */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|
<
<
<
<
<













>
>
|


<


|
>
>
>
>
>
>
>







>
>
>
>
>
>
>
|
>
>






|
|
|
|

|
|
|

|
|
|

|
|

|
|
|
|
|

|

|
|
|

|
|
|

|
|

|
|

|
|
|

|
|
|

|
|
|

|
|
|
|

|
|
|

|
|
|
|
|
|

|
|
|
|
|

|
|

|
|
|













<







>
>
>
>
>
>
>
>
>
>

>

>
>









|
<
|
<
<
<
<
<
<
<
<
<







|
|
|
|

|
|
|
|

|
|
|
|
|
|
|

|
|
|
|
|

|

|
|
|
|
>

|
|
|
|
|
|
|
|

|
|
|
|
|

|
|
|

|
|
|
|
|

|
|

|

<
<
|
|
|
|
|
|

|
|
|

|
|
|

|
|
|
|
|

|
|
|













>
>
|
>

<
|
|
|
|
|

<
|
|
|
|
<

<
|
|
|
|
<
<
>
|
<
|
|






>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>




80
81
82
83
84
85
86

















87
88
89
90
91
92
93
94





95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268

269









270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338


339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380

381
382
383
384
385
386

387
388
389
390

391

392
393
394
395


396
397

398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
...
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
...
607
608
609
610
611
612
613




614























































































































615
616
617
618
619
  /****** other ****************************************************/
  int (*xSleep)(lsm_env*, int microseconds);

  /* New fields may be added in future releases, in which case the
  ** iVersion value will increase. */
};


















/* 
** Values that may be passed as the second argument to xMutexStatic. 
*/
#define LSM_MUTEX_GLOBAL 1
#define LSM_MUTEX_HEAP   2

/*
** CAPI: LSM Error Codes





*/
#define LSM_OK         0
#define LSM_ERROR      1
#define LSM_BUSY       5
#define LSM_NOMEM      7
#define LSM_IOERR     10
#define LSM_CORRUPT   11
#define LSM_FULL      13
#define LSM_CANTOPEN  14
#define LSM_PROTOCOL  15
#define LSM_MISUSE    21

/* 
** CAPI: Creating and Destroying Database Connection Handles
**
** Open and close a database connection handle.
*/
int lsm_new(lsm_env*, lsm_db **ppDb);

int lsm_close(lsm_db *pDb);

/* 
** CAPI: Connecting to a Database
*/
int lsm_open(lsm_db *pDb, const char *zFilename);

/*
** CAPI: Obtaining pointers to databases environments
**
** Return a pointer to the environment used by the database connection 
** passed as the first argument. Assuming the argument is valid, this 
** function always returns a valid environment pointer - it cannot fail.
*/
lsm_env *lsm_get_env(lsm_db *pDb);

/*
** The lsm_default_env() function returns a pointer to the default LSM
** environment for the current platform.
*/
lsm_env *lsm_default_env(void);


/*
** CAPI: Configuring a database connection.
**
** The lsm_config() function is used to configure a database connection.
*/
int lsm_config(lsm_db *, int, ...);

/*
** The following values may be passed as the second argument to lsm_config().
**
** LSM_CONFIG_WRITE_BUFFER:
**   A read/write integer parameter. This value determines the maximum amount
**   of space (in bytes) used to accumulate writes in main-memory before 
**   they are flushed to a level 0 segment.
**
** LSM_CONFIG_PAGE_SIZE:
**   A read/write integer parameter. This parameter may only be set before
**   lsm_open() has been called.
**
** LSM_CONFIG_BLOCK_SIZE:
**   A read/write integer parameter. This parameter may only be set before
**   lsm_open() has been called.
**
** LSM_CONFIG_LOG_SIZE:
**   A read/write integer parameter.
**
** LSM_CONFIG_SAFETY:
**   A read/write integer parameter. Valid values are 0, 1 (the default) 
**   and 2. This parameter determines how robust the database is in the
**   face of a system crash (e.g. a power failure or operating system 
**   crash). As follows:
**
**     0 (off):    No robustness. A system crash may corrupt the database.
**
**     1 (normal): Some robustness. A system crash may not corrupt the
**                 database file, but recently committed transactions may
**                 be lost following recovery.
**
**     2 (full):   Full robustness. A system crash may not corrupt the
**                 database file. Following recovery the database file
**                 contains all successfully committed transactions.
**
** LSM_CONFIG_AUTOWORK:
**   A read/write integer parameter.
**
** LSM_CONFIG_AUTOCHECKPOINT:
**   A read/write integer parameter.
**
** LSM_CONFIG_MMAP:
**   A read/write integer parameter. True to use mmap() to access the 
**   database file. False otherwise.
**
** LSM_CONFIG_USE_LOG:
**   A read/write boolean parameter. True (the default) to use the log
**   file normally. False otherwise.
**
** LSM_CONFIG_NMERGE:
**   A read/write integer parameter. The minimum number of segments to
**   merge together at a time. Default value 4.
**
** LSM_CONFIG_MAX_FREELIST:
**   A read/write integer parameter. The maximum number of free-list 
**   entries that are stored in a database checkpoint (the others are
**   stored elsewhere in the database).
**
**   There is no reason for an application to configure or query this
**   parameter. It is only present because configuring a small value
**   makes certain parts of the lsm code easier to test.
**
** LSM_CONFIG_MULTIPLE_PROCESSES:
**   A read/write boolean parameter. This parameter may only be set before
**   lsm_open() has been called. If true, the library uses shared-memory
**   and posix advisory locks to co-ordinate access by clients from within
**   multiple processes. Otherwise, if false, all database clients must be 
**   located in the same process. The default value is true.
**
** LSM_CONFIG_SET_COMPRESSION:
**   Set the compression methods used to compress and decompress database
**   content. The argument to this option should be a pointer to a structure
**   of type lsm_compress. The lsm_config() method takes a copy of the 
**   structures contents.
**
**   This option may only be used before lsm_open() is called. Invoking it
**   after lsm_open() has been called results in an LSM_MISUSE error.
**
** LSM_CONFIG_GET_COMPRESSION:
**   Query the compression methods used to compress and decompress database
**   content.
*/
#define LSM_CONFIG_WRITE_BUFFER        1
#define LSM_CONFIG_PAGE_SIZE           2
#define LSM_CONFIG_SAFETY              3
#define LSM_CONFIG_BLOCK_SIZE          4
#define LSM_CONFIG_AUTOWORK            5
#define LSM_CONFIG_LOG_SIZE            6
#define LSM_CONFIG_MMAP                7
#define LSM_CONFIG_USE_LOG             8
#define LSM_CONFIG_NMERGE              9
#define LSM_CONFIG_MAX_FREELIST       10
#define LSM_CONFIG_MULTIPLE_PROCESSES 11
#define LSM_CONFIG_AUTOCHECKPOINT     12

#define LSM_CONFIG_SET_COMPRESSION    13
#define LSM_CONFIG_GET_COMPRESSION    14

#define LSM_SAFETY_OFF    0
#define LSM_SAFETY_NORMAL 1
#define LSM_SAFETY_FULL   2

/*
** CAPI: Compression and/or Encryption Hooks
*/
struct lsm_compress {
  void *pCtx;
  unsigned int iId;
  int (*xBound)(void *, int nSrc);
  int (*xCompress)(void *, char *, int *, const char *, int);
  int (*xUncompress)(void *, char *, int *, const char *, int);
};


/*
** CAPI: Allocating and Freeing Memory
**
** Invoke the memory allocation functions that belong to environment
** pEnv. Or the system defaults if no memory allocation functions have 
** been registered.
*/
void *lsm_malloc(lsm_env*, size_t);
void *lsm_realloc(lsm_env*, void *, size_t);
void lsm_free(lsm_env*, void *);

/*
** CAPI: Querying a Connection For Operational Data

**









** Query a database connection for operational statistics or data.
*/
int lsm_info(lsm_db *, int, ...);

/*
** The following values may be passed as the second argument to lsm_info().
**
** LSM_INFO_NWRITE:
**   The third parameter should be of type (int *). The location pointed
**   to by the third parameter is set to the number of 4KB pages written to
**   the database file during the lifetime of this connection. 
**
** LSM_INFO_NREAD:
**   The third parameter should be of type (int *). The location pointed
**   to by the third parameter is set to the number of 4KB pages read from
**   the database file during the lifetime of this connection.
**
** LSM_INFO_DB_STRUCTURE:
**   The third argument should be of type (char **). The location pointed
**   to is populated with a pointer to a nul-terminated string containing
**   the string representation of a Tcl data-structure reflecting the 
**   current structure of the database file. Specifically, the current state
**   of the worker snapshot. The returned string should be eventually freed 
**   by the caller using lsm_free().
**
**   The returned list contains one element for each level in the database,
**   in order from most to least recent. Each element contains a 
**   single element for each segment comprising the corresponding level,
**   starting with the lhs segment, then each of the rhs segments (if any)
**   in order from most to least recent.
**
**   Each segment element is itself a list of 4 integer values, as follows:
**
**   <ol><li> First page of segment
**       <li> Last page of segment
**       <li> Root page of segment (if applicable)
**       <li> Total number of pages in segment
**   </ol>
**
** LSM_INFO_ARRAY_STRUCTURE:
**   There should be two arguments passed following this option (i.e. a 
**   total of four arguments passed to lsm_info()). The first argument 
**   should be the page number of the first page in a database array 
**   (perhaps obtained from an earlier INFO_DB_STRUCTURE call). The second 
**   trailing argument should be of type (char **). The location pointed 
**   to is populated with a pointer to a nul-terminated string that must 
**   be eventually freed using lsm_free() by the caller.
**
**   The output string contains the text representation of a Tcl list of
**   integers. Each pair of integers represent a range of pages used by
**   the identified array. For example, if the array occupies database
**   pages 993 to 1024, then pages 2048 to 2777, then the returned string
**   will be "993 1024 2048 2777".
**
**   If the specified integer argument does not correspond to the first
**   page of any database array, LSM_ERROR is returned and the output
**   pointer is set to a NULL value.
**
** LSM_INFO_LOG_STRUCTURE:
**   The third argument should be of type (char **). The location pointed
**   to is populated with a pointer to a nul-terminated string containing
**   the string representation of a Tcl data-structure. The returned 
**   string should be eventually freed by the caller using lsm_free().
**
**   The Tcl structure returned is a list of six integers that describe
**   the current structure of the log file.
**
** LSM_INFO_ARRAY_PAGES:
**


** LSM_INFO_PAGE_ASCII_DUMP:
**   As with LSM_INFO_ARRAY_STRUCTURE, there should be two arguments passed
**   with calls that specify this option - an integer page number and a
**   (char **) used to return a nul-terminated string that must be later
**   freed using lsm_free(). In this case the output string is populated
**   with a human-readable description of the page content.
**
**   If the page cannot be decoded, it is not an error. In this case the
**   human-readable output message will report the systems failure to 
**   interpret the page data.
**
** LSM_INFO_PAGE_HEX_DUMP:
**   This argument is similar to PAGE_ASCII_DUMP, except that keys and
**   values are represented using hexadecimal notation instead of ascii.
**
** LSM_INFO_FREELIST:
**   The third argument should be of type (char **). The location pointed
**   to is populated with a pointer to a nul-terminated string containing
**   the string representation of a Tcl data-structure. The returned 
**   string should be eventually freed by the caller using lsm_free().
**
**   The Tcl structure returned is a list containing one element for each
**   free block in the database. The element itself consists of two 
**   integers - the block number and the id of the snapshot that freed it.
*/
#define LSM_INFO_NWRITE           1
#define LSM_INFO_NREAD            2
#define LSM_INFO_DB_STRUCTURE     3
#define LSM_INFO_LOG_STRUCTURE    4
#define LSM_INFO_ARRAY_STRUCTURE  5
#define LSM_INFO_PAGE_ASCII_DUMP  6
#define LSM_INFO_PAGE_HEX_DUMP    7
#define LSM_INFO_FREELIST         8
#define LSM_INFO_ARRAY_PAGES      9


/* 
** CAPI: Opening and Closing Write Transactions
**
** These functions are used to open and close transactions and nested 
** sub-transactions.
**

** The lsm_begin() function is used to open transactions and sub-transactions. 
** A successful call to lsm_begin() ensures that there are at least iLevel 
** nested transactions open. To open a top-level transaction, pass iLevel=1. 
** To open a sub-transaction within the top-level transaction, iLevel=2. 
** Passing iLevel=0 is a no-op.
**

** lsm_commit() is used to commit transactions and sub-transactions. A
** successful call to lsm_commit() ensures that there are at most iLevel 
** nested transactions open. To commit a top-level transaction, pass iLevel=0. 
** To commit all sub-transactions inside the main transaction, pass iLevel=1.

**

** Function lsm_rollback() is used to roll back transactions and
** sub-transactions. A successful call to lsm_rollback() restores the database 
** to the state it was in when the iLevel'th nested sub-transaction (if any) 
** was first opened. And then closes transactions to ensure that there are 


** at most iLevel nested transactions open. Passing iLevel=0 rolls back and 
** closes the top-level transaction. iLevel=1 also rolls back the top-level 

** transaction, but leaves it open. iLevel=2 rolls back the sub-transaction 
** nested directly inside the top-level transaction (and leaves it open).
*/
int lsm_begin(lsm_db *pDb, int iLevel);
int lsm_commit(lsm_db *pDb, int iLevel);
int lsm_rollback(lsm_db *pDb, int iLevel);

/* 
** CAPI: Writing to a Database
**
** Write a new value into the database. If a value with a duplicate key 
** already exists it is replaced.
*/
int lsm_insert(lsm_db*, const void *pKey, int nKey, const void *pVal, int nVal);

/*
** Delete a value from the database. No error is returned if the specified
................................................................................
**
** Return LSM_OK if successful, or an LSM error code otherwise.
*/
int lsm_delete_range(lsm_db *, 
    const void *pKey1, int nKey1, const void *pKey2, int nKey2
);

/*
** CAPI: Explicit Database Work and Checkpointing
**
** This function is called by a thread to work on the database structure.
*/
int lsm_work(lsm_db *pDb, int nMerge, int nPage, int *pnWrite);

int lsm_flush(lsm_db *pDb);

/*
** Attempt to checkpoint the current database snapshot. Return an LSM
** error code if an error occurs or LSM_OK otherwise.
**
** If the current snapshot has already been checkpointed, calling this 
** function is a no-op. In this case if pnByte is not NULL, *pnByte is
** set to 0. Or, if the current snapshot is successfully checkpointed
** by this function and pbCkpt is not NULL, *pnByte is set to the number
** of bytes written to the database file since the previous checkpoint
** (the same measure as returned by lsm_ckpt_size()).
*/
int lsm_checkpoint(lsm_db *pDb, int *pnByte);

/*
** CAPI: Opening and Closing Database Cursors
**
** Open and close a database cursor.
*/
int lsm_csr_open(lsm_db *pDb, lsm_cursor **ppCsr);
int lsm_csr_close(lsm_cursor *pCsr);

/* 
** CAPI: Positioning Database Cursors
**
** If the fourth parameter is LSM_SEEK_EQ, LSM_SEEK_GE or LSM_SEEK_LE,
** this function searches the database for an entry with key (pKey/nKey). 
** If an error occurs, an LSM error code is returned. Otherwise, LSM_OK.
**
** If no error occurs and the requested key is present in the database, the
** cursor is left pointing to the entry with the specified key. Or, if the 
** specified key is not present in the database the state of the cursor 
** depends on the value passed as the final parameter, as follows:
**
** LSM_SEEK_EQ:
**   The cursor is left at EOF (invalidated). A call to lsm_csr_valid()
**   returns non-zero.
**
** LSM_SEEK_LE:
**   The cursor is left pointing to the largest key in the database that
**   is smaller than (pKey/nKey). If the database contains no keys smaller
**   than (pKey/nKey), the cursor is left at EOF.
**
** LSM_SEEK_GE:
**   The cursor is left pointing to the smallest key in the database that
**   is larger than (pKey/nKey). If the database contains no keys larger
**   than (pKey/nKey), the cursor is left at EOF.
**
** If the fourth parameter is LSM_SEEK_LEFAST, this function searches the
** database in a similar manner to LSM_SEEK_LE, with two differences:
**
** <ol><li>Even if a key can be found (the cursor is not left at EOF), the
** lsm_csr_value() function may not be used (attempts to do so return
** LSM_MISUSE).
**
** <li>The key that the cursor is left pointing to may be one that has 
** been recently deleted from the database. In this case it is
** guaranteed that the returned key is larger than any key currently 
** in the database that is less than or equal to (pKey/nKey).
** </ol>
**
** LSM_SEEK_LEFAST requests are intended to be used to allocate database
** keys.
*/
int lsm_csr_seek(lsm_cursor *pCsr, const void *pKey, int nKey, int eSeek);

int lsm_csr_first(lsm_cursor *pCsr);
int lsm_csr_last(lsm_cursor *pCsr);

/*
** Advance the specified cursor to the next or previous key in the database.
** Return LSM_OK if successful, or an LSM error code otherwise.
**
** Functions lsm_csr_seek(), lsm_csr_first() and lsm_csr_last() are "seek"
** functions. Whether or not lsm_csr_next and lsm_csr_prev may be called
** successfully also depends on the most recent seek function called on
** the cursor. Specifically:
**
** <ul>
** <li> At least one seek function must have been called on the cursor.
** <li> To call lsm_csr_next(), the most recent call to a seek function must
** have been either lsm_csr_first() or a call to lsm_csr_seek() specifying
** LSM_SEEK_GE. 
** <li> To call lsm_csr_prev(), the most recent call to a seek function must
** have been either lsm_csr_first() or a call to lsm_csr_seek() specifying
** LSM_SEEK_GE. 
** </ul>
**
** Otherwise, if the above conditions are not met when lsm_csr_next or 
** lsm_csr_prev is called, LSM_MISUSE is returned and the cursor position
** remains unchanged.
*/
int lsm_csr_next(lsm_cursor *pCsr);
int lsm_csr_prev(lsm_cursor *pCsr);

/*
** Values that may be passed as the fourth argument to lsm_csr_seek().
*/
#define LSM_SEEK_LEFAST   -2
#define LSM_SEEK_LE       -1
#define LSM_SEEK_EQ        0
#define LSM_SEEK_GE        1

/* 
** CAPI: Extracting Data From Database Cursors
**
** Retrieve data from a database cursor.
*/
int lsm_csr_valid(lsm_cursor *pCsr);
int lsm_csr_key(lsm_cursor *pCsr, const void **ppKey, int *pnKey);
int lsm_csr_value(lsm_cursor *pCsr, const void **ppVal, int *pnVal);

/*
** If no error occurs, this function compares the database key passed via
** the pKey/nKey arguments with the key that the cursor passed as the first
** argument currently points to. If the cursors key is less than, equal to
** or greater than pKey/nKey, *piRes is set to less than, equal to or greater
** than zero before returning. LSM_OK is returned in this case.
**
** Or, if an error occurs, an LSM error code is returned and the final 
** value of *piRes is undefined. If the cursor does not point to a valid
** key when this function is called, LSM_MISUSE is returned.
*/
int lsm_csr_cmp(lsm_cursor *pCsr, const void *pKey, int nKey, int *piRes);

/*
** CAPI: Change these!!
**
** Configure a callback to which debugging and other messages should 
** be directed. Only useful for debugging lsm.
*/
void lsm_config_log(lsm_db *, void (*)(void *, int, const char *), void *);

/*
** Configure a callback that is invoked if the database connection ever
** writes to the database file.
*/
void lsm_config_work_hook(lsm_db *, void (*)(lsm_db *, void *), void *);

/*
** The lsm_tree_size() function reports on the current state of the 
** in-memory tree data structure. 
**
** At any time, there are either one or two tree structures held in shared
** memory that new database clients will access (there may also be additional 
** tree structures being used by older clients - this API does not provide
................................................................................
**
** RACE CONDITION:
**   Describe the race condition this function is subject to. Or remove
**   it somehow.
*/
int lsm_ckpt_size(lsm_db *, int *pnByte);





























































































































/* ENDOFAPI */
#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif /* ifndef _LSM_H */

Added tool/mklsmapi.tcl.























































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203

#
# This script is used to generate the www/lsmapi.wiki page from comments in
# the source file lsm.h. It should be run as follows:
#
#    tclsh ./src/lsm.h > www/lsmapi.wiki
#
# before committing changes to API comments in file lsm.h.
#

set document_preamble {
<title>LSM API Reference</title>
<nowiki>
<br note="
  DO NOT EDIT!!! 
  DO NOT EDIT!!! 
  DO NOT EDIT!!! 
  This document is generated by script tools/updateapi.tcl.
  DO NOT EDIT!!! 
  DO NOT EDIT!!! 
  DO NOT EDIT!!! 
">

<p>
This page contains the LSM API Reference Manual. It is intended to complement
the <a href=lsmusr.wiki>LSM User Manual</a>.
}

set document_text ""
set document_toc  ""

set document_defines   [list]
set document_functions [list]
set document_types     [list]

proc put_section {} {
  global S

  if {$::state != "off"} {

    set style {style=text-decoration:none}

    regexp {^([^( ]*)} $S(heading) -> id
    set id [string tolower [string map {- _} $id]]
    if {$id == "file"} {set id filespace}

    set defs [list]
    foreach line [split $S(code) "\n"] {
      if {[regexp {^#define (LSM_[^ ]*)} $line -> sym]} {
        lappend defs $sym
        lappend ::document_defines $sym
      } 

      if {[regexp {struct (lsm_[a-z]*)} $line -> sym]} {
        lappend defs $sym
        lappend ::document_types $sym
      } 

      if {[regexp { (lsm_[a-z_]*)\(} $line -> sym]} {
        lappend defs $sym
        lappend ::document_functions $sym
      }

    }

    append ::document_text "<h2 id=$id>$S(heading)"
    foreach sym $defs { append ::document_text "<a id=$sym></a>" }
    append ::document_text "</h2>\n"

    append ::document_text "<verbatim>$S(code)</verbatim>\n"
    append ::document_text "$S(text)"

    append ::document_toc "<li><a href=\"#$id\" $style>$S(heading)</a>\n"
  }

  set S(heading) ""
  set S(code) ""
  set S(text) ""
}

# Process the command line arguments.
#
if {[llength $argv]!=1} {
  puts stderr "Usage: $argv0 <path to lsm.h>"
  exit -1
}
set zipvfsh [lindex $argv 0]
set fd [open $zipvfsh]

# The $state variable may be set to one of:
#
#   off
#   on
#   table
#   deflist
#
set state off

while {![eof $fd]} {
  set line [gets $fd]

  switch -regexp -- $line {
    {^/\* *$} { # no-op }
    {^\*/ *$} { # no-op }
    {^ *$} { # no-op }

    {^\*\* CAPI: .*$} {
      put_section
      regexp {.*CAPI: (.*)} $line -> S(heading)
      set state on
    }
    {.*ENDOFAPI.*} {
      put_section
      set state off
    }

    {^\*\* *[^ ]*: *$} {
      regexp {( *)([^ ]*):} $line -> ws title
      if {$state == "on"} {
        if {[string length $ws] > 1} {
          append S(text) <table>
          set state table
        } else {
          append S(text) <dl>
          set state deflist
        }
      }
      if {$state == "table"} {
        append S(text) "<tr><td valign=top>$title<td>"
      }
      if {$state == "deflist"} {
        append S(text) <dt>$title<dd>
      }
    }

    {^\*\* *$} {
      if {$state == "on" || $state=="deflist"} {
        append S(text) <p>
      }
    }

    {^\*\*.*$} {
      if {$state != "off"} {
        regexp {^\*\*( *)(.*)} $line -> ws text

        if {$state == "table" && [string length $ws]<=1} {
          append S(text) </table><p>
          set state on
        }
        if {$state == "deflist" && [string length $ws]<=1} {
          append S(text) </dl><p>
          set state on
        }

        if {$state == "on" && [string length $ws]>=3} {
          append S(text) <blockquote><pre>$text</blockquote></pre>
        } else {
          append S(text) $text
        }

        append S(text) "\n"
      }
    }

    default {
      if {$state != "off"} {
        if {$state == "table"} { append S(text) </table> }
        if {$state == "deflist"} { append S(text) </dl> }
        set state on
      }
      if {$state == "on"} {
        append S(code) $line
        append S(code) "\n"
      }
    }
  }
}
put_section

close $fd

puts $document_preamble
puts "<h1>LSM API Topics</h1>"
puts <ol>
puts $document_toc
puts </ol>
set s "display:block;float:left;width:40ex"
puts "<h1 style=clear:both>All LSM API Functions</h1>"
foreach sym [lsort $document_functions] {
  puts "<span style=$s><a href=#$sym>$sym</a></span>"
}
puts "<br style=clear:both>"
puts "<h1 style=clear:both>All LSM API Types</h1>"
foreach sym [lsort $document_types] {
  puts "<span style=$s><a href=#$sym>$sym</a></span>"
}
puts "<br style=clear:both>"
puts "<h1>All LSM API Constants</h1>"
foreach sym [lsort $document_defines] {
  puts "<span style=$s><a href=#$sym>$sym</a></span>"
}
puts "<br style=clear:both>"
puts $document_text

Added www/lsmapi.wiki.





































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466

<title>LSM API Reference</title>
<nowiki>
<br note="
  DO NOT EDIT!!! 
  DO NOT EDIT!!! 
  DO NOT EDIT!!! 
  This document is generated by script tools/updateapi.tcl.
  DO NOT EDIT!!! 
  DO NOT EDIT!!! 
  DO NOT EDIT!!! 
">

<p>
This page contains the LSM API Reference Manual. It is intended to complement
the <a href=lsmusr.wiki>LSM User Manual</a>.

<h1>LSM API Topics</h1>
<ol>
<li><a href="#lsm" style=text-decoration:none>LSM Error Codes</a>
<li><a href="#creating" style=text-decoration:none>Creating and Destroying Database Connection Handles</a>
<li><a href="#connecting" style=text-decoration:none>Connecting to a Database</a>
<li><a href="#obtaining" style=text-decoration:none>Obtaining pointers to databases environments</a>
<li><a href="#configuring" style=text-decoration:none>Configuring a database connection.</a>
<li><a href="#compression" style=text-decoration:none>Compression and/or Encryption Hooks</a>
<li><a href="#allocating" style=text-decoration:none>Allocating and Freeing Memory</a>
<li><a href="#querying" style=text-decoration:none>Querying a Connection For Operational Data</a>
<li><a href="#opening" style=text-decoration:none>Opening and Closing Write Transactions</a>
<li><a href="#writing" style=text-decoration:none>Writing to a Database</a>
<li><a href="#explicit" style=text-decoration:none>Explicit Database Work and Checkpointing</a>
<li><a href="#opening" style=text-decoration:none>Opening and Closing Database Cursors</a>
<li><a href="#positioning" style=text-decoration:none>Positioning Database Cursors</a>
<li><a href="#extracting" style=text-decoration:none>Extracting Data From Database Cursors</a>
<li><a href="#change" style=text-decoration:none>Change these!!</a>

</ol>
<h1 style=clear:both>All LSM API Functions</h1>
<span style=display:block;float:left;width:40ex><a href=#lsm_begin>lsm_begin</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_checkpoint>lsm_checkpoint</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_ckpt_size>lsm_ckpt_size</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_close>lsm_close</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_commit>lsm_commit</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_config>lsm_config</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_config_log>lsm_config_log</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_config_work_hook>lsm_config_work_hook</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_csr_close>lsm_csr_close</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_csr_cmp>lsm_csr_cmp</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_csr_first>lsm_csr_first</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_csr_key>lsm_csr_key</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_csr_last>lsm_csr_last</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_csr_next>lsm_csr_next</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_csr_open>lsm_csr_open</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_csr_prev>lsm_csr_prev</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_csr_seek>lsm_csr_seek</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_csr_valid>lsm_csr_valid</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_csr_value>lsm_csr_value</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_delete>lsm_delete</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_delete_range>lsm_delete_range</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_flush>lsm_flush</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_free>lsm_free</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_info>lsm_info</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_insert>lsm_insert</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_new>lsm_new</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_open>lsm_open</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_rollback>lsm_rollback</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_tree_size>lsm_tree_size</a></span>
<span style=display:block;float:left;width:40ex><a href=#lsm_work>lsm_work</a></span>
<br style=clear:both>
<h1 style=clear:both>All LSM API Types</h1>
<span style=display:block;float:left;width:40ex><a href=#lsm_compress>lsm_compress</a></span>
<br style=clear:both>
<h1>All LSM API Constants</h1>
<span style=display:block;float:left;width:40ex><a href=#LSM_BUSY>LSM_BUSY</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CANTOPEN>LSM_CANTOPEN</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_AUTOCHECKPOINT>LSM_CONFIG_AUTOCHECKPOINT</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_AUTOWORK>LSM_CONFIG_AUTOWORK</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_BLOCK_SIZE>LSM_CONFIG_BLOCK_SIZE</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_GET_COMPRESSION>LSM_CONFIG_GET_COMPRESSION</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_LOG_SIZE>LSM_CONFIG_LOG_SIZE</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_MAX_FREELIST>LSM_CONFIG_MAX_FREELIST</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_MMAP>LSM_CONFIG_MMAP</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_MULTIPLE_PROCESSES>LSM_CONFIG_MULTIPLE_PROCESSES</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_NMERGE>LSM_CONFIG_NMERGE</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_PAGE_SIZE>LSM_CONFIG_PAGE_SIZE</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_SAFETY>LSM_CONFIG_SAFETY</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_SET_COMPRESSION>LSM_CONFIG_SET_COMPRESSION</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_USE_LOG>LSM_CONFIG_USE_LOG</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CONFIG_WRITE_BUFFER>LSM_CONFIG_WRITE_BUFFER</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_CORRUPT>LSM_CORRUPT</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_ERROR>LSM_ERROR</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_FULL>LSM_FULL</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_INFO_ARRAY_PAGES>LSM_INFO_ARRAY_PAGES</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_INFO_ARRAY_STRUCTURE>LSM_INFO_ARRAY_STRUCTURE</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_INFO_DB_STRUCTURE>LSM_INFO_DB_STRUCTURE</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_INFO_FREELIST>LSM_INFO_FREELIST</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_INFO_LOG_STRUCTURE>LSM_INFO_LOG_STRUCTURE</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_INFO_NREAD>LSM_INFO_NREAD</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_INFO_NWRITE>LSM_INFO_NWRITE</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_INFO_PAGE_ASCII_DUMP>LSM_INFO_PAGE_ASCII_DUMP</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_INFO_PAGE_HEX_DUMP>LSM_INFO_PAGE_HEX_DUMP</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_IOERR>LSM_IOERR</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_MISUSE>LSM_MISUSE</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_NOMEM>LSM_NOMEM</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_OK>LSM_OK</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_PROTOCOL>LSM_PROTOCOL</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_SAFETY_FULL>LSM_SAFETY_FULL</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_SAFETY_NORMAL>LSM_SAFETY_NORMAL</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_SAFETY_OFF>LSM_SAFETY_OFF</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_SEEK_EQ>LSM_SEEK_EQ</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_SEEK_GE>LSM_SEEK_GE</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_SEEK_LE>LSM_SEEK_LE</a></span>
<span style=display:block;float:left;width:40ex><a href=#LSM_SEEK_LEFAST>LSM_SEEK_LEFAST</a></span>
<br style=clear:both>
<h2 id=lsm>LSM Error Codes<a id=LSM_OK></a><a id=LSM_ERROR></a><a id=LSM_BUSY></a><a id=LSM_NOMEM></a><a id=LSM_IOERR></a><a id=LSM_CORRUPT></a><a id=LSM_FULL></a><a id=LSM_CANTOPEN></a><a id=LSM_PROTOCOL></a><a id=LSM_MISUSE></a></h2>
<verbatim>#define LSM_OK         0
#define LSM_ERROR      1
#define LSM_BUSY       5
#define LSM_NOMEM      7
#define LSM_IOERR     10
#define LSM_CORRUPT   11
#define LSM_FULL      13
#define LSM_CANTOPEN  14
#define LSM_PROTOCOL  15
#define LSM_MISUSE    21
</verbatim>
<h2 id=creating>Creating and Destroying Database Connection Handles<a id=lsm_new></a><a id=lsm_close></a></h2>
<verbatim>int lsm_new(lsm_env*, lsm_db **ppDb);
int lsm_close(lsm_db *pDb);
</verbatim>
<p>Open and close a database connection handle.
<h2 id=connecting>Connecting to a Database<a id=lsm_open></a></h2>
<verbatim>int lsm_open(lsm_db *pDb, const char *zFilename);
</verbatim>
<h2 id=obtaining>Obtaining pointers to databases environments</h2>
<verbatim>lsm_env *lsm_get_env(lsm_db *pDb);
lsm_env *lsm_default_env(void);
</verbatim>
<p>Return a pointer to the environment used by the database connection 
passed as the first argument. Assuming the argument is valid, this 
function always returns a valid environment pointer - it cannot fail.
The lsm_default_env() function returns a pointer to the default LSM
environment for the current platform.
<h2 id=configuring>Configuring a database connection.<a id=lsm_config></a><a id=LSM_CONFIG_WRITE_BUFFER></a><a id=LSM_CONFIG_PAGE_SIZE></a><a id=LSM_CONFIG_SAFETY></a><a id=LSM_CONFIG_BLOCK_SIZE></a><a id=LSM_CONFIG_AUTOWORK></a><a id=LSM_CONFIG_LOG_SIZE></a><a id=LSM_CONFIG_MMAP></a><a id=LSM_CONFIG_USE_LOG></a><a id=LSM_CONFIG_NMERGE></a><a id=LSM_CONFIG_MAX_FREELIST></a><a id=LSM_CONFIG_MULTIPLE_PROCESSES></a><a id=LSM_CONFIG_AUTOCHECKPOINT></a><a id=LSM_CONFIG_SET_COMPRESSION></a><a id=LSM_CONFIG_GET_COMPRESSION></a><a id=LSM_SAFETY_OFF></a><a id=LSM_SAFETY_NORMAL></a><a id=LSM_SAFETY_FULL></a></h2>
<verbatim>int lsm_config(lsm_db *, int, ...);
#define LSM_CONFIG_WRITE_BUFFER        1
#define LSM_CONFIG_PAGE_SIZE           2
#define LSM_CONFIG_SAFETY              3
#define LSM_CONFIG_BLOCK_SIZE          4
#define LSM_CONFIG_AUTOWORK            5
#define LSM_CONFIG_LOG_SIZE            6
#define LSM_CONFIG_MMAP                7
#define LSM_CONFIG_USE_LOG             8
#define LSM_CONFIG_NMERGE              9
#define LSM_CONFIG_MAX_FREELIST       10
#define LSM_CONFIG_MULTIPLE_PROCESSES 11
#define LSM_CONFIG_AUTOCHECKPOINT     12
#define LSM_CONFIG_SET_COMPRESSION    13
#define LSM_CONFIG_GET_COMPRESSION    14
#define LSM_SAFETY_OFF    0
#define LSM_SAFETY_NORMAL 1
#define LSM_SAFETY_FULL   2
</verbatim>
<p>The lsm_config() function is used to configure a database connection.
The following values may be passed as the second argument to lsm_config().
<p><dl><dt>LSM_CONFIG_WRITE_BUFFER<dd>A read/write integer parameter. This value determines the maximum amount
of space (in bytes) used to accumulate writes in main-memory before 
they are flushed to a level 0 segment.
<p><dt>LSM_CONFIG_PAGE_SIZE<dd>A read/write integer parameter. This parameter may only be set before
lsm_open() has been called.
<p><dt>LSM_CONFIG_BLOCK_SIZE<dd>A read/write integer parameter. This parameter may only be set before
lsm_open() has been called.
<p><dt>LSM_CONFIG_LOG_SIZE<dd>A read/write integer parameter.
<p><dt>LSM_CONFIG_SAFETY<dd>A read/write integer parameter. Valid values are 0, 1 (the default) 
and 2. This parameter determines how robust the database is in the
face of a system crash (e.g. a power failure or operating system 
crash). As follows:
<p>0 (off):    No robustness. A system crash may corrupt the database.
<p>1 (normal): Some robustness. A system crash may not corrupt the
database file, but recently committed transactions may
be lost following recovery.
<p>2 (full):   Full robustness. A system crash may not corrupt the
database file. Following recovery the database file
contains all successfully committed transactions.
<p><dt>LSM_CONFIG_AUTOWORK<dd>A read/write integer parameter.
<p><dt>LSM_CONFIG_AUTOCHECKPOINT<dd>A read/write integer parameter.
<p><dt>LSM_CONFIG_MMAP<dd>A read/write integer parameter. True to use mmap() to access the 
database file. False otherwise.
<p><dt>LSM_CONFIG_USE_LOG<dd>A read/write boolean parameter. True (the default) to use the log
file normally. False otherwise.
<p><dt>LSM_CONFIG_NMERGE<dd>A read/write integer parameter. The minimum number of segments to
merge together at a time. Default value 4.
<p><dt>LSM_CONFIG_MAX_FREELIST<dd>A read/write integer parameter. The maximum number of free-list 
entries that are stored in a database checkpoint (the others are
stored elsewhere in the database).
<p>There is no reason for an application to configure or query this
parameter. It is only present because configuring a small value
makes certain parts of the lsm code easier to test.
<p><dt>LSM_CONFIG_MULTIPLE_PROCESSES<dd>A read/write boolean parameter. This parameter may only be set before
lsm_open() has been called. If true, the library uses shared-memory
and posix advisory locks to co-ordinate access by clients from within
multiple processes. Otherwise, if false, all database clients must be 
located in the same process. The default value is true.
<p><dt>LSM_CONFIG_SET_COMPRESSION<dd>Set the compression methods used to compress and decompress database
content. The argument to this option should be a pointer to a structure
of type lsm_compress. The lsm_config() method takes a copy of the 
structures contents.
<p>This option may only be used before lsm_open() is called. Invoking it
after lsm_open() has been called results in an LSM_MISUSE error.
<p><dt>LSM_CONFIG_GET_COMPRESSION<dd>Query the compression methods used to compress and decompress database
content.
</dl><h2 id=compression>Compression and/or Encryption Hooks<a id=lsm_compress></a></h2>
<verbatim>struct lsm_compress {
  void *pCtx;
  unsigned int iId;
  int (*xBound)(void *, int nSrc);
  int (*xCompress)(void *, char *, int *, const char *, int);
  int (*xUncompress)(void *, char *, int *, const char *, int);
};
</verbatim>
<h2 id=allocating>Allocating and Freeing Memory<a id=lsm_free></a></h2>
<verbatim>void *lsm_malloc(lsm_env*, size_t);
void *lsm_realloc(lsm_env*, void *, size_t);
void lsm_free(lsm_env*, void *);
</verbatim>
<p>Invoke the memory allocation functions that belong to environment
pEnv. Or the system defaults if no memory allocation functions have 
been registered.
<h2 id=querying>Querying a Connection For Operational Data<a id=lsm_info></a><a id=LSM_INFO_NWRITE></a><a id=LSM_INFO_NREAD></a><a id=LSM_INFO_DB_STRUCTURE></a><a id=LSM_INFO_LOG_STRUCTURE></a><a id=LSM_INFO_ARRAY_STRUCTURE></a><a id=LSM_INFO_PAGE_ASCII_DUMP></a><a id=LSM_INFO_PAGE_HEX_DUMP></a><a id=LSM_INFO_FREELIST></a><a id=LSM_INFO_ARRAY_PAGES></a></h2>
<verbatim>int lsm_info(lsm_db *, int, ...);
#define LSM_INFO_NWRITE           1
#define LSM_INFO_NREAD            2
#define LSM_INFO_DB_STRUCTURE     3
#define LSM_INFO_LOG_STRUCTURE    4
#define LSM_INFO_ARRAY_STRUCTURE  5
#define LSM_INFO_PAGE_ASCII_DUMP  6
#define LSM_INFO_PAGE_HEX_DUMP    7
#define LSM_INFO_FREELIST         8
#define LSM_INFO_ARRAY_PAGES      9
</verbatim>
<p>Query a database connection for operational statistics or data.
The following values may be passed as the second argument to lsm_info().
<p><dl><dt>LSM_INFO_NWRITE<dd>The third parameter should be of type (int *). The location pointed
to by the third parameter is set to the number of 4KB pages written to
the database file during the lifetime of this connection. 
<p><dt>LSM_INFO_NREAD<dd>The third parameter should be of type (int *). The location pointed
to by the third parameter is set to the number of 4KB pages read from
the database file during the lifetime of this connection.
<p><dt>LSM_INFO_DB_STRUCTURE<dd>The third argument should be of type (char **). The location pointed
to is populated with a pointer to a nul-terminated string containing
the string representation of a Tcl data-structure reflecting the 
current structure of the database file. Specifically, the current state
of the worker snapshot. The returned string should be eventually freed 
by the caller using lsm_free().
<p>The returned list contains one element for each level in the database,
in order from most to least recent. Each element contains a 
single element for each segment comprising the corresponding level,
starting with the lhs segment, then each of the rhs segments (if any)
in order from most to least recent.
<p>Each segment element is itself a list of 4 integer values, as follows:
<p><ol><li> First page of segment
<li> Last page of segment
<li> Root page of segment (if applicable)
<li> Total number of pages in segment
</ol>
<p><dt>LSM_INFO_ARRAY_STRUCTURE<dd>There should be two arguments passed following this option (i.e. a 
total of four arguments passed to lsm_info()). The first argument 
should be the page number of the first page in a database array 
(perhaps obtained from an earlier INFO_DB_STRUCTURE call). The second 
trailing argument should be of type (char **). The location pointed 
to is populated with a pointer to a nul-terminated string that must 
be eventually freed using lsm_free() by the caller.
<p>The output string contains the text representation of a Tcl list of
integers. Each pair of integers represent a range of pages used by
the identified array. For example, if the array occupies database
pages 993 to 1024, then pages 2048 to 2777, then the returned string
will be "993 1024 2048 2777".
<p>If the specified integer argument does not correspond to the first
page of any database array, LSM_ERROR is returned and the output
pointer is set to a NULL value.
<p><dt>LSM_INFO_LOG_STRUCTURE<dd>The third argument should be of type (char **). The location pointed
to is populated with a pointer to a nul-terminated string containing
the string representation of a Tcl data-structure. The returned 
string should be eventually freed by the caller using lsm_free().
<p>The Tcl structure returned is a list of six integers that describe
the current structure of the log file.
<p><dt>LSM_INFO_ARRAY_PAGES<dd><p><dt>LSM_INFO_PAGE_ASCII_DUMP<dd>As with LSM_INFO_ARRAY_STRUCTURE, there should be two arguments passed
with calls that specify this option - an integer page number and a
(char **) used to return a nul-terminated string that must be later
freed using lsm_free(). In this case the output string is populated
with a human-readable description of the page content.
<p>If the page cannot be decoded, it is not an error. In this case the
human-readable output message will report the systems failure to 
interpret the page data.
<p><dt>LSM_INFO_PAGE_HEX_DUMP<dd>This argument is similar to PAGE_ASCII_DUMP, except that keys and
values are represented using hexadecimal notation instead of ascii.
<p><dt>LSM_INFO_FREELIST<dd>The third argument should be of type (char **). The location pointed
to is populated with a pointer to a nul-terminated string containing
the string representation of a Tcl data-structure. The returned 
string should be eventually freed by the caller using lsm_free().
<p>The Tcl structure returned is a list containing one element for each
free block in the database. The element itself consists of two 
integers - the block number and the id of the snapshot that freed it.
</dl><h2 id=opening>Opening and Closing Write Transactions<a id=lsm_begin></a><a id=lsm_commit></a><a id=lsm_rollback></a></h2>
<verbatim>int lsm_begin(lsm_db *pDb, int iLevel);
int lsm_commit(lsm_db *pDb, int iLevel);
int lsm_rollback(lsm_db *pDb, int iLevel);
</verbatim>
<p>These functions are used to open and close transactions and nested 
sub-transactions.
<p>The lsm_begin() function is used to open transactions and sub-transactions. 
A successful call to lsm_begin() ensures that there are at least iLevel 
nested transactions open. To open a top-level transaction, pass iLevel=1. 
To open a sub-transaction within the top-level transaction, iLevel=2. 
Passing iLevel=0 is a no-op.
<p>lsm_commit() is used to commit transactions and sub-transactions. A
successful call to lsm_commit() ensures that there are at most iLevel 
nested transactions open. To commit a top-level transaction, pass iLevel=0. 
To commit all sub-transactions inside the main transaction, pass iLevel=1.
<p>Function lsm_rollback() is used to roll back transactions and
sub-transactions. A successful call to lsm_rollback() restores the database 
to the state it was in when the iLevel'th nested sub-transaction (if any) 
was first opened. And then closes transactions to ensure that there are 
at most iLevel nested transactions open. Passing iLevel=0 rolls back and 
closes the top-level transaction. iLevel=1 also rolls back the top-level 
transaction, but leaves it open. iLevel=2 rolls back the sub-transaction 
nested directly inside the top-level transaction (and leaves it open).
<h2 id=writing>Writing to a Database<a id=lsm_insert></a><a id=lsm_delete></a><a id=lsm_delete_range></a></h2>
<verbatim>int lsm_insert(lsm_db*, const void *pKey, int nKey, const void *pVal, int nVal);
int lsm_delete(lsm_db *, const void *pKey, int nKey);
int lsm_delete_range(lsm_db *, 
    const void *pKey1, int nKey1, const void *pKey2, int nKey2
);
</verbatim>
<p>Write a new value into the database. If a value with a duplicate key 
already exists it is replaced.
Delete a value from the database. No error is returned if the specified
key value does not exist in the database.
Delete all database entries with keys that are greater than (pKey1/nKey1) 
and smaller than (pKey2/nKey2). Note that keys (pKey1/nKey1) and
(pKey2/nKey2) themselves, if they exist in the database, are not deleted.
<p>Return LSM_OK if successful, or an LSM error code otherwise.
<h2 id=explicit>Explicit Database Work and Checkpointing<a id=lsm_work></a><a id=lsm_flush></a><a id=lsm_checkpoint></a></h2>
<verbatim>int lsm_work(lsm_db *pDb, int nMerge, int nPage, int *pnWrite);
int lsm_flush(lsm_db *pDb);
int lsm_checkpoint(lsm_db *pDb, int *pnByte);
</verbatim>
<p>This function is called by a thread to work on the database structure.
Attempt to checkpoint the current database snapshot. Return an LSM
error code if an error occurs or LSM_OK otherwise.
<p>If the current snapshot has already been checkpointed, calling this 
function is a no-op. In this case if pnByte is not NULL, *pnByte is
set to 0. Or, if the current snapshot is successfully checkpointed
by this function and pbCkpt is not NULL, *pnByte is set to the number
of bytes written to the database file since the previous checkpoint
(the same measure as returned by lsm_ckpt_size()).
<h2 id=opening>Opening and Closing Database Cursors<a id=lsm_csr_open></a><a id=lsm_csr_close></a></h2>
<verbatim>int lsm_csr_open(lsm_db *pDb, lsm_cursor **ppCsr);
int lsm_csr_close(lsm_cursor *pCsr);
</verbatim>
<p>Open and close a database cursor.
<h2 id=positioning>Positioning Database Cursors<a id=lsm_csr_seek></a><a id=lsm_csr_first></a><a id=lsm_csr_last></a><a id=lsm_csr_next></a><a id=lsm_csr_prev></a><a id=LSM_SEEK_LEFAST></a><a id=LSM_SEEK_LE></a><a id=LSM_SEEK_EQ></a><a id=LSM_SEEK_GE></a></h2>
<verbatim>int lsm_csr_seek(lsm_cursor *pCsr, const void *pKey, int nKey, int eSeek);
int lsm_csr_first(lsm_cursor *pCsr);
int lsm_csr_last(lsm_cursor *pCsr);
int lsm_csr_next(lsm_cursor *pCsr);
int lsm_csr_prev(lsm_cursor *pCsr);
#define LSM_SEEK_LEFAST   -2
#define LSM_SEEK_LE       -1
#define LSM_SEEK_EQ        0
#define LSM_SEEK_GE        1
</verbatim>
<p>If the fourth parameter is LSM_SEEK_EQ, LSM_SEEK_GE or LSM_SEEK_LE,
this function searches the database for an entry with key (pKey/nKey). 
If an error occurs, an LSM error code is returned. Otherwise, LSM_OK.
<p>If no error occurs and the requested key is present in the database, the
cursor is left pointing to the entry with the specified key. Or, if the 
specified key is not present in the database the state of the cursor 
depends on the value passed as the final parameter, as follows:
<p><dl><dt>LSM_SEEK_EQ<dd>The cursor is left at EOF (invalidated). A call to lsm_csr_valid()
returns non-zero.
<p><dt>LSM_SEEK_LE<dd>The cursor is left pointing to the largest key in the database that
is smaller than (pKey/nKey). If the database contains no keys smaller
than (pKey/nKey), the cursor is left at EOF.
<p><dt>LSM_SEEK_GE<dd>The cursor is left pointing to the smallest key in the database that
is larger than (pKey/nKey). If the database contains no keys larger
than (pKey/nKey), the cursor is left at EOF.
<p></dl><p>If the fourth parameter is LSM_SEEK_LEFAST, this function searches the
database in a similar manner to LSM_SEEK_LE, with two differences:
<p><ol><li>Even if a key can be found (the cursor is not left at EOF), the
lsm_csr_value() function may not be used (attempts to do so return
LSM_MISUSE).
<p><li>The key that the cursor is left pointing to may be one that has 
been recently deleted from the database. In this case it is
guaranteed that the returned key is larger than any key currently 
in the database that is less than or equal to (pKey/nKey).
</ol>
<p>LSM_SEEK_LEFAST requests are intended to be used to allocate database
keys.
Advance the specified cursor to the next or previous key in the database.
Return LSM_OK if successful, or an LSM error code otherwise.
<p>Functions lsm_csr_seek(), lsm_csr_first() and lsm_csr_last() are "seek"
functions. Whether or not lsm_csr_next and lsm_csr_prev may be called
successfully also depends on the most recent seek function called on
the cursor. Specifically:
<p><ul>
<li> At least one seek function must have been called on the cursor.
<li> To call lsm_csr_next(), the most recent call to a seek function must
have been either lsm_csr_first() or a call to lsm_csr_seek() specifying
LSM_SEEK_GE. 
<li> To call lsm_csr_prev(), the most recent call to a seek function must
have been either lsm_csr_first() or a call to lsm_csr_seek() specifying
LSM_SEEK_GE. 
</ul>
<p>Otherwise, if the above conditions are not met when lsm_csr_next or 
lsm_csr_prev is called, LSM_MISUSE is returned and the cursor position
remains unchanged.
Values that may be passed as the fourth argument to lsm_csr_seek().
<h2 id=extracting>Extracting Data From Database Cursors<a id=lsm_csr_valid></a><a id=lsm_csr_key></a><a id=lsm_csr_value></a><a id=lsm_csr_cmp></a></h2>
<verbatim>int lsm_csr_valid(lsm_cursor *pCsr);
int lsm_csr_key(lsm_cursor *pCsr, const void **ppKey, int *pnKey);
int lsm_csr_value(lsm_cursor *pCsr, const void **ppVal, int *pnVal);
int lsm_csr_cmp(lsm_cursor *pCsr, const void *pKey, int nKey, int *piRes);
</verbatim>
<p>Retrieve data from a database cursor.
If no error occurs, this function compares the database key passed via
the pKey/nKey arguments with the key that the cursor passed as the first
argument currently points to. If the cursors key is less than, equal to
or greater than pKey/nKey, *piRes is set to less than, equal to or greater
than zero before returning. LSM_OK is returned in this case.
<p>Or, if an error occurs, an LSM error code is returned and the final 
value of *piRes is undefined. If the cursor does not point to a valid
key when this function is called, LSM_MISUSE is returned.
<h2 id=change>Change these!!<a id=lsm_config_log></a><a id=lsm_config_work_hook></a><a id=lsm_tree_size></a><a id=lsm_ckpt_size></a></h2>
<verbatim>void lsm_config_log(lsm_db *, void (*)(void *, int, const char *), void *);
void lsm_config_work_hook(lsm_db *, void (*)(lsm_db *, void *), void *);
int lsm_tree_size(lsm_db *, int *pbOld, int *pnNew);
int lsm_ckpt_size(lsm_db *, int *pnByte);
</verbatim>
<p>Configure a callback to which debugging and other messages should 
be directed. Only useful for debugging lsm.
Configure a callback that is invoked if the database connection ever
writes to the database file.
The lsm_tree_size() function reports on the current state of the 
in-memory tree data structure. 
<p>At any time, there are either one or two tree structures held in shared
memory that new database clients will access (there may also be additional 
tree structures being used by older clients - this API does not provide
information on them). One tree structure - the current tree - is used to
accumulate new data written to the database. The other tree structure - the 
old tree - is a read-only tree holding older data and may be flushed to disk
at any time.
<p>If successful, this function sets *pnNew to the number of bytes of shared
memory space used by the current tree. *pbOld is set to true if the old 
tree exists, or false if it does not. 
<p>If no error occurs, LSM_OK is returned. Otherwise an LSM error code.
<p>RACE CONDITION:
<blockquote><pre>Describe the race condition this function is subject to. </blockquote></pre>
This function is used to query the amount of data that has been written
to the database file but not checkpointed (synced). If successful, *pnByte
is set to the number of bytes before returning.
<p>LSM_OK is returned if successful. Or if an error occurs, an LSM error
code is returned.
<p>RACE CONDITION:
<blockquote><pre>Describe the race condition this function is subject to. Or remove</blockquote></pre>
<blockquote><pre>it somehow.</blockquote></pre>

Changes to www/lsmusr.wiki.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
...
425
426
427
428
429
430
431

























































432
433
434
435
436
437
438
439
...
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
...
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
...
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
...
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
...
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
...
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965

<title>LSM Users Guide</title>
<nowiki>

<h2>Table of Contents</h2>



<div id=start_of_toc></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#overview_of_lsm style=text-decoration:none>1. Overview of LSM</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#using_lsm_in_applications style=text-decoration:none>2. Using LSM in Applications </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#basic_usage style=text-decoration:none>3. Basic Usage</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#opening_and_closing_database_connections style=text-decoration:none>3.1. Opening and Closing Database Connections </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#writing_to_a_database style=text-decoration:none>3.2. Writing to a Database </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#reading_from_a_database style=text-decoration:none>3.3. Reading from a Database </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#database_robustness style=text-decoration:none>3.4. Database Robustness </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#database_transactions_and_mvcc style=text-decoration:none>3.5. Database Transactions and MVCC </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#compressed_and_encrypted_databases style=text-decoration:none>4. Compressed and Encrypted Databases </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#performance_tuning style=text-decoration:none>5. Performance Tuning</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#architectural_overview style=text-decoration:none>5.1. Architectural Overview </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#work_and_checkpoint_scheduling style=text-decoration:none>5.2. Work and Checkpoint Scheduling </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#automatic_work_and_checkpoint_scheduling style=text-decoration:none>5.2.1. Automatic Work and Checkpoint Scheduling</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#explicit_work_and_checkpoint_scheduling style=text-decoration:none>5.2.2. Explicit Work and Checkpoint Scheduling</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#compulsary_work_and_checkpoint_scheduling style=text-decoration:none>5.2.3. Compulsary Work and Checkpoint Scheduling</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#database_optimization style=text-decoration:none>5.3. Database Optimization</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#other_parameters style=text-decoration:none>5.4. Other Parameters </a><br>

<div id=end_of_toc></div>

<h2>Overview</h2>

<p>This page describes the LSM embedded database library and use thereof. 
It is intended to be part user-manual and part tutorial.


<h1 id=overview_of_lsm>1. Introduction to LSM</h1>

<p>LSM is an embedded database library for key-value data, roughly similar
in scope to
<a href="http://www.oracle.com/technetwork/products/berkeleydb/overview/index.html">Berkeley DB</a>, 
<a href="http://code.google.com/p/leveldb/">LevelDB</a> or
<a href="http://fallabs.com/kyotocabinet/">KyotoCabinet</a>.
Both keys and
................................................................................
  }
</verbatim>

<verbatim>
  lsm_csr_close(csr);
</verbatim>

<h2 id=database_robustness>3.4. Database Robustness </h2>

<p>The value of the configuration parameter LSM_CONFIG_SAFETY determines
how often data is synced to disk by the LSM library. This is an important
tradeoff - syncing less often can lead to orders of magnitude better
performance, but also exposes the application to the risk of partial or total
data loss in the event of a power failure;

<table valign=top>
<tr> <td valign=top>LSM_SAFETY_OFF 
     <td valign=top style="padding-left:1ex;padding-right:1ex">(0)
     <td> Do not sync to disk at all. This is the fastest mode.
          <p>If a power failure occurs while writing to the database, 
          following recovery the database may be corrupt. All or some data may
          be recoverable.

<tr> <td valign=top>LSM_SAFETY_NORMAL 
     <td valign=top style="padding-left:1ex;padding-right:1ex">(1)
     <td> Sync only as much as is necessary to prevent database corruption.
         This is the default setting. Although slower than LSM_SAFETY_OFF, 
         this mode is still much faster than LSM_SAFETY_FULL.
     <p> If a power failure occurs while writing to the database, following
          recovery some recently committed transactions may have been lost.
          But the database file should not be corrupt and older data intact.

<tr> <td valign=top>LSM_SAFETY_FULL 
     <td valign=top style="padding-left:1ex;padding-right:1ex">(2)
     <td> Sync every transaction to disk as part of committing it. This is
          the slowest mode.
       <p>If a power failure occurs while writing to the database, all
          successfully committed transactions should be present.
          The database file should not be corrupt.
</table>

<p>The following example code sets the value of the LSM_CONFIG_SAFETY 
parameter for connection db to LSM_SAFETY_FULL:

<verbatim>
  int iSafety = LSM_SAFETY_FULL;
  lsm_config(db, LSM_CONFIG_SAFETY, &iSafety);
</verbatim>

<p>The current value of the LSM_CONFIG_SAFETY parameter can also be queried
by setting the initial value of the argument to -1 (or any other negative
value). For example:

<verbatim>
  int iSafety = -1;
  lsm_config(db, LSM_CONFIG_SAFETY, &iSafety);
  /* At this point, variable iSafety is set to the currently configured value
  ** of the LSM_CONFIG_SAFETY parameter (either 0, 1 or 2).  */
</verbatim>

<p>The lsm_config() function may also be used to configure other database
connection parameters.  

<h2 id=database_transactions_and_mvcc>3.5. Database Transactions and MVCC </h2>

<p>LSM supports a single-writer/multiple-reader 
<a href=http://en.wikipedia.org/wiki/Multiversion_concurrency_control>MVCC</a>
based transactional concurrency model. This is the same model that SQLite
supports in <a href="http://www.sqlite.org/wal.html">WAL mode</a>.

<p>A read-transaction must be opened in order to read from the database. 
................................................................................
  lsm_delete(db, "k", 1);
  lsm_rollback(db, 2);
  lsm_delete(db, "m", 1);
  lsm_commit(db, 0);
  
</verbatim>


























































<h1 id=compressed_and_encrypted_databases>4. Compressed and Encrypted Databases </h1>

<p>LSM does not provide built-in methods for creating encrypted or compressed
databases. Instead, it allows the user to provide hooks to call external
functions to compress and/or encrypt data before it is written to the database
file, and to decrypt and/or uncompress data as it is read from the database
file.

................................................................................
fails (no transaction or database cursor is opened).

<p><i>Maybe there should be a way to register a mismatch-handler callback.
Otherwise, applications have to handle LSM_MISMATCH everywhere...
</i>


<h1 id=performance_tuning>5. Performance Tuning</h1>

<h2 id=architectural_overview>5.1. Architectural Overview </h2>

<p> The LSM library implements two separate data structures that are used 
together to store user data. When the database is queried, the library 
actually runs parallel queries on both of these data stores and merges the
results together to return to the user. The data structures are:

<ul>
................................................................................
database file header (to checkpoint the database). 
</table>

<p>The tasks associated with each of the locks above may be performed
concurrently by multiple database connections, located either in the same
application process or different processes.

<h2 id=work_and_checkpoint_scheduling>5.2. Work and Checkpoint Scheduling </h2>

<p>The section above describes the three stages of transfering data written
to the database from the application to persistent storage. A "writer" 
client writes the data into the in-memory tree and log file. Later on a 
"worker" client flushes the data from the in-memory tree to a new segment
in the the database file. Additionally, a worker client must periodically
merge existing database segments together to prevent them from growing too
numerous.

<h3 id=automatic_work_and_checkpoint_scheduling>5.2.1. Automatic Work and Checkpoint Scheduling</h3>

<p>By default, database "work" (the flushing and merging of segments, performed
by clients holding the WORKER lock) and checkpointing are scheduled and
performed automatically from within calls to "write" API functions. The 
"write" functions are:

<ul>
................................................................................
than zero, after performing database work, the library automatically checks
how many bytes of raw data have been written to the database file since the
last checkpoint (by any client, not just by the current client). If this
value is greater than the value of the LSM_CONFIG_AUTOCHECKPOINT parameter,
a checkpoint is attempted. It is not an error if the attempt fails because the
CHECKPOINTER lock cannot be obtained.

<h3 id=explicit_work_and_checkpoint_scheduling>5.2.2. Explicit Work and Checkpoint Scheduling</h3>

<p>The alternative to automatic scheduling of work and checkpoint operations
is to explicitly schedule them. Possibly in a background thread or dedicated
application process. In order to disable automatic work, a client must set
the LSM_CONFIG_AUTOWORK parameter to zero. This parameter is a property of
a database connection, not of a database itself, so it must be cleared
separately by all processes that may write to the database. Otherwise, they
................................................................................
  rc = lsm_info(db, LSM_INFO_TREE_SIZE, &nOld, &nLive);
</verbatim>

<verbatim>
  int lsm_flush(lsm_db *db);
</verbatim>

<h3 id=compulsary_work_and_checkpoint_scheduling>5.2.3. Compulsary Work and Checkpoint Scheduling</h3>

<p>Apart from the scenarios described above, there are two there are two 
scenarios where database work or checkpointing may be performed automatically,
regardless of the value of the LSM_CONFIG_AUTOWORK parameter.

<ul>
  <li> When closing a database connection, and 
................................................................................
</ul>

<p>Finally, regardless of age, a database is limited to a maximum of 64
segments in total. If an attempt is made to flush an in-memory tree to disk
when the database already contains 64 segments, two or more existing segments
must be merged together before the new segment can be created.

<h2 id=database_optimization>5.3. Database Optimization</h2>

<p>Database optimization transforms the contents of database file so that
the following are true:

<ul>
  <li> All database content is stored in a single segment.
  <li> The database file contains no (or as little as possible) free space.
................................................................................
parameter should be set to a non-zero value, or otherwise lsm_checkpoint()
should be called periodically. Otherwise, no checkpoints will be performed,
preventing the library from reusing any space occupied by old segments even
after their content has been merged into the new segment. The result - a
database file that is optimized, except that it is up to twice as large as
it otherwise would be.

<h2 id=other_parameters>5.4. Other Parameters </h2>

<i>
<p>Mention other configuration options that can be used to tune performance
here.

<ul>
  <li> LSM_CONFIG_MMAP
  <li> LSM_CONFIG_MULTIPLE_PROCESSES
  <li> LSM_CONFIG_USE_LOG
</ul>

</i>













>

|





|
|
|
|
|
|
|
|
|
|
|






|
>

|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







 







|

|







 







|









|







 







|







 







|







 







|







 







|












<
<
<



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
...
216
217
218
219
220
221
222
























































223
224
225
226
227
228
229
230
...
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
...
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
...
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
...
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
...
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
...
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
...
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962



963
964
965

<title>LSM Users Guide</title>
<nowiki>

<h2>Table of Contents</h2>



<div id=start_of_toc></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#introduction_to_lsm style=text-decoration:none>1. Introduction to LSM</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#using_lsm_in_applications style=text-decoration:none>2. Using LSM in Applications </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#basic_usage style=text-decoration:none>3. Basic Usage</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#opening_and_closing_database_connections style=text-decoration:none>3.1. Opening and Closing Database Connections </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#writing_to_a_database style=text-decoration:none>3.2. Writing to a Database </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#reading_from_a_database style=text-decoration:none>3.3. Reading from a Database </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#database_transactions_and_mvcc style=text-decoration:none>3.4. Database Transactions and MVCC </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#database_robustness style=text-decoration:none>4. Database Robustness </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#compressed_and_encrypted_databases style=text-decoration:none>5. Compressed and Encrypted Databases </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#performance_tuning style=text-decoration:none>6. Performance Tuning</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#architectural_overview style=text-decoration:none>6.1. Architectural Overview </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#work_and_checkpoint_scheduling style=text-decoration:none>6.2. Work and Checkpoint Scheduling </a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#automatic_work_and_checkpoint_scheduling style=text-decoration:none>6.2.1. Automatic Work and Checkpoint Scheduling</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#explicit_work_and_checkpoint_scheduling style=text-decoration:none>6.2.2. Explicit Work and Checkpoint Scheduling</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#compulsary_work_and_checkpoint_scheduling style=text-decoration:none>6.2.3. Compulsary Work and Checkpoint Scheduling</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#database_optimization style=text-decoration:none>6.3. Database Optimization</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=#other_parameters style=text-decoration:none>6.4. Other Parameters </a><br>

<div id=end_of_toc></div>

<h2>Overview</h2>

<p>This page describes the LSM embedded database library and use thereof. 
It is intended to be part user-manual and part tutorial. It is intended to
to complement the <a href=lsmapi.wiki>LSM API reference manual</a>.

<h1 id=introduction_to_lsm>1. Introduction to LSM</h1>

<p>LSM is an embedded database library for key-value data, roughly similar
in scope to
<a href="http://www.oracle.com/technetwork/products/berkeleydb/overview/index.html">Berkeley DB</a>, 
<a href="http://code.google.com/p/leveldb/">LevelDB</a> or
<a href="http://fallabs.com/kyotocabinet/">KyotoCabinet</a>.
Both keys and
................................................................................
  }
</verbatim>

<verbatim>
  lsm_csr_close(csr);
</verbatim>

























































<h2 id=database_transactions_and_mvcc>3.4. Database Transactions and MVCC </h2>

<p>LSM supports a single-writer/multiple-reader 
<a href=http://en.wikipedia.org/wiki/Multiversion_concurrency_control>MVCC</a>
based transactional concurrency model. This is the same model that SQLite
supports in <a href="http://www.sqlite.org/wal.html">WAL mode</a>.

<p>A read-transaction must be opened in order to read from the database. 
................................................................................
  lsm_delete(db, "k", 1);
  lsm_rollback(db, 2);
  lsm_delete(db, "m", 1);
  lsm_commit(db, 0);
  
</verbatim>

<h1 id=database_robustness>4. Database Robustness </h1>

<p>The value of the configuration parameter LSM_CONFIG_SAFETY determines
how often data is synced to disk by the LSM library. This is an important
tradeoff - syncing less often can lead to orders of magnitude better
performance, but also exposes the application to the risk of partial or total
data loss in the event of a power failure;

<table valign=top>
<tr> <td valign=top>LSM_SAFETY_OFF 
     <td valign=top style="padding-left:1ex;padding-right:1ex">(0)
     <td> Do not sync to disk at all. This is the fastest mode.
          <p>If a power failure occurs while writing to the database, 
          following recovery the database may be corrupt. All or some data may
          be recoverable.

<tr> <td valign=top>LSM_SAFETY_NORMAL 
     <td valign=top style="padding-left:1ex;padding-right:1ex">(1)
     <td> Sync only as much as is necessary to prevent database corruption.
         This is the default setting. Although slower than LSM_SAFETY_OFF, 
         this mode is still much faster than LSM_SAFETY_FULL.
     <p> If a power failure occurs while writing to the database, following
          recovery some recently committed transactions may have been lost.
          But the database file should not be corrupt and older data intact.

<tr> <td valign=top>LSM_SAFETY_FULL 
     <td valign=top style="padding-left:1ex;padding-right:1ex">(2)
     <td> Sync every transaction to disk as part of committing it. This is
          the slowest mode.
       <p>If a power failure occurs while writing to the database, all
          successfully committed transactions should be present.
          The database file should not be corrupt.
</table>

<p>The following example code sets the value of the LSM_CONFIG_SAFETY 
parameter for connection db to LSM_SAFETY_FULL:

<verbatim>
  int iSafety = LSM_SAFETY_FULL;
  lsm_config(db, LSM_CONFIG_SAFETY, &iSafety);
</verbatim>

<p>The current value of the LSM_CONFIG_SAFETY parameter can also be queried
by setting the initial value of the argument to -1 (or any other negative
value). For example:

<verbatim>
  int iSafety = -1;
  lsm_config(db, LSM_CONFIG_SAFETY, &iSafety);
  /* At this point, variable iSafety is set to the currently configured value
  ** of the LSM_CONFIG_SAFETY parameter (either 0, 1 or 2).  */
</verbatim>

<p>The lsm_config() function may also be used to configure other database
connection parameters.  


<h1 id=compressed_and_encrypted_databases>5. Compressed and Encrypted Databases </h1>

<p>LSM does not provide built-in methods for creating encrypted or compressed
databases. Instead, it allows the user to provide hooks to call external
functions to compress and/or encrypt data before it is written to the database
file, and to decrypt and/or uncompress data as it is read from the database
file.

................................................................................
fails (no transaction or database cursor is opened).

<p><i>Maybe there should be a way to register a mismatch-handler callback.
Otherwise, applications have to handle LSM_MISMATCH everywhere...
</i>


<h1 id=performance_tuning>6. Performance Tuning</h1>

<h2 id=architectural_overview>6.1. Architectural Overview </h2>

<p> The LSM library implements two separate data structures that are used 
together to store user data. When the database is queried, the library 
actually runs parallel queries on both of these data stores and merges the
results together to return to the user. The data structures are:

<ul>
................................................................................
database file header (to checkpoint the database). 
</table>

<p>The tasks associated with each of the locks above may be performed
concurrently by multiple database connections, located either in the same
application process or different processes.

<h2 id=work_and_checkpoint_scheduling>6.2. Work and Checkpoint Scheduling </h2>

<p>The section above describes the three stages of transfering data written
to the database from the application to persistent storage. A "writer" 
client writes the data into the in-memory tree and log file. Later on a 
"worker" client flushes the data from the in-memory tree to a new segment
in the the database file. Additionally, a worker client must periodically
merge existing database segments together to prevent them from growing too
numerous.

<h3 id=automatic_work_and_checkpoint_scheduling>6.2.1. Automatic Work and Checkpoint Scheduling</h3>

<p>By default, database "work" (the flushing and merging of segments, performed
by clients holding the WORKER lock) and checkpointing are scheduled and
performed automatically from within calls to "write" API functions. The 
"write" functions are:

<ul>
................................................................................
than zero, after performing database work, the library automatically checks
how many bytes of raw data have been written to the database file since the
last checkpoint (by any client, not just by the current client). If this
value is greater than the value of the LSM_CONFIG_AUTOCHECKPOINT parameter,
a checkpoint is attempted. It is not an error if the attempt fails because the
CHECKPOINTER lock cannot be obtained.

<h3 id=explicit_work_and_checkpoint_scheduling>6.2.2. Explicit Work and Checkpoint Scheduling</h3>

<p>The alternative to automatic scheduling of work and checkpoint operations
is to explicitly schedule them. Possibly in a background thread or dedicated
application process. In order to disable automatic work, a client must set
the LSM_CONFIG_AUTOWORK parameter to zero. This parameter is a property of
a database connection, not of a database itself, so it must be cleared
separately by all processes that may write to the database. Otherwise, they
................................................................................
  rc = lsm_info(db, LSM_INFO_TREE_SIZE, &nOld, &nLive);
</verbatim>

<verbatim>
  int lsm_flush(lsm_db *db);
</verbatim>

<h3 id=compulsary_work_and_checkpoint_scheduling>6.2.3. Compulsary Work and Checkpoint Scheduling</h3>

<p>Apart from the scenarios described above, there are two there are two 
scenarios where database work or checkpointing may be performed automatically,
regardless of the value of the LSM_CONFIG_AUTOWORK parameter.

<ul>
  <li> When closing a database connection, and 
................................................................................
</ul>

<p>Finally, regardless of age, a database is limited to a maximum of 64
segments in total. If an attempt is made to flush an in-memory tree to disk
when the database already contains 64 segments, two or more existing segments
must be merged together before the new segment can be created.

<h2 id=database_optimization>6.3. Database Optimization</h2>

<p>Database optimization transforms the contents of database file so that
the following are true:

<ul>
  <li> All database content is stored in a single segment.
  <li> The database file contains no (or as little as possible) free space.
................................................................................
parameter should be set to a non-zero value, or otherwise lsm_checkpoint()
should be called periodically. Otherwise, no checkpoints will be performed,
preventing the library from reusing any space occupied by old segments even
after their content has been merged into the new segment. The result - a
database file that is optimized, except that it is up to twice as large as
it otherwise would be.

<h2 id=other_parameters>6.4. Other Parameters </h2>

<i>
<p>Mention other configuration options that can be used to tune performance
here.

<ul>
  <li> LSM_CONFIG_MMAP
  <li> LSM_CONFIG_MULTIPLE_PROCESSES
  <li> LSM_CONFIG_USE_LOG
</ul>

</i>