diff options
author | unknown <brian@zim.(none)> | 2005-04-26 18:19:54 -0700 |
---|---|---|
committer | unknown <brian@zim.(none)> | 2005-04-26 18:19:54 -0700 |
commit | b7e422be1b7a8ca3f4e761e67db5e8febc701dfd (patch) | |
tree | df9016f3d70b4657f89dcddca2ec4e188fc7fbdf /myisam | |
parent | c0333ecee42a4de499b3377cfa21d7b5af1ddd2b (diff) | |
download | mariadb-git-b7e422be1b7a8ca3f4e761e67db5e8febc701dfd.tar.gz |
Changes to create storage directory for storage engines.
storage/heap/.cvsignore:
mvdir
storage/heap/ChangeLog:
mvdir
storage/heap/Makefile.am:
mvdir
storage/heap/_check.c:
mvdir
storage/heap/_rectest.c:
mvdir
storage/heap/heapdef.h:
mvdir
storage/heap/hp_block.c:
mvdir
storage/heap/hp_clear.c:
mvdir
storage/heap/hp_close.c:
mvdir
storage/heap/hp_create.c:
mvdir
storage/heap/hp_delete.c:
mvdir
storage/heap/hp_extra.c:
mvdir
storage/heap/hp_hash.c:
mvdir
storage/heap/hp_info.c:
mvdir
storage/heap/hp_open.c:
mvdir
storage/heap/hp_panic.c:
mvdir
storage/heap/hp_rename.c:
mvdir
storage/heap/hp_rfirst.c:
mvdir
storage/heap/hp_rkey.c:
mvdir
storage/heap/hp_rlast.c:
mvdir
storage/heap/hp_rnext.c:
mvdir
storage/heap/hp_rprev.c:
mvdir
storage/heap/hp_rrnd.c:
mvdir
storage/heap/hp_rsame.c:
mvdir
storage/heap/hp_scan.c:
mvdir
storage/heap/hp_static.c:
mvdir
storage/heap/hp_test1.c:
mvdir
storage/heap/hp_test2.c:
mvdir
storage/heap/hp_update.c:
mvdir
storage/heap/hp_write.c:
mvdir
storage/heap/make-ccc:
mvdir
storage/myisam/.cvsignore:
mvdir
storage/myisam/ChangeLog:
mvdir
storage/myisam/Makefile.am:
mvdir
storage/myisam/NEWS:
mvdir
storage/myisam/TODO:
mvdir
storage/myisam/ft_boolean_search.c:
mvdir
storage/myisam/ft_eval.c:
mvdir
storage/myisam/ft_eval.h:
mvdir
storage/myisam/ft_nlq_search.c:
mvdir
storage/myisam/ft_parser.c:
mvdir
storage/myisam/ft_static.c:
mvdir
storage/myisam/ft_stem.c:
mvdir
storage/myisam/ft_stopwords.c:
mvdir
storage/myisam/ft_test1.c:
mvdir
storage/myisam/ft_test1.h:
mvdir
storage/myisam/ft_update.c:
mvdir
storage/myisam/ftdefs.h:
mvdir
storage/myisam/fulltext.h:
mvdir
storage/myisam/make-ccc:
mvdir
storage/myisam/mi_cache.c:
mvdir
storage/myisam/mi_changed.c:
mvdir
storage/myisam/mi_check.c:
mvdir
storage/myisam/mi_checksum.c:
mvdir
storage/myisam/mi_close.c:
mvdir
storage/myisam/mi_create.c:
mvdir
storage/myisam/mi_dbug.c:
mvdir
storage/myisam/mi_delete.c:
mvdir
storage/myisam/mi_delete_all.c:
mvdir
storage/myisam/mi_delete_table.c:
mvdir
storage/myisam/mi_dynrec.c:
mvdir
storage/myisam/mi_extra.c:
mvdir
storage/myisam/mi_info.c:
mvdir
storage/myisam/mi_key.c:
mvdir
storage/myisam/mi_keycache.c:
mvdir
storage/myisam/mi_locking.c:
mvdir
storage/myisam/mi_log.c:
mvdir
storage/myisam/mi_open.c:
mvdir
storage/myisam/mi_packrec.c:
mvdir
storage/myisam/mi_page.c:
mvdir
storage/myisam/mi_panic.c:
mvdir
storage/myisam/mi_preload.c:
mvdir
storage/myisam/mi_range.c:
mvdir
storage/myisam/mi_rename.c:
mvdir
storage/myisam/mi_rfirst.c:
mvdir
storage/myisam/mi_rkey.c:
mvdir
storage/myisam/mi_rlast.c:
mvdir
storage/myisam/mi_rnext.c:
mvdir
storage/myisam/mi_rnext_same.c:
mvdir
storage/myisam/mi_rprev.c:
mvdir
storage/myisam/mi_rrnd.c:
mvdir
storage/myisam/mi_rsame.c:
mvdir
storage/myisam/ftbench/Ecompare.pl:
mvdir
storage/myisam/ftbench/Ecreate.pl:
mvdir
storage/myisam/ftbench/Ereport.pl:
mvdir
storage/myisam/ftbench/README:
mvdir
storage/myisam/ftbench/ft-test-run.sh:
mvdir
storage/myisam/mi_rsamepos.c:
mvdir
storage/myisam/mi_scan.c:
mvdir
storage/myisam/mi_search.c:
mvdir
storage/myisam/mi_static.c:
mvdir
storage/myisam/mi_statrec.c:
mvdir
storage/myisam/mi_test1.c:
mvdir
storage/myisam/mi_test2.c:
mvdir
storage/myisam/mi_test3.c:
mvdir
storage/myisam/mi_test_all.res:
mvdir
storage/myisam/mi_test_all.sh:
mvdir
storage/myisam/mi_unique.c:
mvdir
storage/myisam/mi_update.c:
mvdir
storage/myisam/mi_write.c:
mvdir
storage/myisam/myisam_ftdump.c:
mvdir
storage/myisam/myisamchk.c:
mvdir
storage/myisam/myisamdef.h:
mvdir
storage/myisam/myisamlog.c:
mvdir
storage/myisam/myisampack.c:
mvdir
storage/myisam/rt_index.c:
mvdir
storage/myisam/rt_index.h:
mvdir
storage/myisam/rt_key.c:
mvdir
storage/myisam/rt_key.h:
mvdir
storage/myisam/rt_mbr.c:
mvdir
storage/myisam/rt_mbr.h:
mvdir
storage/myisam/rt_split.c:
mvdir
storage/myisam/rt_test.c:
mvdir
storage/myisam/sort.c:
mvdir
storage/myisam/sp_defs.h:
mvdir
storage/myisam/sp_key.c:
mvdir
storage/myisam/sp_test.c:
mvdir
storage/myisam/test_pack:
mvdir
storage/myisammrg/.cvsignore:
mvdir
storage/myisammrg/Makefile.am:
mvdir
storage/myisammrg/make-ccc:
mvdir
storage/myisammrg/myrg_close.c:
mvdir
storage/myisammrg/myrg_create.c:
mvdir
storage/myisammrg/myrg_def.h:
mvdir
storage/myisammrg/myrg_delete.c:
mvdir
storage/myisammrg/myrg_extra.c:
mvdir
storage/myisammrg/myrg_info.c:
mvdir
storage/myisammrg/myrg_locking.c:
mvdir
storage/myisammrg/myrg_open.c:
mvdir
storage/myisammrg/myrg_panic.c:
mvdir
storage/myisammrg/myrg_queue.c:
mvdir
storage/myisammrg/myrg_range.c:
mvdir
storage/myisammrg/myrg_rfirst.c:
mvdir
storage/myisammrg/myrg_rkey.c:
mvdir
storage/myisammrg/myrg_rlast.c:
mvdir
storage/myisammrg/myrg_rnext.c:
mvdir
storage/myisammrg/myrg_rnext_same.c:
mvdir
storage/myisammrg/myrg_rprev.c:
mvdir
storage/myisammrg/myrg_rrnd.c:
mvdir
storage/myisammrg/myrg_rsame.c:
mvdir
storage/myisammrg/myrg_static.c:
mvdir
storage/myisammrg/myrg_update.c:
mvdir
storage/myisammrg/myrg_write.c:
mvdir
storage/innobase/Makefile.am:
mvdir
storage/innobase/btr/Makefile.am:
mvdir
storage/innobase/btr/btr0btr.c:
mvdir
storage/innobase/btr/btr0cur.c:
mvdir
storage/innobase/btr/btr0pcur.c:
mvdir
storage/innobase/btr/btr0sea.c:
mvdir
storage/innobase/btr/makefilewin:
mvdir
storage/innobase/buf/Makefile.am:
mvdir
storage/innobase/buf/buf0buf.c:
mvdir
storage/innobase/buf/buf0flu.c:
mvdir
storage/innobase/buf/buf0lru.c:
mvdir
storage/innobase/buf/buf0rea.c:
mvdir
storage/innobase/buf/makefilewin:
mvdir
storage/innobase/configure.in:
mvdir
storage/innobase/data/Makefile.am:
mvdir
storage/innobase/data/data0data.c:
mvdir
storage/innobase/data/data0type.c:
mvdir
storage/innobase/data/makefilewin:
mvdir
storage/innobase/db/db0err.h:
mvdir
storage/innobase/dict/Makefile.am:
mvdir
storage/innobase/dict/dict0boot.c:
mvdir
storage/innobase/dict/dict0crea.c:
mvdir
storage/innobase/dict/dict0dict.c:
mvdir
storage/innobase/dict/dict0load.c:
mvdir
storage/innobase/makefilewin:
mvdir
storage/innobase/my_cnf:
mvdir
storage/innobase/dict/dict0mem.c:
mvdir
storage/innobase/dict/makefilewin:
mvdir
storage/innobase/dyn/Makefile.am:
mvdir
storage/innobase/dyn/dyn0dyn.c:
mvdir
storage/innobase/dyn/makefilewin:
mvdir
storage/innobase/eval/Makefile.am:
mvdir
storage/innobase/eval/eval0eval.c:
mvdir
storage/innobase/eval/eval0proc.c:
mvdir
storage/innobase/eval/makefilewin:
mvdir
storage/innobase/fil/Makefile.am:
mvdir
storage/innobase/fil/fil0fil.c:
mvdir
storage/innobase/fil/makefilewin:
mvdir
storage/innobase/fsp/Makefile.am:
mvdir
storage/innobase/fsp/fsp0fsp.c:
mvdir
storage/innobase/fsp/makefilewin:
mvdir
storage/innobase/fut/Makefile.am:
mvdir
storage/innobase/fut/fut0fut.c:
mvdir
storage/innobase/fut/fut0lst.c:
mvdir
storage/innobase/fut/makefilewin:
mvdir
storage/innobase/ha/Makefile.am:
mvdir
storage/innobase/ha/ha0ha.c:
mvdir
storage/innobase/ha/hash0hash.c:
mvdir
storage/innobase/ha/makefilewin:
mvdir
storage/innobase/ibuf/Makefile.am:
mvdir
storage/innobase/ibuf/ibuf0ibuf.c:
mvdir
storage/innobase/ibuf/makefilewin:
mvdir
storage/innobase/include/Makefile.am:
mvdir
storage/innobase/include/Makefile.i:
mvdir
storage/innobase/include/btr0btr.h:
mvdir
storage/innobase/include/btr0btr.ic:
mvdir
storage/innobase/include/btr0cur.h:
mvdir
storage/innobase/include/btr0cur.ic:
mvdir
storage/innobase/include/btr0pcur.h:
mvdir
storage/innobase/include/btr0pcur.ic:
mvdir
storage/innobase/include/btr0sea.h:
mvdir
storage/innobase/include/btr0sea.ic:
mvdir
storage/innobase/include/btr0types.h:
mvdir
storage/innobase/include/buf0buf.h:
mvdir
storage/innobase/include/buf0buf.ic:
mvdir
storage/innobase/include/buf0flu.h:
mvdir
storage/innobase/include/buf0flu.ic:
mvdir
storage/innobase/include/buf0lru.h:
mvdir
storage/innobase/include/buf0lru.ic:
mvdir
storage/innobase/include/buf0rea.h:
mvdir
storage/innobase/include/buf0types.h:
mvdir
storage/innobase/include/data0data.h:
mvdir
storage/innobase/include/data0data.ic:
mvdir
storage/innobase/include/data0type.h:
mvdir
storage/innobase/include/data0type.ic:
mvdir
storage/innobase/include/data0types.h:
mvdir
storage/innobase/include/db0err.h:
mvdir
storage/innobase/include/dict0boot.h:
mvdir
storage/innobase/include/dict0boot.ic:
mvdir
storage/innobase/include/dict0crea.h:
mvdir
storage/innobase/include/dict0crea.ic:
mvdir
storage/innobase/include/dict0dict.h:
mvdir
storage/innobase/include/dict0dict.ic:
mvdir
storage/innobase/include/dict0load.h:
mvdir
storage/innobase/include/dict0load.ic:
mvdir
storage/innobase/include/dict0mem.h:
mvdir
storage/innobase/include/dict0mem.ic:
mvdir
storage/innobase/include/dict0types.h:
mvdir
storage/innobase/include/dyn0dyn.h:
mvdir
storage/innobase/include/dyn0dyn.ic:
mvdir
storage/innobase/include/eval0eval.h:
mvdir
storage/innobase/include/eval0eval.ic:
mvdir
storage/innobase/include/eval0proc.h:
mvdir
storage/innobase/include/eval0proc.ic:
mvdir
storage/innobase/include/fil0fil.h:
mvdir
storage/innobase/include/fsp0fsp.h:
mvdir
storage/innobase/include/fsp0fsp.ic:
mvdir
storage/innobase/include/fut0fut.h:
mvdir
storage/innobase/include/fut0fut.ic:
mvdir
storage/innobase/include/fut0lst.h:
mvdir
storage/innobase/include/fut0lst.ic:
mvdir
storage/innobase/include/ha0ha.h:
mvdir
storage/innobase/include/ha0ha.ic:
mvdir
storage/innobase/include/hash0hash.h:
mvdir
storage/innobase/include/hash0hash.ic:
mvdir
storage/innobase/include/ibuf0ibuf.h:
mvdir
storage/innobase/include/ibuf0ibuf.ic:
mvdir
storage/innobase/include/ibuf0types.h:
mvdir
storage/innobase/include/lock0lock.h:
mvdir
storage/innobase/include/lock0lock.ic:
mvdir
storage/innobase/include/lock0types.h:
mvdir
storage/innobase/include/log0log.h:
mvdir
storage/innobase/include/log0log.ic:
mvdir
storage/innobase/include/log0recv.h:
mvdir
storage/innobase/include/log0recv.ic:
mvdir
storage/innobase/include/mach0data.h:
mvdir
storage/innobase/include/mach0data.ic:
mvdir
storage/innobase/include/makefilewin.i:
mvdir
storage/innobase/include/mem0dbg.h:
mvdir
storage/innobase/include/mem0dbg.ic:
mvdir
storage/innobase/include/mem0mem.h:
mvdir
storage/innobase/include/mem0mem.ic:
mvdir
storage/innobase/include/mem0pool.h:
mvdir
storage/innobase/include/mem0pool.ic:
mvdir
storage/innobase/include/mtr0log.h:
mvdir
storage/innobase/include/mtr0log.ic:
mvdir
storage/innobase/include/mtr0mtr.h:
mvdir
storage/innobase/include/mtr0mtr.ic:
mvdir
storage/innobase/include/mtr0types.h:
mvdir
storage/innobase/include/os0file.h:
mvdir
storage/innobase/include/os0proc.h:
mvdir
storage/innobase/include/os0proc.ic:
mvdir
storage/innobase/include/os0sync.h:
mvdir
storage/innobase/include/os0sync.ic:
mvdir
storage/innobase/include/os0thread.h:
mvdir
storage/innobase/include/os0thread.ic:
mvdir
storage/innobase/include/page0cur.h:
mvdir
storage/innobase/include/page0cur.ic:
mvdir
storage/innobase/include/page0page.h:
mvdir
storage/innobase/include/page0page.ic:
mvdir
storage/innobase/include/page0types.h:
mvdir
storage/innobase/include/pars0grm.h:
mvdir
storage/innobase/include/pars0opt.h:
mvdir
storage/innobase/include/pars0opt.ic:
mvdir
storage/innobase/include/pars0pars.h:
mvdir
storage/innobase/include/pars0pars.ic:
mvdir
storage/innobase/include/pars0sym.h:
mvdir
storage/innobase/include/pars0sym.ic:
mvdir
storage/innobase/include/pars0types.h:
mvdir
storage/innobase/include/que0que.h:
mvdir
storage/innobase/include/que0que.ic:
mvdir
storage/innobase/include/que0types.h:
mvdir
storage/innobase/include/read0read.h:
mvdir
storage/innobase/include/read0read.ic:
mvdir
storage/innobase/include/read0types.h:
mvdir
storage/innobase/include/rem0cmp.h:
mvdir
storage/innobase/include/rem0cmp.ic:
mvdir
storage/innobase/include/rem0rec.h:
mvdir
storage/innobase/include/rem0rec.ic:
mvdir
storage/innobase/include/rem0types.h:
mvdir
storage/innobase/include/row0ins.h:
mvdir
storage/innobase/include/row0ins.ic:
mvdir
storage/innobase/include/row0mysql.h:
mvdir
storage/innobase/include/row0mysql.ic:
mvdir
storage/innobase/include/row0purge.h:
mvdir
storage/innobase/include/row0purge.ic:
mvdir
storage/innobase/include/row0row.h:
mvdir
storage/innobase/include/row0row.ic:
mvdir
storage/innobase/include/row0sel.h:
mvdir
storage/innobase/include/row0sel.ic:
mvdir
storage/innobase/include/row0types.h:
mvdir
storage/innobase/include/row0uins.h:
mvdir
storage/innobase/include/row0uins.ic:
mvdir
storage/innobase/include/row0umod.h:
mvdir
storage/innobase/include/row0umod.ic:
mvdir
storage/innobase/include/row0undo.h:
mvdir
storage/innobase/include/row0undo.ic:
mvdir
storage/innobase/include/row0upd.h:
mvdir
storage/innobase/include/row0upd.ic:
mvdir
storage/innobase/include/row0vers.h:
mvdir
storage/innobase/include/row0vers.ic:
mvdir
storage/innobase/include/srv0que.h:
mvdir
storage/innobase/include/srv0srv.h:
mvdir
storage/innobase/include/srv0srv.ic:
mvdir
storage/innobase/include/srv0start.h:
mvdir
storage/innobase/include/sync0arr.h:
mvdir
storage/innobase/include/sync0arr.ic:
mvdir
storage/innobase/include/sync0rw.h:
mvdir
storage/innobase/include/sync0rw.ic:
mvdir
storage/innobase/include/sync0sync.h:
mvdir
storage/innobase/include/sync0sync.ic:
mvdir
storage/innobase/include/sync0types.h:
mvdir
storage/innobase/include/thr0loc.h:
mvdir
storage/innobase/include/thr0loc.ic:
mvdir
storage/innobase/include/trx0purge.h:
mvdir
storage/innobase/include/trx0purge.ic:
mvdir
storage/innobase/include/trx0rec.h:
mvdir
storage/innobase/include/trx0rec.ic:
mvdir
storage/innobase/include/trx0roll.h:
mvdir
storage/innobase/include/trx0roll.ic:
mvdir
storage/innobase/include/trx0rseg.h:
mvdir
storage/innobase/include/trx0rseg.ic:
mvdir
storage/innobase/include/trx0sys.h:
mvdir
storage/innobase/include/trx0sys.ic:
mvdir
storage/innobase/include/trx0trx.h:
mvdir
storage/innobase/include/trx0trx.ic:
mvdir
storage/innobase/include/trx0types.h:
mvdir
storage/innobase/include/trx0undo.h:
mvdir
storage/innobase/include/trx0undo.ic:
mvdir
storage/innobase/include/trx0xa.h:
mvdir
storage/innobase/include/univ.i:
mvdir
storage/innobase/include/usr0sess.h:
mvdir
storage/innobase/include/usr0sess.ic:
mvdir
storage/innobase/include/usr0types.h:
mvdir
storage/innobase/include/ut0byte.h:
mvdir
storage/innobase/include/ut0byte.ic:
mvdir
storage/innobase/include/ut0dbg.h:
mvdir
storage/innobase/include/ut0lst.h:
mvdir
storage/innobase/include/ut0mem.h:
mvdir
storage/innobase/include/ut0mem.ic:
mvdir
storage/innobase/include/ut0rnd.h:
mvdir
storage/innobase/include/ut0rnd.ic:
mvdir
storage/innobase/include/ut0sort.h:
mvdir
storage/innobase/include/ut0ut.h:
mvdir
storage/innobase/include/ut0ut.ic:
mvdir
storage/innobase/lock/Makefile.am:
mvdir
storage/innobase/lock/lock0lock.c:
mvdir
storage/innobase/lock/makefilewin:
mvdir
storage/innobase/log/Makefile.am:
mvdir
storage/innobase/log/log0log.c:
mvdir
storage/innobase/log/log0recv.c:
mvdir
storage/innobase/log/makefilewin:
mvdir
storage/innobase/mach/Makefile.am:
mvdir
storage/innobase/mach/mach0data.c:
mvdir
storage/innobase/mach/makefilewin:
mvdir
storage/innobase/mem/Makefile.am:
mvdir
storage/innobase/mem/makefilewin:
mvdir
storage/innobase/mem/mem0dbg.c:
mvdir
storage/innobase/mem/mem0mem.c:
mvdir
storage/innobase/mem/mem0pool.c:
mvdir
storage/innobase/mtr/Makefile.am:
mvdir
storage/innobase/mtr/makefilewin:
mvdir
storage/innobase/mtr/mtr0log.c:
mvdir
storage/innobase/mtr/mtr0mtr.c:
mvdir
storage/innobase/os/Makefile.am:
mvdir
storage/innobase/os/makefilewin:
mvdir
storage/innobase/os/os0file.c:
mvdir
storage/innobase/os/os0proc.c:
mvdir
storage/innobase/os/os0sync.c:
mvdir
storage/innobase/os/os0thread.c:
mvdir
storage/innobase/page/Makefile.am:
mvdir
storage/innobase/page/makefilewin:
mvdir
storage/innobase/page/page0cur.c:
mvdir
storage/innobase/page/page0page.c:
mvdir
storage/innobase/pars/Makefile.am:
mvdir
storage/innobase/pars/lexyy.c:
mvdir
storage/innobase/pars/makefilewin:
mvdir
storage/innobase/pars/pars0grm.c:
mvdir
storage/innobase/pars/pars0grm.h:
mvdir
storage/innobase/pars/pars0grm.y:
mvdir
storage/innobase/pars/pars0lex.l:
mvdir
storage/innobase/pars/pars0opt.c:
mvdir
storage/innobase/pars/pars0pars.c:
mvdir
storage/innobase/pars/pars0sym.c:
mvdir
storage/innobase/que/Makefile.am:
mvdir
storage/innobase/que/makefilewin:
mvdir
storage/innobase/que/que0que.c:
mvdir
storage/innobase/read/Makefile.am:
mvdir
storage/innobase/read/makefilewin:
mvdir
storage/innobase/read/read0read.c:
mvdir
storage/innobase/rem/Makefile.am:
mvdir
storage/innobase/rem/makefilewin:
mvdir
storage/innobase/rem/rem0cmp.c:
mvdir
storage/innobase/rem/rem0rec.c:
mvdir
storage/innobase/row/Makefile.am:
mvdir
storage/innobase/row/makefilewin:
mvdir
storage/innobase/row/row0ins.c:
mvdir
storage/innobase/row/row0mysql.c:
mvdir
storage/innobase/row/row0purge.c:
mvdir
storage/innobase/row/row0row.c:
mvdir
storage/innobase/row/row0sel.c:
mvdir
storage/innobase/row/row0uins.c:
mvdir
storage/innobase/row/row0umod.c:
mvdir
storage/innobase/row/row0undo.c:
mvdir
storage/innobase/row/row0upd.c:
mvdir
storage/innobase/row/row0vers.c:
mvdir
storage/innobase/srv/Makefile.am:
mvdir
storage/innobase/srv/makefilewin:
mvdir
storage/innobase/srv/srv0que.c:
mvdir
storage/innobase/srv/srv0srv.c:
mvdir
storage/innobase/srv/srv0start.c:
mvdir
storage/innobase/sync/Makefile.am:
mvdir
storage/innobase/sync/makefilewin:
mvdir
storage/innobase/sync/sync0arr.c:
mvdir
storage/innobase/sync/sync0rw.c:
mvdir
storage/innobase/sync/sync0sync.c:
mvdir
storage/innobase/thr/Makefile.am:
mvdir
storage/innobase/thr/makefilewin:
mvdir
storage/innobase/thr/thr0loc.c:
mvdir
storage/innobase/trx/Makefile.am:
mvdir
storage/innobase/trx/makefilewin:
mvdir
storage/innobase/trx/trx0purge.c:
mvdir
storage/innobase/trx/trx0rec.c:
mvdir
storage/innobase/trx/trx0roll.c:
mvdir
storage/innobase/trx/trx0rseg.c:
mvdir
storage/innobase/trx/trx0sys.c:
mvdir
storage/innobase/trx/trx0trx.c:
mvdir
storage/innobase/trx/trx0undo.c:
mvdir
storage/innobase/usr/Makefile.am:
mvdir
storage/innobase/usr/makefilewin:
mvdir
storage/innobase/usr/usr0sess.c:
mvdir
storage/innobase/ut/Makefile.am:
mvdir
storage/innobase/ut/makefilewin:
mvdir
storage/innobase/ut/ut0byte.c:
mvdir
storage/innobase/ut/ut0dbg.c:
mvdir
storage/innobase/ut/ut0mem.c:
mvdir
storage/innobase/ut/ut0rnd.c:
mvdir
storage/innobase/ut/ut0ut.c:
mvdir
storage/ndb/Makefile.am:
mvdir
storage/ndb/bin/.empty:
mvdir
storage/ndb/bin/check-regression.sh:
mvdir
storage/ndb/bin/makeTestPrograms_html.sh:
mvdir
storage/ndb/config/common.mk.am:
mvdir
storage/ndb/config/make-win-dsw.sh:
mvdir
storage/ndb/config/type_kernel.mk.am:
mvdir
storage/ndb/config/type_mgmapiclient.mk.am:
mvdir
storage/ndb/config/type_ndbapi.mk.am:
mvdir
storage/ndb/config/type_ndbapiclient.mk.am:
mvdir
storage/ndb/config/type_ndbapitest.mk.am:
mvdir
storage/ndb/config/type_ndbapitools.mk.am:
mvdir
storage/ndb/config/type_util.mk.am:
mvdir
storage/ndb/config/win-includes:
mvdir
storage/ndb/config/win-lib.am:
mvdir
storage/ndb/config/win-libraries:
mvdir
storage/ndb/config/win-name:
mvdir
storage/ndb/config/win-prg.am:
mvdir
storage/ndb/config/win-sources:
mvdir
storage/ndb/demos/1-node/1-api-3/Ndb.cfg:
mvdir
storage/ndb/demos/1-node/1-db-2/Ndb.cfg:
mvdir
storage/ndb/demos/1-node/1-mgm-1/Ndb.cfg:
mvdir
storage/ndb/demos/1-node/1-mgm-1/template_config.ini:
mvdir
storage/ndb/demos/2-node/2-api-4/Ndb.cfg:
mvdir
storage/ndb/demos/2-node/2-api-5/Ndb.cfg:
mvdir
storage/ndb/demos/2-node/2-api-6/Ndb.cfg:
mvdir
storage/ndb/demos/2-node/2-api-7/Ndb.cfg:
mvdir
storage/ndb/demos/2-node/2-db-2/Ndb.cfg:
mvdir
storage/ndb/demos/2-node/2-db-3/Ndb.cfg:
mvdir
storage/ndb/demos/2-node/2-mgm-1/Ndb.cfg:
mvdir
storage/ndb/demos/2-node/2-mgm-1/template_config.ini:
mvdir
storage/ndb/demos/config-templates/config_template-1-REP.ini:
mvdir
storage/ndb/demos/config-templates/config_template-4.ini:
mvdir
storage/ndb/demos/config-templates/config_template-install.ini:
mvdir
storage/ndb/demos/run_demo1-PS-SS_common.sh:
mvdir
storage/ndb/demos/run_demo1-PS.sh:
mvdir
storage/ndb/demos/run_demo1-SS.sh:
mvdir
storage/ndb/demos/run_demo1.sh:
mvdir
storage/ndb/demos/run_demo2.sh:
mvdir
storage/ndb/docs/Makefile.am:
mvdir
storage/ndb/docs/README:
mvdir
storage/ndb/docs/doxygen/Doxyfile.mgmapi:
mvdir
storage/ndb/docs/doxygen/Doxyfile.ndbapi:
mvdir
storage/ndb/docs/doxygen/Doxyfile.ndb:
mvdir
storage/ndb/docs/doxygen/Doxyfile.odbc:
mvdir
storage/ndb/docs/doxygen/Doxyfile.test:
mvdir
storage/ndb/docs/doxygen/header.mgmapi.tex:
mvdir
storage/ndb/docs/doxygen/header.ndbapi.tex:
mvdir
storage/ndb/docs/doxygen/postdoxy.pl:
mvdir
storage/ndb/docs/doxygen/predoxy.pl:
mvdir
storage/ndb/docs/wl2077.txt:
mvdir
storage/ndb/home/bin/Linuxmkisofs:
mvdir
storage/ndb/home/bin/Solarismkisofs:
mvdir
storage/ndb/home/bin/cvs2cl.pl:
mvdir
storage/ndb/home/bin/fix-cvs-root:
mvdir
storage/ndb/home/bin/import-from-bk.sh:
mvdir
storage/ndb/home/bin/ndb_deploy:
mvdir
storage/ndb/home/bin/ndbdoxy.pl:
mvdir
storage/ndb/home/bin/ngcalc:
mvdir
storage/ndb/home/bin/parseConfigFile.awk:
mvdir
storage/ndb/home/bin/setup-test.sh:
mvdir
storage/ndb/home/bin/signallog2html.lib/signallog2list.awk:
mvdir
storage/ndb/home/bin/signallog2html.lib/uniq_blocks.awk:
mvdir
storage/ndb/home/bin/signallog2html.sh:
mvdir
storage/ndb/home/bin/stripcr:
mvdir
storage/ndb/home/lib/funcs.sh:
mvdir
storage/ndb/include/Makefile.am:
mvdir
storage/ndb/include/debugger/DebuggerNames.hpp:
mvdir
storage/ndb/include/debugger/EventLogger.hpp:
mvdir
storage/ndb/include/debugger/GrepError.hpp:
mvdir
storage/ndb/include/debugger/SignalLoggerManager.hpp:
mvdir
storage/ndb/include/editline/editline.h:
mvdir
storage/ndb/include/kernel/AttributeDescriptor.hpp:
mvdir
storage/ndb/include/kernel/AttributeHeader.hpp:
mvdir
storage/ndb/include/kernel/AttributeList.hpp:
mvdir
storage/ndb/include/kernel/BlockNumbers.h:
mvdir
storage/ndb/include/kernel/GlobalSignalNumbers.h:
mvdir
storage/ndb/include/kernel/GrepEvent.hpp:
mvdir
storage/ndb/include/kernel/Interpreter.hpp:
mvdir
storage/ndb/include/kernel/LogLevel.hpp:
mvdir
storage/ndb/include/kernel/NodeBitmask.hpp:
mvdir
storage/ndb/include/kernel/NodeInfo.hpp:
mvdir
storage/ndb/include/kernel/NodeState.hpp:
mvdir
storage/ndb/include/kernel/RefConvert.hpp:
mvdir
storage/ndb/include/kernel/kernel_config_parameters.h:
mvdir
storage/ndb/include/kernel/kernel_types.h:
mvdir
storage/ndb/include/kernel/ndb_limits.h:
mvdir
storage/ndb/include/kernel/signaldata/AbortAll.hpp:
mvdir
storage/ndb/include/kernel/signaldata/AccFrag.hpp:
mvdir
storage/ndb/include/kernel/signaldata/AccLock.hpp:
mvdir
storage/ndb/include/kernel/signaldata/AccScan.hpp:
mvdir
storage/ndb/include/kernel/signaldata/AccSizeAltReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/AlterIndx.hpp:
mvdir
storage/ndb/include/kernel/signaldata/AlterTab.hpp:
mvdir
storage/ndb/include/kernel/signaldata/AlterTable.hpp:
mvdir
storage/ndb/include/kernel/signaldata/AlterTrig.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ApiRegSignalData.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ApiVersion.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ArbitSignalData.hpp:
mvdir
storage/ndb/include/kernel/signaldata/AttrInfo.hpp:
mvdir
storage/ndb/include/kernel/trigger_definitions.h:
mvdir
storage/ndb/include/ndb_constants.h:
mvdir
storage/ndb/include/ndb_global.h.in:
mvdir
storage/ndb/include/ndb_init.h:
mvdir
storage/ndb/include/ndb_net.h:
mvdir
storage/ndb/include/ndb_types.h.in:
mvdir
storage/ndb/include/ndb_version.h.in:
mvdir
storage/ndb/include/kernel/signaldata/BackupContinueB.hpp:
mvdir
storage/ndb/include/kernel/signaldata/BackupImpl.hpp:
mvdir
storage/ndb/include/kernel/signaldata/BackupSignalData.hpp:
mvdir
storage/ndb/include/kernel/signaldata/BlockCommitOrd.hpp:
mvdir
storage/ndb/include/kernel/signaldata/BuildIndx.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CheckNodeGroups.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CloseComReqConf.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CmInit.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CmRegSignalData.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CmvmiCfgConf.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CntrMasterConf.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CntrMasterReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CntrStart.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ConfigParamId.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ContinueFragmented.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CopyActive.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CopyFrag.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CopyGCIReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CreateEvnt.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CreateFrag.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CreateFragmentation.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CreateIndx.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CreateTab.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CreateTable.hpp:
mvdir
storage/ndb/include/kernel/signaldata/CreateTrig.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DiAddTab.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DiGetNodes.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DictSchemaInfo.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DictSizeAltReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DictStart.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DictTabInfo.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DihAddFrag.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DihContinueB.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DihSizeAltReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DihStartTab.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DihSwitchReplica.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DisconnectRep.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DropIndx.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DropTab.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DropTabFile.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DropTable.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DropTrig.hpp:
mvdir
storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp:
mvdir
storage/ndb/include/kernel/signaldata/EmptyLcp.hpp:
mvdir
storage/ndb/include/kernel/signaldata/EndTo.hpp:
mvdir
storage/ndb/include/kernel/signaldata/EventReport.hpp:
mvdir
storage/ndb/include/kernel/signaldata/EventSubscribeReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ExecFragReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/FailRep.hpp:
mvdir
storage/ndb/include/kernel/signaldata/FireTrigOrd.hpp:
mvdir
storage/ndb/include/kernel/signaldata/FsAppendReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/FsCloseReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/FsConf.hpp:
mvdir
storage/ndb/include/kernel/signaldata/FsOpenReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/FsReadWriteReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/FsRef.hpp:
mvdir
storage/ndb/include/kernel/signaldata/FsRemoveReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/GCPSave.hpp:
mvdir
storage/ndb/include/kernel/signaldata/GetTabInfo.hpp:
mvdir
storage/ndb/include/kernel/signaldata/GetTableId.hpp:
mvdir
storage/ndb/include/kernel/signaldata/GrepImpl.hpp:
mvdir
storage/ndb/include/kernel/signaldata/HotSpareRep.hpp:
mvdir
storage/ndb/include/kernel/signaldata/IndxAttrInfo.hpp:
mvdir
storage/ndb/include/kernel/signaldata/IndxKeyInfo.hpp:
mvdir
storage/ndb/include/kernel/signaldata/InvalidateNodeLCPConf.hpp:
mvdir
storage/ndb/include/kernel/signaldata/InvalidateNodeLCPReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/KeyInfo.hpp:
mvdir
storage/ndb/include/kernel/signaldata/LCP.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ListTables.hpp:
mvdir
storage/ndb/include/kernel/signaldata/LqhFrag.hpp:
mvdir
storage/ndb/include/kernel/signaldata/LqhKey.hpp:
mvdir
storage/ndb/include/kernel/signaldata/LqhSizeAltReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/LqhTransConf.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ManagementServer.hpp:
mvdir
storage/ndb/include/kernel/signaldata/MasterGCP.hpp:
mvdir
storage/ndb/include/kernel/signaldata/MasterLCP.hpp:
mvdir
storage/ndb/include/kernel/signaldata/NFCompleteRep.hpp:
mvdir
storage/ndb/include/kernel/signaldata/NdbSttor.hpp:
mvdir
storage/ndb/include/kernel/signaldata/NdbfsContinueB.hpp:
mvdir
storage/ndb/include/kernel/signaldata/NextScan.hpp:
mvdir
storage/ndb/include/kernel/signaldata/NodeFailRep.hpp:
mvdir
storage/ndb/include/kernel/signaldata/NodeStateSignalData.hpp:
mvdir
storage/ndb/include/kernel/signaldata/PackedSignal.hpp:
mvdir
storage/ndb/include/kernel/signaldata/PrepDropTab.hpp:
mvdir
storage/ndb/include/kernel/signaldata/PrepFailReqRef.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ReadConfig.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ReadNodesConf.hpp:
mvdir
storage/ndb/include/kernel/signaldata/RelTabMem.hpp:
mvdir
storage/ndb/include/kernel/signaldata/RepImpl.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ResumeReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ScanFrag.hpp:
mvdir
storage/ndb/include/kernel/signaldata/ScanTab.hpp:
mvdir
storage/ndb/include/kernel/signaldata/SetLogLevelOrd.hpp:
mvdir
storage/ndb/include/kernel/signaldata/SetVarReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/SignalData.hpp:
mvdir
storage/ndb/include/kernel/signaldata/SignalDataPrint.hpp:
mvdir
storage/ndb/include/kernel/signaldata/SignalDroppedRep.hpp:
mvdir
storage/ndb/include/kernel/signaldata/SrFragidConf.hpp:
mvdir
storage/ndb/include/kernel/signaldata/StartFragReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/StartInfo.hpp:
mvdir
storage/ndb/include/kernel/signaldata/StartMe.hpp:
mvdir
storage/ndb/include/kernel/signaldata/StartOrd.hpp:
mvdir
storage/ndb/include/kernel/signaldata/StartPerm.hpp:
mvdir
storage/ndb/include/kernel/signaldata/StartRec.hpp:
mvdir
storage/ndb/include/kernel/signaldata/StartTo.hpp:
mvdir
storage/ndb/include/kernel/signaldata/StopMe.hpp:
mvdir
storage/ndb/include/kernel/signaldata/StopPerm.hpp:
mvdir
storage/ndb/include/kernel/signaldata/StopReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/SumaImpl.hpp:
mvdir
storage/ndb/include/kernel/signaldata/SystemError.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TamperOrd.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TcCommit.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TcContinueB.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TcHbRep.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TcIndx.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TcKeyConf.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TcKeyFailConf.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TcKeyRef.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TcKeyReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TcRollbackRep.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TcSizeAltReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TestOrd.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TransIdAI.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TrigAttrInfo.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TupCommit.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TupFrag.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TupKey.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TupSizeAltReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TuxBound.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TuxContinueB.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TuxMaint.hpp:
mvdir
storage/ndb/include/kernel/signaldata/TuxSizeAltReq.hpp:
mvdir
storage/ndb/include/kernel/signaldata/UpdateTo.hpp:
mvdir
storage/ndb/include/kernel/signaldata/UpgradeStartup.hpp:
mvdir
storage/ndb/include/kernel/signaldata/UtilDelete.hpp:
mvdir
storage/ndb/include/kernel/signaldata/UtilExecute.hpp:
mvdir
storage/ndb/include/kernel/signaldata/UtilLock.hpp:
mvdir
storage/ndb/include/kernel/signaldata/UtilPrepare.hpp:
mvdir
storage/ndb/include/kernel/signaldata/UtilRelease.hpp:
mvdir
storage/ndb/include/kernel/signaldata/UtilSequence.hpp:
mvdir
storage/ndb/include/kernel/signaldata/WaitGCP.hpp:
mvdir
storage/ndb/include/logger/ConsoleLogHandler.hpp:
mvdir
storage/ndb/include/logger/FileLogHandler.hpp:
mvdir
storage/ndb/include/logger/LogHandler.hpp:
mvdir
storage/ndb/include/logger/Logger.hpp:
mvdir
storage/ndb/include/logger/SysLogHandler.hpp:
mvdir
storage/ndb/include/mgmapi/mgmapi.h:
mvdir
storage/ndb/include/mgmapi/mgmapi_config_parameters.h:
mvdir
storage/ndb/include/mgmapi/mgmapi_config_parameters_debug.h:
mvdir
storage/ndb/include/mgmapi/mgmapi_debug.h:
mvdir
storage/ndb/include/mgmapi/ndb_logevent.h:
mvdir
storage/ndb/include/mgmcommon/ConfigRetriever.hpp:
mvdir
storage/ndb/include/mgmcommon/IPCConfig.hpp:
mvdir
storage/ndb/include/mgmcommon/MgmtErrorReporter.hpp:
mvdir
storage/ndb/include/ndbapi/Ndb.hpp:
mvdir
storage/ndb/include/ndbapi/NdbApi.hpp:
mvdir
storage/ndb/include/ndbapi/NdbBlob.hpp:
mvdir
storage/ndb/include/ndbapi/NdbDictionary.hpp:
mvdir
storage/ndb/include/ndbapi/NdbError.hpp:
mvdir
storage/ndb/include/ndbapi/NdbEventOperation.hpp:
mvdir
storage/ndb/include/ndbapi/NdbIndexOperation.hpp:
mvdir
storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp:
mvdir
storage/ndb/include/ndbapi/NdbOperation.hpp:
mvdir
storage/ndb/include/ndbapi/NdbPool.hpp:
mvdir
storage/ndb/include/ndbapi/NdbRecAttr.hpp:
mvdir
storage/ndb/include/ndbapi/NdbReceiver.hpp:
mvdir
storage/ndb/include/ndbapi/NdbScanFilter.hpp:
mvdir
storage/ndb/include/ndbapi/NdbScanOperation.hpp:
mvdir
storage/ndb/include/ndbapi/NdbTransaction.hpp:
mvdir
storage/ndb/include/ndbapi/ndb_cluster_connection.hpp:
mvdir
storage/ndb/include/ndbapi/ndb_opt_defaults.h:
mvdir
storage/ndb/include/ndbapi/ndbapi_limits.h:
mvdir
storage/ndb/include/ndbapi/ndberror.h:
mvdir
storage/ndb/include/newtonapi/dba.h:
mvdir
storage/ndb/include/newtonapi/defs/pcn_types.h:
mvdir
storage/ndb/include/portlib/NdbCondition.h:
mvdir
storage/ndb/include/portlib/NdbConfig.h:
mvdir
storage/ndb/include/portlib/NdbDaemon.h:
mvdir
storage/ndb/include/portlib/NdbEnv.h:
mvdir
storage/ndb/include/portlib/NdbHost.h:
mvdir
storage/ndb/include/portlib/NdbMain.h:
mvdir
storage/ndb/include/portlib/NdbMem.h:
mvdir
storage/ndb/include/portlib/NdbMutex.h:
mvdir
storage/ndb/include/portlib/NdbSleep.h:
mvdir
storage/ndb/include/portlib/NdbTCP.h:
mvdir
storage/ndb/include/portlib/NdbThread.h:
mvdir
storage/ndb/include/portlib/NdbTick.h:
mvdir
storage/ndb/include/portlib/PortDefs.h:
mvdir
storage/ndb/include/portlib/prefetch.h:
mvdir
storage/ndb/include/transporter/TransporterCallback.hpp:
mvdir
storage/ndb/include/transporter/TransporterDefinitions.hpp:
mvdir
storage/ndb/include/transporter/TransporterRegistry.hpp:
mvdir
storage/ndb/include/util/Base64.hpp:
mvdir
storage/ndb/include/util/BaseString.hpp:
mvdir
storage/ndb/include/util/Bitmask.hpp:
mvdir
storage/ndb/include/util/ConfigValues.hpp:
mvdir
storage/ndb/include/util/File.hpp:
mvdir
storage/ndb/include/util/InputStream.hpp:
mvdir
storage/ndb/include/util/NdbAutoPtr.hpp:
mvdir
storage/ndb/include/util/NdbOut.hpp:
mvdir
storage/ndb/include/util/NdbSqlUtil.hpp:
mvdir
storage/ndb/include/util/OutputStream.hpp:
mvdir
storage/ndb/include/util/Parser.hpp:
mvdir
storage/ndb/include/util/Properties.hpp:
mvdir
storage/ndb/include/util/SimpleProperties.hpp:
mvdir
storage/ndb/include/util/SocketAuthenticator.hpp:
mvdir
storage/ndb/include/util/SocketClient.hpp:
mvdir
storage/ndb/include/util/SocketServer.hpp:
mvdir
storage/ndb/include/util/UtilBuffer.hpp:
mvdir
storage/ndb/include/util/Vector.hpp:
mvdir
storage/ndb/include/util/basestring_vsnprintf.h:
mvdir
storage/ndb/include/util/md5_hash.hpp:
mvdir
storage/ndb/include/util/ndb_opts.h:
mvdir
storage/ndb/include/util/random.h:
mvdir
storage/ndb/include/util/socket_io.h:
mvdir
storage/ndb/include/util/uucode.h:
mvdir
storage/ndb/include/util/version.h:
mvdir
storage/ndb/lib/.empty:
mvdir
storage/ndb/ndbapi-examples/Makefile:
mvdir
storage/ndb/ndbapi-examples/mgmapi_logevent_example/Makefile:
mvdir
storage/ndb/ndbapi-examples/mgmapi_logevent_example/mgmapi_logevent.cpp:
mvdir
storage/ndb/ndbapi-examples/ndbapi_async_example/Makefile:
mvdir
storage/ndb/ndbapi-examples/ndbapi_async_example/ndbapi_async.cpp:
mvdir
storage/ndb/ndbapi-examples/ndbapi_async_example/readme.txt:
mvdir
storage/ndb/ndbapi-examples/ndbapi_async_example1/Makefile:
mvdir
storage/ndb/ndbapi-examples/ndbapi_async_example1/ndbapi_async1.cpp:
mvdir
storage/ndb/ndbapi-examples/ndbapi_event_example/Makefile:
mvdir
storage/ndb/ndbapi-examples/ndbapi_event_example/ndbapi_event.cpp:
mvdir
storage/ndb/ndbapi-examples/ndbapi_retries_example/Makefile:
mvdir
storage/ndb/ndbapi-examples/ndbapi_retries_example/ndbapi_retries.cpp:
mvdir
storage/ndb/ndbapi-examples/ndbapi_scan_example/Makefile:
mvdir
storage/ndb/ndbapi-examples/ndbapi_scan_example/ndbapi_scan.cpp:
mvdir
storage/ndb/ndbapi-examples/ndbapi_scan_example/readme.txt:
mvdir
storage/ndb/ndbapi-examples/ndbapi_simple_example/Makefile:
mvdir
storage/ndb/ndbapi-examples/ndbapi_simple_example/ndbapi_simple.cpp:
mvdir
storage/ndb/ndbapi-examples/ndbapi_simple_index_example/Makefile:
mvdir
storage/ndb/ndbapi-examples/ndbapi_simple_index_example/ndbapi_simple_index.cpp:
mvdir
storage/ndb/src/Makefile.am:
mvdir
storage/ndb/src/common/Makefile.am:
mvdir
storage/ndb/src/common/debugger/BlockNames.cpp:
mvdir
storage/ndb/src/common/debugger/DebuggerNames.cpp:
mvdir
storage/ndb/src/common/debugger/EventLogger.cpp:
mvdir
storage/ndb/src/common/debugger/GrepError.cpp:
mvdir
storage/ndb/src/common/debugger/Makefile.am:
mvdir
storage/ndb/src/common/debugger/SignalLoggerManager.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/AccLock.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/AlterIndx.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/AlterTab.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/AlterTable.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/AlterTrig.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/BackupImpl.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/BackupSignalData.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/CloseComReqConf.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/CntrStart.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/ContinueB.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/CopyGCI.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/CreateEvnt.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/CreateFragmentation.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/CreateIndx.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/CreateTrig.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/DihContinueB.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/DihSwitchReplicaReq.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/DisconnectRep.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/DropIndx.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/DropTab.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/DropTrig.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/FailRep.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/FireTrigOrd.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/FsAppendReq.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/FsCloseReq.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/FsConf.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/FsOpenReq.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/FsReadWriteReq.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/FsRef.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/GCPSave.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/IndxAttrInfo.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/IndxKeyInfo.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/LCP.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/LqhFrag.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/LqhKey.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/LqhTrans.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/Makefile.am:
mvdir
storage/ndb/src/common/debugger/signaldata/MasterLCP.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/NFCompleteRep.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/NdbSttor.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/NdbfsContinueB.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/PackedSignal.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/PrepDropTab.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/PrepFailReqRef.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/ReadNodesConf.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/ScanFrag.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/ScanTab.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/SignalDroppedRep.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/SignalNames.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/StartRec.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/SumaImpl.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/SystemError.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/TcIndx.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/TcKeyConf.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/TcKeyRef.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/TcKeyReq.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/TcRollbackRep.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/TrigAttrInfo.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/TupCommit.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/TupKey.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/TuxMaint.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/UtilDelete.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/UtilExecute.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/UtilLock.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/UtilPrepare.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/UtilSequence.cpp:
mvdir
storage/ndb/src/common/debugger/signaldata/print.awk:
mvdir
storage/ndb/src/common/logger/ConsoleLogHandler.cpp:
mvdir
storage/ndb/src/common/logger/FileLogHandler.cpp:
mvdir
storage/ndb/src/common/logger/LogHandler.cpp:
mvdir
storage/ndb/src/common/logger/LogHandlerList.cpp:
mvdir
storage/ndb/src/common/logger/LogHandlerList.hpp:
mvdir
storage/ndb/src/common/logger/Logger.cpp:
mvdir
storage/ndb/src/common/logger/Makefile.am:
mvdir
storage/ndb/src/common/logger/SysLogHandler.cpp:
mvdir
storage/ndb/src/common/logger/listtest/LogHandlerListUnitTest.cpp:
mvdir
storage/ndb/src/common/logger/listtest/LogHandlerListUnitTest.hpp:
mvdir
storage/ndb/src/common/logger/listtest/Makefile:
mvdir
storage/ndb/src/common/logger/loggertest/LoggerUnitTest.cpp:
mvdir
storage/ndb/src/common/logger/loggertest/LoggerUnitTest.hpp:
mvdir
storage/ndb/src/common/logger/loggertest/Makefile:
mvdir
storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp:
mvdir
storage/ndb/src/common/mgmcommon/IPCConfig.cpp:
mvdir
storage/ndb/src/common/mgmcommon/Makefile.am:
mvdir
storage/ndb/src/common/mgmcommon/printConfig/Makefile:
mvdir
storage/ndb/src/common/mgmcommon/printConfig/printConfig.cpp:
mvdir
storage/ndb/src/common/portlib/Makefile.am:
mvdir
storage/ndb/src/common/portlib/NdbCondition.c:
mvdir
storage/ndb/src/common/portlib/NdbConfig.c:
mvdir
storage/ndb/src/common/portlib/NdbDaemon.c:
mvdir
storage/ndb/src/common/portlib/NdbEnv.c:
mvdir
storage/ndb/src/common/portlib/NdbHost.c:
mvdir
storage/ndb/src/common/portlib/NdbMem.c:
mvdir
storage/ndb/src/common/portlib/NdbMutex.c:
mvdir
storage/ndb/src/common/portlib/NdbPortLibTest.cpp:
mvdir
storage/ndb/src/common/portlib/NdbSleep.c:
mvdir
storage/ndb/src/common/portlib/NdbTCP.cpp:
mvdir
storage/ndb/src/common/portlib/NdbThread.c:
mvdir
storage/ndb/src/common/portlib/NdbTick.c:
mvdir
storage/ndb/src/common/portlib/gcc.cpp:
mvdir
storage/ndb/src/common/portlib/memtest.c:
mvdir
storage/ndb/src/common/portlib/mmslist.cpp:
mvdir
storage/ndb/src/common/portlib/mmstest.cpp:
mvdir
storage/ndb/src/common/portlib/munmaptest.cpp:
mvdir
storage/ndb/src/common/portlib/old_dirs/memtest/Makefile:
mvdir
storage/ndb/src/common/portlib/old_dirs/memtest/munmaptest/Makefile:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/Makefile:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/NdbCondition.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/NdbConditionOSE.h:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/NdbEnv.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/NdbHost.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/NdbMem.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/NdbMem_SoftOse.cpp:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/NdbMutex.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/NdbOut.cpp:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/NdbSleep.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/NdbTCP.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/NdbThread.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/ose/NdbTick.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/test/Makefile:
mvdir
storage/ndb/src/common/portlib/old_dirs/win32/Makefile:
mvdir
storage/ndb/src/common/portlib/old_dirs/win32/NdbCondition.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/win32/NdbDaemon.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/win32/NdbEnv.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/win32/NdbHost.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/win32/NdbMem.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/win32/NdbMutex.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/win32/NdbSleep.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/win32/NdbTCP.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/win32/NdbThread.c:
mvdir
storage/ndb/src/common/portlib/old_dirs/win32/NdbTick.c:
mvdir
storage/ndb/src/common/portlib/win32/NdbCondition.c:
mvdir
storage/ndb/src/common/portlib/win32/NdbDaemon.c:
mvdir
storage/ndb/src/common/portlib/win32/NdbEnv.c:
mvdir
storage/ndb/src/common/portlib/win32/NdbHost.c:
mvdir
storage/ndb/src/common/portlib/win32/NdbMem.c:
mvdir
storage/ndb/src/common/portlib/win32/NdbMutex.c:
mvdir
storage/ndb/src/common/portlib/win32/NdbSleep.c:
mvdir
storage/ndb/src/common/portlib/win32/NdbTCP.c:
mvdir
storage/ndb/src/common/portlib/win32/NdbThread.c:
mvdir
storage/ndb/src/common/portlib/win32/NdbTick.c:
mvdir
storage/ndb/src/common/transporter/Makefile.am:
mvdir
storage/ndb/src/common/transporter/OSE_Receiver.cpp:
mvdir
storage/ndb/src/common/transporter/OSE_Receiver.hpp:
mvdir
storage/ndb/src/common/transporter/OSE_Signals.hpp:
mvdir
storage/ndb/src/common/transporter/OSE_Transporter.cpp:
mvdir
storage/ndb/src/common/transporter/OSE_Transporter.hpp:
mvdir
storage/ndb/src/common/transporter/Packer.cpp:
mvdir
storage/ndb/src/common/transporter/Packer.hpp:
mvdir
storage/ndb/src/common/transporter/SCI_Transporter.cpp:
mvdir
storage/ndb/src/common/transporter/SCI_Transporter.hpp:
mvdir
storage/ndb/src/common/transporter/SHM_Buffer.hpp:
mvdir
storage/ndb/src/common/transporter/SHM_Transporter.cpp:
mvdir
storage/ndb/src/common/transporter/SHM_Transporter.hpp:
mvdir
storage/ndb/src/common/transporter/SHM_Transporter.unix.cpp:
mvdir
storage/ndb/src/common/transporter/SHM_Transporter.win32.cpp:
mvdir
storage/ndb/src/common/transporter/SendBuffer.cpp:
mvdir
storage/ndb/src/common/transporter/SendBuffer.hpp:
mvdir
storage/ndb/src/common/transporter/TCP_Transporter.cpp:
mvdir
storage/ndb/src/common/transporter/TCP_Transporter.hpp:
mvdir
storage/ndb/src/common/transporter/Transporter.cpp:
mvdir
storage/ndb/src/common/transporter/Transporter.hpp:
mvdir
storage/ndb/src/common/transporter/TransporterInternalDefinitions.hpp:
mvdir
storage/ndb/src/common/transporter/TransporterRegistry.cpp:
mvdir
storage/ndb/src/common/transporter/basictest/Makefile:
mvdir
storage/ndb/src/common/transporter/basictest/basicTransporterTest.cpp:
mvdir
storage/ndb/src/common/transporter/buddy.cpp:
mvdir
storage/ndb/src/common/transporter/buddy.hpp:
mvdir
storage/ndb/src/common/transporter/failoverSCI/Makefile:
mvdir
storage/ndb/src/common/transporter/failoverSCI/failoverSCI.cpp:
mvdir
storage/ndb/src/common/transporter/perftest/Makefile:
mvdir
storage/ndb/src/common/transporter/perftest/perfTransporterTest.cpp:
mvdir
storage/ndb/src/common/transporter/priotest/Makefile:
mvdir
storage/ndb/src/common/transporter/priotest/prioOSE/Makefile:
mvdir
storage/ndb/src/common/transporter/priotest/prioSCI/Makefile:
mvdir
storage/ndb/src/common/transporter/priotest/prioSCI/prioSCI.cpp:
mvdir
storage/ndb/src/common/transporter/priotest/prioSHM/Makefile:
mvdir
storage/ndb/src/common/transporter/priotest/prioSHM/prioSHM.cpp:
mvdir
storage/ndb/src/common/transporter/priotest/prioTCP/Makefile:
mvdir
storage/ndb/src/common/transporter/priotest/prioTCP/prioTCP.cpp:
mvdir
storage/ndb/src/common/transporter/priotest/prioTransporterTest.cpp:
mvdir
storage/ndb/src/common/transporter/priotest/prioTransporterTest.hpp:
mvdir
storage/ndb/src/common/util/Base64.cpp:
mvdir
storage/ndb/src/common/util/BaseString.cpp:
mvdir
storage/ndb/src/common/util/Bitmask.cpp:
mvdir
storage/ndb/src/common/util/ConfigValues.cpp:
mvdir
storage/ndb/src/common/util/File.cpp:
mvdir
storage/ndb/src/common/util/InputStream.cpp:
mvdir
storage/ndb/src/common/util/Makefile.am:
mvdir
storage/ndb/src/common/util/NdbErrHnd.cpp:
mvdir
storage/ndb/src/common/util/NdbOut.cpp:
mvdir
storage/ndb/src/common/util/NdbSqlUtil.cpp:
mvdir
storage/ndb/src/common/util/OutputStream.cpp:
mvdir
storage/ndb/src/common/util/Parser.cpp:
mvdir
storage/ndb/src/common/util/Properties.cpp:
mvdir
storage/ndb/src/common/util/SimpleProperties.cpp:
mvdir
storage/ndb/src/common/util/SocketAuthenticator.cpp:
mvdir
storage/ndb/src/common/util/SocketClient.cpp:
mvdir
storage/ndb/src/common/util/SocketServer.cpp:
mvdir
storage/ndb/src/common/util/basestring_vsnprintf.c:
mvdir
storage/ndb/src/common/util/filetest/FileUnitTest.cpp:
mvdir
storage/ndb/src/common/util/filetest/FileUnitTest.hpp:
mvdir
storage/ndb/src/common/util/filetest/Makefile:
mvdir
storage/ndb/src/common/util/getarg.cat3:
mvdir
storage/ndb/src/common/util/md5_hash.cpp:
mvdir
storage/ndb/src/common/util/ndb_init.c:
mvdir
storage/ndb/src/common/util/new.cpp:
mvdir
storage/ndb/src/common/util/random.c:
mvdir
storage/ndb/src/common/util/socket_io.cpp:
mvdir
storage/ndb/src/common/util/strdup.c:
mvdir
storage/ndb/src/common/util/testConfigValues/Makefile:
mvdir
storage/ndb/src/common/util/testConfigValues/testConfigValues.cpp:
mvdir
storage/ndb/src/common/util/uucode.c:
mvdir
storage/ndb/src/common/util/version.c:
mvdir
storage/ndb/src/common/util/testProperties/Makefile:
mvdir
storage/ndb/src/common/util/testProperties/testProperties.cpp:
mvdir
storage/ndb/src/common/util/testSimpleProperties/Makefile:
mvdir
storage/ndb/src/common/util/testSimpleProperties/sp_test.cpp:
mvdir
storage/ndb/src/cw/Makefile.am:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.cpp:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.dsp:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.dsw:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.h:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.rc:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.sln:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.suo:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.vcproj:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/Closed.ICO:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/NdbControls.cpp:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/Open.ICO:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/StdAfx.cpp:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/StdAfx.h:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/TreeView.cpp:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/TreeView.h:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/bmp00001.bmp:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/resource.h:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/small.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/C++/toolbar.bmp:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/App.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/CPC_Form.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/Computer.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/ComputerAddDialog.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/ComputerRemoveDialog.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/DATABASE.ICO:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/Database.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.csproj.user:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.csproj:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.ncb:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.sln:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/PanelWizard.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/Process.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/ProcessDefineDialog.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/fileaccess/FileMgmt.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/simpleparser/SimpleCPCParser.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/socketcomm/SocketComm.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/socketcomm/myTcpClient.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/startDatabaseDlg.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/csharp/telnetclient/telnetClient.cs:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Computer.cls:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Database.cls:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Icon 110.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Icon 231.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Icon 237.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Icon 241.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Icon 242.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Icon 270.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Icon 271.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Icon 273.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Icon 31.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Icon 337.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Icon 338.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Icon 339.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/MSSCCPRJ.SCC:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Module1.bas:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/NdbCPC.vbp:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/NdbCPC.vbw:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/Process.cls:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/closed folder.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/computer.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/frmAbout.frm:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/frmLogin.frm:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/frmMain.frm:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/frmNewComputer.frm:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/frmNewComputer.frx:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/frmNewDatabase.frx:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/frmNewDatabase1.frm:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/frmNewDatabase2.frm:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/frmNewDatabase2.log:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/frmNewDatabase3.frm:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/frmOptions.frm:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/frmSplash.frx:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/networking.ico:
mvdir
storage/ndb/src/cw/cpcc-win32/vb6/open folder.ico:
mvdir
storage/ndb/src/cw/cpcd/APIService.cpp:
mvdir
storage/ndb/src/cw/cpcd/APIService.hpp:
mvdir
storage/ndb/src/cw/cpcd/CPCD.cpp:
mvdir
storage/ndb/src/cw/cpcd/CPCD.hpp:
mvdir
storage/ndb/src/cw/cpcd/Makefile.am:
mvdir
storage/ndb/src/cw/cpcd/Monitor.cpp:
mvdir
storage/ndb/src/cw/cpcd/Process.cpp:
mvdir
storage/ndb/src/cw/cpcd/common.cpp:
mvdir
storage/ndb/src/cw/cpcd/common.hpp:
mvdir
storage/ndb/src/cw/cpcd/main.cpp:
mvdir
storage/ndb/src/cw/test/socketclient/Makefile:
mvdir
storage/ndb/src/cw/test/socketclient/socketClientTest.cpp:
mvdir
storage/ndb/src/cw/util/ClientInterface.cpp:
mvdir
storage/ndb/src/cw/util/ClientInterface.hpp:
mvdir
storage/ndb/src/cw/util/Makefile:
mvdir
storage/ndb/src/cw/util/SocketRegistry.cpp:
mvdir
storage/ndb/src/cw/util/SocketRegistry.hpp:
mvdir
storage/ndb/src/cw/util/SocketService.cpp:
mvdir
storage/ndb/src/cw/util/SocketService.hpp:
mvdir
storage/ndb/src/external/WIN32.x86/sci/lib/SISCI_LIBRARY_WIN32.TXT:
mvdir
storage/ndb/src/external/WIN32.x86/sci/lib/scilib.lib:
mvdir
storage/ndb/src/external/WIN32.x86/sci/lib/scilib_md.lib:
mvdir
storage/ndb/src/external/WIN32.x86/sci/lib/scilib_mt.lib:
mvdir
storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api.lib:
mvdir
storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api_md.lib:
mvdir
storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api_mt.lib:
mvdir
storage/ndb/src/kernel/Makefile.am:
mvdir
storage/ndb/src/kernel/SimBlockList.cpp:
mvdir
storage/ndb/src/kernel/blocks/ERROR_codes.txt:
mvdir
storage/ndb/src/kernel/blocks/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/NodeRestart.new.txt:
mvdir
storage/ndb/src/kernel/blocks/NodeRestart.txt:
mvdir
storage/ndb/src/kernel/blocks/Start.txt:
mvdir
storage/ndb/src/kernel/blocks/SystemRestart.new.txt:
mvdir
storage/ndb/src/kernel/blocks/SystemRestart.txt:
mvdir
storage/ndb/src/kernel/blocks/backup/Backup.cpp:
mvdir
storage/ndb/src/kernel/blocks/backup/Backup.hpp:
mvdir
storage/ndb/src/kernel/blocks/backup/Backup.txt:
mvdir
storage/ndb/src/kernel/blocks/backup/BackupFormat.hpp:
mvdir
storage/ndb/src/kernel/blocks/backup/BackupInit.cpp:
mvdir
storage/ndb/src/kernel/blocks/backup/FsBuffer.hpp:
mvdir
storage/ndb/src/kernel/blocks/backup/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/backup/read.cpp:
mvdir
storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp:
mvdir
storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp:
mvdir
storage/ndb/src/kernel/blocks/cmvmi/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp:
mvdir
storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbacc/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/mutexes.hpp:
mvdir
storage/ndb/src/kernel/blocks/new-block.tar.gz:
mvdir
storage/ndb/src/kernel/main.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbdict/CreateIndex.txt:
mvdir
storage/ndb/src/kernel/blocks/dbdict/CreateTable.new.txt:
mvdir
storage/ndb/src/kernel/blocks/dbdict/CreateTable.txt:
mvdir
storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp:
mvdir
storage/ndb/src/kernel/blocks/dbdict/Dbdict.txt:
mvdir
storage/ndb/src/kernel/blocks/dbdict/DropTable.txt:
mvdir
storage/ndb/src/kernel/blocks/dbdict/Event.txt:
mvdir
storage/ndb/src/kernel/blocks/dbdict/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/dbdict/Master_AddTable.sfl:
mvdir
storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp:
mvdir
storage/ndb/src/kernel/blocks/dbdict/Slave_AddTable.sfl:
mvdir
storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp:
mvdir
storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbdih/LCP.txt:
mvdir
storage/ndb/src/kernel/blocks/dbdih/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/dbdih/Sysfile.hpp:
mvdir
storage/ndb/src/kernel/blocks/dbdih/printSysfile/Makefile:
mvdir
storage/ndb/src/kernel/blocks/dbdih/printSysfile/printSysfile.cpp:
mvdir
storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp:
mvdir
storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp:
mvdir
storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp:
mvdir
storage/ndb/src/kernel/blocks/dblqh/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/dblqh/redoLogReader/Makefile:
mvdir
storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp:
mvdir
storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp:
mvdir
storage/ndb/src/kernel/blocks/dblqh/redoLogReader/redoLogFileReader.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp:
mvdir
storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtc/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/dbtup/AttributeOffset.hpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupFixAlloc.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupLCP.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupSystemRestart.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/DbtupUndoLog.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtup/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/dbtup/Notes.txt:
mvdir
storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp:
mvdir
storage/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbtux/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/dbtux/Times.txt:
mvdir
storage/ndb/src/kernel/blocks/dbtux/tuxstatus.html:
mvdir
storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp:
mvdir
storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp:
mvdir
storage/ndb/src/kernel/blocks/dbutil/DbUtil.txt:
mvdir
storage/ndb/src/kernel/blocks/dbutil/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/grep/Grep.cpp:
mvdir
storage/ndb/src/kernel/blocks/grep/Grep.hpp:
mvdir
storage/ndb/src/kernel/blocks/grep/GrepInit.cpp:
mvdir
storage/ndb/src/kernel/blocks/grep/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/grep/systab_test/Makefile:
mvdir
storage/ndb/src/kernel/blocks/grep/systab_test/grep_systab_test.cpp:
mvdir
storage/ndb/src/kernel/blocks/ndbcntr/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp:
mvdir
storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp:
mvdir
storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp:
mvdir
storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrSysTable.cpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.hpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/CircularIndex.cpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/CircularIndex.hpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/Filename.cpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/Filename.hpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/MemoryChannel.cpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/MemoryChannel.hpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/AsyncFileTest/AsyncFileTest.cpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/AsyncFileTest/Makefile:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/MemoryChannelOSE.hpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/MemoryChannelTest/Makefile:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/MemoryChannelTest/MemoryChannelTest.cpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/OpenFiles.hpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/Pool.hpp:
mvdir
storage/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp:
mvdir
storage/ndb/src/kernel/blocks/qmgr/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp:
mvdir
storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp:
mvdir
storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp:
mvdir
storage/ndb/src/kernel/blocks/qmgr/timer.hpp:
mvdir
storage/ndb/src/kernel/blocks/suma/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/suma/Suma.cpp:
mvdir
storage/ndb/src/kernel/blocks/suma/Suma.hpp:
mvdir
storage/ndb/src/kernel/blocks/suma/Suma.txt:
mvdir
storage/ndb/src/kernel/blocks/suma/SumaInit.cpp:
mvdir
storage/ndb/src/kernel/blocks/trix/Makefile.am:
mvdir
storage/ndb/src/kernel/blocks/trix/Trix.cpp:
mvdir
storage/ndb/src/kernel/blocks/trix/Trix.hpp:
mvdir
storage/ndb/src/kernel/error/Error.hpp:
mvdir
storage/ndb/src/kernel/error/ErrorHandlingMacros.hpp:
mvdir
storage/ndb/src/kernel/error/ErrorMessages.cpp:
mvdir
storage/ndb/src/kernel/error/ErrorMessages.hpp:
mvdir
storage/ndb/src/kernel/error/ErrorReporter.cpp:
mvdir
storage/ndb/src/kernel/error/ErrorReporter.hpp:
mvdir
storage/ndb/src/kernel/error/Makefile.am:
mvdir
storage/ndb/src/kernel/error/TimeModule.cpp:
mvdir
storage/ndb/src/kernel/error/TimeModule.hpp:
mvdir
storage/ndb/src/kernel/vm/Array.hpp:
mvdir
storage/ndb/src/kernel/vm/ArrayFifoList.hpp:
mvdir
storage/ndb/src/kernel/vm/ArrayList.hpp:
mvdir
storage/ndb/src/kernel/vm/ArrayPool.hpp:
mvdir
storage/ndb/src/kernel/vm/CArray.hpp:
mvdir
storage/ndb/src/kernel/vm/Callback.hpp:
mvdir
storage/ndb/src/kernel/vm/ClusterConfiguration.cpp:
mvdir
storage/ndb/src/kernel/vm/ClusterConfiguration.hpp:
mvdir
storage/ndb/src/kernel/vm/Configuration.cpp:
mvdir
storage/ndb/src/kernel/vm/Configuration.hpp:
mvdir
storage/ndb/src/kernel/vm/DLFifoList.hpp:
mvdir
storage/ndb/src/kernel/vm/DLHashTable.hpp:
mvdir
storage/ndb/src/kernel/vm/DLHashTable2.hpp:
mvdir
storage/ndb/src/kernel/vm/DLList.hpp:
mvdir
storage/ndb/src/kernel/vm/DataBuffer.hpp:
mvdir
storage/ndb/src/kernel/vm/Emulator.cpp:
mvdir
storage/ndb/src/kernel/vm/Emulator.hpp:
mvdir
storage/ndb/src/kernel/vm/FastScheduler.cpp:
mvdir
storage/ndb/src/kernel/vm/FastScheduler.hpp:
mvdir
storage/ndb/src/kernel/vm/GlobalData.hpp:
mvdir
storage/ndb/src/kernel/vm/KeyTable.hpp:
mvdir
storage/ndb/src/kernel/vm/KeyTable2.hpp:
mvdir
storage/ndb/src/kernel/vm/LongSignal.hpp:
mvdir
storage/ndb/src/kernel/vm/Makefile.am:
mvdir
storage/ndb/src/kernel/vm/MetaData.cpp:
mvdir
storage/ndb/src/kernel/vm/MetaData.hpp:
mvdir
storage/ndb/src/kernel/vm/Mutex.cpp:
mvdir
storage/ndb/src/kernel/vm/Mutex.hpp:
mvdir
storage/ndb/src/kernel/vm/Prio.hpp:
mvdir
storage/ndb/src/kernel/vm/RequestTracker.hpp:
mvdir
storage/ndb/src/kernel/vm/SLList.hpp:
mvdir
storage/ndb/src/kernel/vm/SafeCounter.cpp:
mvdir
storage/ndb/src/kernel/vm/SafeCounter.hpp:
mvdir
storage/ndb/src/kernel/vm/SectionReader.cpp:
mvdir
storage/ndb/src/kernel/vm/SectionReader.hpp:
mvdir
storage/ndb/src/kernel/vm/SignalCounter.hpp:
mvdir
storage/ndb/src/kernel/vm/SimBlockList.hpp:
mvdir
storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp:
mvdir
storage/ndb/src/kernel/vm/SimulatedBlock.cpp:
mvdir
storage/ndb/src/kernel/vm/SimulatedBlock.hpp:
mvdir
storage/ndb/src/kernel/vm/ThreadConfig.cpp:
mvdir
storage/ndb/src/kernel/vm/ThreadConfig.hpp:
mvdir
storage/ndb/src/kernel/vm/TimeQueue.cpp:
mvdir
storage/ndb/src/kernel/vm/TimeQueue.hpp:
mvdir
storage/ndb/src/kernel/vm/TransporterCallback.cpp:
mvdir
storage/ndb/src/kernel/vm/VMSignal.cpp:
mvdir
storage/ndb/src/kernel/vm/VMSignal.hpp:
mvdir
storage/ndb/src/kernel/vm/WaitQueue.hpp:
mvdir
storage/ndb/src/kernel/vm/WatchDog.cpp:
mvdir
storage/ndb/src/kernel/vm/WatchDog.hpp:
mvdir
storage/ndb/src/kernel/vm/al_test/Makefile:
mvdir
storage/ndb/src/kernel/vm/al_test/arrayListTest.cpp:
mvdir
storage/ndb/src/kernel/vm/al_test/arrayPoolTest.cpp:
mvdir
storage/ndb/src/kernel/vm/al_test/main.cpp:
mvdir
storage/ndb/src/kernel/vm/pc.hpp:
mvdir
storage/ndb/src/kernel/vm/testCopy/Makefile:
mvdir
storage/ndb/src/kernel/vm/testCopy/rr.cpp:
mvdir
storage/ndb/src/kernel/vm/testCopy/testCopy.cpp:
mvdir
storage/ndb/src/kernel/vm/testDataBuffer/Makefile:
mvdir
storage/ndb/src/kernel/vm/testDataBuffer/testDataBuffer.cpp:
mvdir
storage/ndb/src/kernel/vm/testLongSig/Makefile:
mvdir
storage/ndb/src/kernel/vm/testLongSig/testLongSig.cpp:
mvdir
storage/ndb/src/kernel/vm/testSimplePropertiesSection/Makefile:
mvdir
storage/ndb/src/kernel/vm/testSimplePropertiesSection/test.cpp:
mvdir
storage/ndb/src/mgmapi/LocalConfig.cpp:
mvdir
storage/ndb/src/mgmapi/LocalConfig.hpp:
mvdir
storage/ndb/src/mgmapi/Makefile.am:
mvdir
storage/ndb/src/mgmapi/mgmapi.cpp:
mvdir
storage/ndb/src/mgmapi/mgmapi_configuration.cpp:
mvdir
storage/ndb/src/mgmapi/mgmapi_configuration.hpp:
mvdir
storage/ndb/src/mgmapi/mgmapi_internal.h:
mvdir
storage/ndb/src/mgmapi/ndb_logevent.cpp:
mvdir
storage/ndb/src/mgmapi/ndb_logevent.hpp:
mvdir
storage/ndb/src/mgmapi/test/Makefile:
mvdir
storage/ndb/src/mgmapi/test/keso.c:
mvdir
storage/ndb/src/mgmapi/test/mgmSrvApi.cpp:
mvdir
storage/ndb/src/mgmclient/CommandInterpreter.cpp:
mvdir
storage/ndb/src/mgmclient/Makefile.am:
mvdir
storage/ndb/src/mgmclient/main.cpp:
mvdir
storage/ndb/src/mgmclient/ndb_mgmclient.hpp:
mvdir
storage/ndb/src/mgmclient/ndb_mgmclient.h:
mvdir
storage/ndb/src/mgmclient/test_cpcd/Makefile:
mvdir
storage/ndb/src/mgmclient/test_cpcd/test_cpcd.cpp:
mvdir
storage/ndb/src/mgmsrv/Config.cpp:
mvdir
storage/ndb/src/mgmsrv/Config.hpp:
mvdir
storage/ndb/src/mgmsrv/ConfigInfo.cpp:
mvdir
storage/ndb/src/mgmsrv/ConfigInfo.hpp:
mvdir
storage/ndb/src/mgmsrv/InitConfigFileParser.cpp:
mvdir
storage/ndb/src/mgmsrv/InitConfigFileParser.hpp:
mvdir
storage/ndb/src/mgmsrv/Makefile.am:
mvdir
storage/ndb/src/mgmsrv/MgmtSrvr.cpp:
mvdir
storage/ndb/src/mgmsrv/MgmtSrvr.hpp:
mvdir
storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp:
mvdir
storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp:
mvdir
storage/ndb/src/mgmsrv/Services.cpp:
mvdir
storage/ndb/src/mgmsrv/Services.hpp:
mvdir
storage/ndb/src/mgmsrv/SignalQueue.cpp:
mvdir
storage/ndb/src/mgmsrv/SignalQueue.hpp:
mvdir
storage/ndb/src/mgmsrv/convertStrToInt.cpp:
mvdir
storage/ndb/src/mgmsrv/convertStrToInt.hpp:
mvdir
storage/ndb/src/mgmsrv/main.cpp:
mvdir
storage/ndb/src/mgmsrv/mkconfig/Makefile:
mvdir
storage/ndb/src/mgmsrv/mkconfig/mkconfig.cpp:
mvdir
storage/ndb/src/ndbapi/API.hpp:
mvdir
storage/ndb/src/ndbapi/ClusterMgr.cpp:
mvdir
storage/ndb/src/ndbapi/ClusterMgr.hpp:
mvdir
storage/ndb/src/ndbapi/DictCache.cpp:
mvdir
storage/ndb/src/ndbapi/DictCache.hpp:
mvdir
storage/ndb/src/ndbapi/Makefile.am:
mvdir
storage/ndb/src/ndbapi/Ndb.cpp:
mvdir
storage/ndb/src/ndbapi/NdbApiSignal.cpp:
mvdir
storage/ndb/src/ndbapi/NdbApiSignal.hpp:
mvdir
storage/ndb/src/ndbapi/NdbBlob.cpp:
mvdir
storage/ndb/src/ndbapi/NdbBlobImpl.hpp:
mvdir
storage/ndb/src/ndbapi/NdbDictionary.cpp:
mvdir
storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp:
mvdir
storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp:
mvdir
storage/ndb/src/ndbapi/NdbErrorOut.cpp:
mvdir
storage/ndb/src/ndbapi/NdbEventOperation.cpp:
mvdir
storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp:
mvdir
storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp:
mvdir
storage/ndb/src/ndbapi/NdbImpl.hpp:
mvdir
storage/ndb/src/ndbapi/NdbIndexOperation.cpp:
mvdir
storage/ndb/src/ndbapi/NdbLinHash.hpp:
mvdir
storage/ndb/src/ndbapi/NdbOperation.cpp:
mvdir
storage/ndb/src/ndbapi/NdbOperationDefine.cpp:
mvdir
storage/ndb/src/ndbapi/NdbOperationExec.cpp:
mvdir
storage/ndb/src/ndbapi/NdbOperationInt.cpp:
mvdir
storage/ndb/src/ndbapi/NdbOperationScan.cpp:
mvdir
storage/ndb/src/ndbapi/NdbOperationSearch.cpp:
mvdir
storage/ndb/src/ndbapi/NdbPool.cpp:
mvdir
storage/ndb/src/ndbapi/NdbPoolImpl.cpp:
mvdir
storage/ndb/src/ndbapi/NdbPoolImpl.hpp:
mvdir
storage/ndb/src/ndbapi/NdbRecAttr.cpp:
mvdir
storage/ndb/src/ndbapi/NdbReceiver.cpp:
mvdir
storage/ndb/src/ndbapi/NdbScanFilter.cpp:
mvdir
storage/ndb/src/ndbapi/NdbScanOperation.cpp:
mvdir
storage/ndb/src/ndbapi/NdbTransaction.cpp:
mvdir
storage/ndb/src/ndbapi/NdbTransactionScan.cpp:
mvdir
storage/ndb/src/ndbapi/NdbUtil.cpp:
mvdir
storage/ndb/src/ndbapi/NdbUtil.hpp:
mvdir
storage/ndb/src/ndbapi/NdbWaiter.hpp:
mvdir
storage/ndb/src/ndbapi/Ndberr.cpp:
mvdir
storage/ndb/src/ndbapi/Ndbif.cpp:
mvdir
storage/ndb/src/ndbapi/Ndbinit.cpp:
mvdir
storage/ndb/src/ndbapi/Ndblist.cpp:
mvdir
storage/ndb/src/ndbapi/ObjectMap.hpp:
mvdir
storage/ndb/src/ndbapi/ScanOperation.txt:
mvdir
storage/ndb/src/ndbapi/TransporterFacade.cpp:
mvdir
storage/ndb/src/ndbapi/TransporterFacade.hpp:
mvdir
storage/ndb/src/ndbapi/ndb_cluster_connection.cpp:
mvdir
storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp:
mvdir
storage/ndb/src/ndbapi/ndberror.c:
mvdir
storage/ndb/src/ndbapi/signal-sender/Makefile:
mvdir
storage/ndb/src/ndbapi/signal-sender/SignalSender.cpp:
mvdir
storage/ndb/src/ndbapi/signal-sender/SignalSender.hpp:
mvdir
storage/ndb/src/old_files/client/Makefile:
mvdir
storage/ndb/src/old_files/client/odbc/Extra.mk:
mvdir
storage/ndb/src/old_files/client/odbc/Makefile:
mvdir
storage/ndb/src/old_files/client/odbc/NdbOdbc.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/NdbOdbc.def:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/CodeGen.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/CodeGen.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_base.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_base.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_column.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_column.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_comp_op.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_comp_op.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_create_index.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_create_index.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_create_row.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_create_row.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_create_table.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_create_table.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_data_type.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_data_type.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_ddl.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_ddl.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_ddl_column.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_ddl_column.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_ddl_constr.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_ddl_constr.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_ddl_row.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_ddl_row.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_delete.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_delete.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_delete_index.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_delete_index.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_delete_lookup.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_delete_lookup.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_delete_scan.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_delete_scan.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_dml.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_dml.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_dml_column.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_dml_column.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_dml_row.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_dml_row.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_drop_index.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_drop_index.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_drop_table.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_drop_table.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_column.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_column.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_const.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_const.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_conv.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_conv.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_func.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_func.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_op.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_op.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_param.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_param.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_row.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_expr_row.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_idx_column.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_idx_column.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_insert.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_insert.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_pred.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_pred.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_pred_op.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_pred_op.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_count.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_count.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_distinct.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_distinct.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_filter.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_filter.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_group.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_group.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_index.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_index.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_join.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_join.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_lookup.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_lookup.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_project.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_project.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_range.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_range.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_repeat.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_repeat.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_scan.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_scan.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_sort.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_sort.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_sys.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_query_sys.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_root.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_root.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_select.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_select.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_set_row.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_set_row.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_stmt.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_stmt.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_table.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_table.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_table_list.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_table_list.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_update.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_update.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_update_index.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_update_index.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_update_lookup.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_update_lookup.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_update_scan.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Code_update_scan.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/Makefile:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/SimpleGram.ypp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/SimpleParser.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/SimpleParser.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/codegen/SimpleScan.lpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/AttrArea.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/AttrArea.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/CodeTree.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/CodeTree.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/ConnArea.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/ConnArea.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/Ctx.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/Ctx.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/DataField.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/DataField.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/DataRow.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/DataRow.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/DataType.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/DataType.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/DescArea.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/DescArea.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/DiagArea.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/DiagArea.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/Makefile:
mvdir
storage/ndb/src/old_files/client/odbc/common/OdbcData.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/OdbcData.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/ResultArea.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/ResultArea.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/Sqlstate.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/Sqlstate.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/StmtArea.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/StmtArea.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/StmtInfo.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/StmtInfo.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/common.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/common/common.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/DictCatalog.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/DictCatalog.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/DictColumn.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/DictColumn.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/DictIndex.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/DictIndex.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/DictSchema.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/DictSchema.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/DictSys.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/DictSys.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/DictTable.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/DictTable.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/dictionary/Makefile:
mvdir
storage/ndb/src/old_files/client/odbc/docs/class.fig:
mvdir
storage/ndb/src/old_files/client/odbc/docs/descfield.pl:
mvdir
storage/ndb/src/old_files/client/odbc/docs/diag.txt:
mvdir
storage/ndb/src/old_files/client/odbc/docs/getinfo.pl:
mvdir
storage/ndb/src/old_files/client/odbc/docs/gettypeinfo.pl:
mvdir
storage/ndb/src/old_files/client/odbc/docs/handleattr.pl:
mvdir
storage/ndb/src/old_files/client/odbc/docs/main.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/docs/ndbodbc.html:
mvdir
storage/ndb/src/old_files/client/odbc/docs/select.fig:
mvdir
storage/ndb/src/old_files/client/odbc/docs/systables.pl:
mvdir
storage/ndb/src/old_files/client/odbc/docs/type.txt:
mvdir
storage/ndb/src/old_files/client/odbc/driver/Func.data:
mvdir
storage/ndb/src/old_files/client/odbc/driver/Func.pl:
mvdir
storage/ndb/src/old_files/client/odbc/driver/Makefile:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLAllocConnect.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLAllocEnv.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLAllocHandle.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLAllocHandleStd.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLAllocStmt.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLBindCol.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLBindParam.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLBindParameter.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLBrowseConnect.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLBulkOperations.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLCancel.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLCloseCursor.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLColAttribute.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLColAttributes.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLColumnPrivileges.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLColumns.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLConnect.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLCopyDesc.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLDataSources.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLDescribeCol.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLDescribeParam.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLDisconnect.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLDriverConnect.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLDrivers.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLEndTran.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLError.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLExecDirect.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLExecute.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLExtendedFetch.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLFetch.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLFetchScroll.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLForeignKeys.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLFreeConnect.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLFreeEnv.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLFreeHandle.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLFreeStmt.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetConnectAttr.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetConnectOption.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetCursorName.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetData.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetDescField.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetDescRec.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetDiagField.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetDiagRec.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetEnvAttr.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetFunctions.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetInfo.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetStmtAttr.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetStmtOption.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLGetTypeInfo.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLMoreResults.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLNativeSql.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLNumParams.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLNumResultCols.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLParamData.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLParamOptions.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLPrepare.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLPrimaryKeys.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLProcedureColumns.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLProcedures.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLPutData.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLRowCount.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLSetConnectAttr.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLSetConnectOption.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLSetCursorName.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLSetDescField.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLSetDescRec.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLSetEnvAttr.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLSetParam.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLSetPos.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLSetScrollOptions.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLSetStmtAttr.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLSetStmtOption.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLSpecialColumns.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLStatistics.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLTablePrivileges.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLTables.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/SQLTransact.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/driver.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/driver/driver.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_comp_op.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_create_index.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_create_table.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_delete_index.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_delete_lookup.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_delete_scan.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_drop_index.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_drop_table.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_expr_conv.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_expr_func.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_expr_op.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_insert.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_pred_op.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_query_index.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_query_lookup.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_query_range.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_query_scan.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_query_sys.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_update_index.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_update_lookup.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Exec_update_scan.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Executor.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Executor.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/executor/Makefile:
mvdir
storage/ndb/src/old_files/client/odbc/handles/AttrDbc.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/AttrEnv.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/AttrRoot.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/AttrStmt.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/DescSpec.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/FuncTab.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/HandleBase.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/HandleBase.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/HandleDbc.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/HandleDbc.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/HandleDesc.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/HandleDesc.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/HandleEnv.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/HandleEnv.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/HandleRoot.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/HandleRoot.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/HandleStmt.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/HandleStmt.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/InfoTab.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/Makefile:
mvdir
storage/ndb/src/old_files/client/odbc/handles/PoolNdb.cpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/PoolNdb.hpp:
mvdir
storage/ndb/src/old_files/client/odbc/handles/handles.hpp:
mvdir
storage/ndb/src/old_files/ndbbaseclient/Makefile:
mvdir
storage/ndb/src/old_files/ndbbaseclient/ndbbaseclient_dummy.cpp:
mvdir
storage/ndb/src/old_files/ndbclient/Makefile:
mvdir
storage/ndb/src/old_files/ndbclient/ndbclient_dummy.cpp:
mvdir
storage/ndb/src/old_files/newtonapi/Makefile:
mvdir
storage/ndb/src/old_files/newtonapi/dba_binding.cpp:
mvdir
storage/ndb/src/old_files/newtonapi/dba_bulkread.cpp:
mvdir
storage/ndb/src/old_files/newtonapi/dba_config.cpp:
mvdir
storage/ndb/src/old_files/newtonapi/dba_dac.cpp:
mvdir
storage/ndb/src/old_files/newtonapi/dba_error.cpp:
mvdir
storage/ndb/src/old_files/newtonapi/dba_init.cpp:
mvdir
storage/ndb/src/old_files/newtonapi/dba_internal.hpp:
mvdir
storage/ndb/src/old_files/newtonapi/dba_process.cpp:
mvdir
storage/ndb/src/old_files/newtonapi/dba_process.hpp:
mvdir
storage/ndb/src/old_files/newtonapi/dba_schema.cpp:
mvdir
storage/ndb/src/old_files/rep/ExtSender.cpp:
mvdir
storage/ndb/src/old_files/rep/ExtSender.hpp:
mvdir
storage/ndb/src/old_files/rep/Makefile:
mvdir
storage/ndb/src/old_files/rep/NodeConnectInfo.hpp:
mvdir
storage/ndb/src/old_files/rep/README:
mvdir
storage/ndb/src/old_files/rep/RepApiInterpreter.cpp:
mvdir
storage/ndb/src/old_files/rep/RepApiInterpreter.hpp:
mvdir
storage/ndb/src/old_files/rep/RepApiService.cpp:
mvdir
storage/ndb/src/old_files/rep/RepApiService.hpp:
mvdir
storage/ndb/src/old_files/rep/RepCommandInterpreter.cpp:
mvdir
storage/ndb/src/old_files/rep/RepCommandInterpreter.hpp:
mvdir
storage/ndb/src/old_files/rep/RepComponents.cpp:
mvdir
storage/ndb/src/old_files/rep/RepComponents.hpp:
mvdir
storage/ndb/src/old_files/rep/RepMain.cpp:
mvdir
storage/ndb/src/old_files/rep/Requestor.cpp:
mvdir
storage/ndb/src/old_files/rep/Requestor.hpp:
mvdir
storage/ndb/src/old_files/rep/RequestorSubscriptions.cpp:
mvdir
storage/ndb/src/old_files/rep/SignalQueue.cpp:
mvdir
storage/ndb/src/old_files/rep/SignalQueue.hpp:
mvdir
storage/ndb/src/old_files/rep/TODO:
mvdir
storage/ndb/src/old_files/rep/adapters/AppNDB.cpp:
mvdir
storage/ndb/src/old_files/rep/adapters/AppNDB.hpp:
mvdir
storage/ndb/src/old_files/rep/adapters/ExtAPI.cpp:
mvdir
storage/ndb/src/old_files/rep/adapters/ExtAPI.hpp:
mvdir
storage/ndb/src/old_files/rep/adapters/ExtNDB.cpp:
mvdir
storage/ndb/src/old_files/rep/adapters/ExtNDB.hpp:
mvdir
storage/ndb/src/old_files/rep/adapters/Makefile:
mvdir
storage/ndb/src/old_files/rep/adapters/TableInfoPs.hpp:
mvdir
storage/ndb/src/old_files/rep/dbug_hack.cpp:
mvdir
storage/ndb/src/old_files/rep/rep_version.hpp:
mvdir
storage/ndb/src/old_files/rep/repapi/Makefile:
mvdir
storage/ndb/src/old_files/rep/repapi/repapi.cpp:
mvdir
storage/ndb/src/old_files/rep/repapi/repapi.h:
mvdir
storage/ndb/src/old_files/rep/state/Channel.cpp:
mvdir
storage/ndb/src/old_files/rep/state/Channel.hpp:
mvdir
storage/ndb/src/old_files/rep/state/Interval.cpp:
mvdir
storage/ndb/src/old_files/rep/state/Interval.hpp:
mvdir
storage/ndb/src/old_files/rep/state/Makefile:
mvdir
storage/ndb/src/old_files/rep/state/RepState.cpp:
mvdir
storage/ndb/src/old_files/rep/state/RepState.hpp:
mvdir
storage/ndb/src/old_files/rep/state/RepStateEvent.cpp:
mvdir
storage/ndb/src/old_files/rep/state/RepStateRequests.cpp:
mvdir
storage/ndb/src/old_files/rep/state/testInterval/Makefile:
mvdir
storage/ndb/src/old_files/rep/state/testInterval/testInterval.cpp:
mvdir
storage/ndb/src/old_files/rep/state/testRepState/Makefile:
mvdir
storage/ndb/src/old_files/rep/state/testRepState/testRequestor.cpp:
mvdir
storage/ndb/src/old_files/rep/state/testRepState/testRequestor.hpp:
mvdir
storage/ndb/src/old_files/rep/storage/GCIBuffer.cpp:
mvdir
storage/ndb/src/old_files/rep/storage/GCIBuffer.hpp:
mvdir
storage/ndb/src/old_files/rep/storage/GCIContainer.cpp:
mvdir
storage/ndb/src/old_files/rep/storage/GCIContainer.hpp:
mvdir
storage/ndb/src/old_files/rep/storage/GCIContainerPS.cpp:
mvdir
storage/ndb/src/old_files/rep/storage/GCIContainerPS.hpp:
mvdir
storage/ndb/src/old_files/rep/storage/GCIPage.cpp:
mvdir
storage/ndb/src/old_files/rep/storage/GCIPage.hpp:
mvdir
storage/ndb/src/old_files/rep/storage/LogRecord.hpp:
mvdir
storage/ndb/src/old_files/rep/storage/Makefile:
mvdir
storage/ndb/src/old_files/rep/storage/NodeConnectInfo.hpp:
mvdir
storage/ndb/src/old_files/rep/storage/NodeGroup.cpp:
mvdir
storage/ndb/src/old_files/rep/storage/NodeGroup.hpp:
mvdir
storage/ndb/src/old_files/rep/storage/NodeGroupInfo.cpp:
mvdir
storage/ndb/src/old_files/rep/storage/NodeGroupInfo.hpp:
mvdir
storage/ndb/src/old_files/rep/transfer/Makefile:
mvdir
storage/ndb/src/old_files/rep/transfer/TransPS.cpp:
mvdir
storage/ndb/src/old_files/rep/transfer/TransPS.hpp:
mvdir
storage/ndb/src/old_files/rep/transfer/TransSS.cpp:
mvdir
storage/ndb/src/old_files/rep/transfer/TransSS.hpp:
mvdir
storage/ndb/src/old_files/rep/transfer/TransSSSubscriptions.cpp:
mvdir
storage/ndb/test/Makefile.am:
mvdir
storage/ndb/test/include/CpcClient.hpp:
mvdir
storage/ndb/test/include/HugoAsynchTransactions.hpp:
mvdir
storage/ndb/test/include/HugoCalculator.hpp:
mvdir
storage/ndb/test/include/HugoOperations.hpp:
mvdir
storage/ndb/test/include/HugoTransactions.hpp:
mvdir
storage/ndb/test/include/NDBT.hpp:
mvdir
storage/ndb/test/include/NDBT_DataSet.hpp:
mvdir
storage/ndb/test/include/NDBT_DataSetTransaction.hpp:
mvdir
storage/ndb/test/include/NDBT_Error.hpp:
mvdir
storage/ndb/test/include/NDBT_Output.hpp:
mvdir
storage/ndb/test/include/NDBT_ResultRow.hpp:
mvdir
storage/ndb/test/include/NDBT_ReturnCodes.h:
mvdir
storage/ndb/test/include/NDBT_Stats.hpp:
mvdir
storage/ndb/test/include/NDBT_Table.hpp:
mvdir
storage/ndb/test/include/NDBT_Tables.hpp:
mvdir
storage/ndb/test/include/NDBT_Test.hpp:
mvdir
storage/ndb/test/include/NdbBackup.hpp:
mvdir
storage/ndb/test/include/NdbConfig.hpp:
mvdir
storage/ndb/test/include/NdbGrep.hpp:
mvdir
storage/ndb/test/include/NdbRestarter.hpp:
mvdir
storage/ndb/test/include/NdbRestarts.hpp:
mvdir
storage/ndb/test/include/NdbSchemaCon.hpp:
mvdir
storage/ndb/test/include/NdbSchemaOp.hpp:
mvdir
storage/ndb/test/include/NdbTest.hpp:
mvdir
storage/ndb/test/include/NdbTimer.hpp:
mvdir
storage/ndb/test/include/TestNdbEventOperation.hpp:
mvdir
storage/ndb/test/include/UtilTransactions.hpp:
mvdir
storage/ndb/test/include/getarg.h:
mvdir
storage/ndb/test/ndbapi/InsertRecs.cpp:
mvdir
storage/ndb/test/ndbapi/Makefile.am:
mvdir
storage/ndb/test/ndbapi/ScanFilter.hpp:
mvdir
storage/ndb/test/ndbapi/ScanFunctions.hpp:
mvdir
storage/ndb/test/ndbapi/ScanInterpretTest.hpp:
mvdir
storage/ndb/test/ndbapi/TraceNdbApi.cpp:
mvdir
storage/ndb/test/ndbapi/VerifyNdbApi.cpp:
mvdir
storage/ndb/test/ndbapi/acid.cpp:
mvdir
storage/ndb/test/ndbapi/acid2.cpp:
mvdir
storage/ndb/test/ndbapi/adoInsertRecs.cpp:
mvdir
storage/ndb/test/ndbapi/asyncGenerator.cpp:
mvdir
storage/ndb/test/ndbapi/benchronja.cpp:
mvdir
storage/ndb/test/ndbapi/bulk_copy.cpp:
mvdir
storage/ndb/test/ndbapi/cdrserver.cpp:
mvdir
storage/ndb/test/ndbapi/celloDb.cpp:
mvdir
storage/ndb/test/ndbapi/create_all_tabs.cpp:
mvdir
storage/ndb/test/ndbapi/create_tab.cpp:
mvdir
storage/ndb/test/ndbapi/drop_all_tabs.cpp:
mvdir
storage/ndb/test/ndbapi/flexAsynch.cpp:
mvdir
storage/ndb/test/ndbapi/flexBench.cpp:
mvdir
storage/ndb/test/ndbapi/flexHammer.cpp:
mvdir
storage/ndb/test/ndbapi/flexScan.cpp:
mvdir
storage/ndb/test/ndbapi/flexTT.cpp:
mvdir
storage/ndb/test/ndbapi/flexTimedAsynch.cpp:
mvdir
storage/ndb/test/ndbapi/flex_bench_mysql.cpp:
mvdir
storage/ndb/test/ndbapi/index.cpp:
mvdir
storage/ndb/test/ndbapi/index2.cpp:
mvdir
storage/ndb/test/ndbapi/initronja.cpp:
mvdir
storage/ndb/test/ndbapi/interpreterInTup.cpp:
mvdir
storage/ndb/test/ndbapi/mainAsyncGenerator.cpp:
mvdir
storage/ndb/test/ndbapi/msa.cpp:
mvdir
storage/ndb/test/ndbapi/ndb_async1.cpp:
mvdir
storage/ndb/test/ndbapi/ndb_async2.cpp:
mvdir
storage/ndb/test/ndbapi/ndb_user_populate.cpp:
mvdir
storage/ndb/test/ndbapi/ndb_user_transaction.cpp:
mvdir
storage/ndb/test/ndbapi/ndb_user_transaction2.cpp:
mvdir
storage/ndb/test/ndbapi/ndb_user_transaction3.cpp:
mvdir
storage/ndb/test/ndbapi/ndb_user_transaction4.cpp:
mvdir
storage/ndb/test/ndbapi/ndb_user_transaction5.cpp:
mvdir
storage/ndb/test/ndbapi/ndb_user_transaction6.cpp:
mvdir
storage/ndb/test/ndbapi/restarter.cpp:
mvdir
storage/ndb/test/ndbapi/restarter2.cpp:
mvdir
storage/ndb/test/ndbapi/restarts.cpp:
mvdir
storage/ndb/test/ndbapi/size.cpp:
mvdir
storage/ndb/test/ndbapi/slow_select.cpp:
mvdir
storage/ndb/test/ndbapi/testBackup.cpp:
mvdir
storage/ndb/test/ndbapi/testBasic.cpp:
mvdir
storage/ndb/test/ndbapi/testBasicAsynch.cpp:
mvdir
storage/ndb/test/ndbapi/testBitfield.cpp:
mvdir
storage/ndb/test/ndbapi/testBlobs.cpp:
mvdir
storage/ndb/test/ndbapi/testDataBuffers.cpp:
mvdir
storage/ndb/test/ndbapi/testDeadlock.cpp:
mvdir
storage/ndb/test/ndbapi/testDict.cpp:
mvdir
storage/ndb/test/ndbapi/testGrep.cpp:
mvdir
storage/ndb/test/ndbapi/testGrepVerify.cpp:
mvdir
storage/ndb/test/ndbapi/testIndex.cpp:
mvdir
storage/ndb/test/ndbapi/testInterpreter.cpp:
mvdir
storage/ndb/test/ndbapi/testLcp.cpp:
mvdir
storage/ndb/test/ndbapi/testMgm.cpp:
mvdir
storage/ndb/test/ndbapi/testNdbApi.cpp:
mvdir
storage/ndb/test/ndbapi/testNodeRestart.cpp:
mvdir
storage/ndb/test/ndbapi/testOIBasic.cpp:
mvdir
storage/ndb/test/ndbapi/testOperations.cpp:
mvdir
storage/ndb/test/ndbapi/testOrderedIndex.cpp:
mvdir
storage/ndb/test/ndbapi/testPartitioning.cpp:
mvdir
storage/ndb/test/ndbapi/testReadPerf.cpp:
mvdir
storage/ndb/test/ndbapi/testRestartGci.cpp:
mvdir
storage/ndb/test/ndbapi/bank/Bank.cpp:
mvdir
storage/ndb/test/ndbapi/bank/Bank.hpp:
mvdir
storage/ndb/test/ndbapi/bank/BankLoad.cpp:
mvdir
storage/ndb/test/ndbapi/bank/Makefile.am:
mvdir
storage/ndb/test/ndbapi/bank/bankCreator.cpp:
mvdir
storage/ndb/test/ndbapi/bank/bankMakeGL.cpp:
mvdir
storage/ndb/test/ndbapi/bank/bankSumAccounts.cpp:
mvdir
storage/ndb/test/ndbapi/bank/bankTimer.cpp:
mvdir
storage/ndb/test/ndbapi/bank/bankTransactionMaker.cpp:
mvdir
storage/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp:
mvdir
storage/ndb/test/ndbapi/bank/testBank.cpp:
mvdir
storage/ndb/test/ndbapi/bench/asyncGenerator.cpp:
mvdir
storage/ndb/test/ndbapi/bench/dbGenerator.h:
mvdir
storage/ndb/test/ndbapi/bench/dbPopulate.cpp:
mvdir
storage/ndb/test/ndbapi/bench/dbPopulate.h:
mvdir
storage/ndb/test/ndbapi/bench/macros.h:
mvdir
storage/ndb/test/ndbapi/bench/mainAsyncGenerator.cpp:
mvdir
storage/ndb/test/ndbapi/bench/mainPopulate.cpp:
mvdir
storage/ndb/test/ndbapi/bench/ndb_async1.cpp:
mvdir
storage/ndb/test/ndbapi/bench/ndb_async2.cpp:
mvdir
storage/ndb/test/ndbapi/bench/ndb_error.hpp:
mvdir
storage/ndb/test/ndbapi/bench/ndb_schema.hpp:
mvdir
storage/ndb/test/ndbapi/bench/ndb_user_transaction.cpp:
mvdir
storage/ndb/test/ndbapi/bench/ndb_user_transaction2.cpp:
mvdir
storage/ndb/test/ndbapi/bench/ndb_user_transaction3.cpp:
mvdir
storage/ndb/test/ndbapi/bench/ndb_user_transaction4.cpp:
mvdir
storage/ndb/test/ndbapi/bench/ndb_user_transaction5.cpp:
mvdir
storage/ndb/test/ndbapi/testScan.cpp:
mvdir
storage/ndb/test/ndbapi/testScanInterpreter.cpp:
mvdir
storage/ndb/test/ndbapi/testScanPerf.cpp:
mvdir
storage/ndb/test/ndbapi/testSystemRestart.cpp:
mvdir
storage/ndb/test/ndbapi/testTimeout.cpp:
mvdir
storage/ndb/test/ndbapi/testTransactions.cpp:
mvdir
storage/ndb/test/ndbapi/test_event.cpp:
mvdir
storage/ndb/test/ndbapi/test_event_multi_table.cpp:
mvdir
storage/ndb/test/ndbapi/userInterface.cpp:
mvdir
storage/ndb/test/ndbapi/bench/ndb_user_transaction6.cpp:
mvdir
storage/ndb/test/ndbapi/bench/testData.h:
mvdir
storage/ndb/test/ndbapi/bench/testDefinitions.h:
mvdir
storage/ndb/test/ndbapi/bench/userInterface.cpp:
mvdir
storage/ndb/test/ndbapi/bench/userInterface.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/acid/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/acid2/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/acid2/TraceNdbApi.hpp:
mvdir
storage/ndb/test/ndbapi/old_dirs/acid2/VerifyNdbApi.hpp:
mvdir
storage/ndb/test/ndbapi/old_dirs/basicAsynch/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/bulk_copy/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/create_all_tabs/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/create_tab/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/drop_all_tabs/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/flexAsynch/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/flexBench/Makefile.am:
mvdir
storage/ndb/test/ndbapi/old_dirs/flexBench/ndbplot.pl:
mvdir
storage/ndb/test/ndbapi/old_dirs/flexHammer/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/flexHammer/README:
mvdir
storage/ndb/test/ndbapi/old_dirs/flexScan/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/flexScan/README:
mvdir
storage/ndb/test/ndbapi/old_dirs/flexTT/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/flexTimedAsynch/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/flex_bench_mysql/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/indexTest/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/indexTest2/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/interpreterInTup/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/generator/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/dbGenerator.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/testData.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/userInterface.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/macros.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/ndb_error.hpp:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/bin/.empty:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/include/ndb_schema.hpp:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/include/testDefinitions.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/lib/.empty:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/script/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l-p10.sh:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l.sh:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-p10.sh:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench.sh:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/README:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.c:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/mainGenerator.c:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/include/testData.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/include/userInterface.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.linux:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.sparc:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/dbPopulate.c:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/dbPopulate.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/mainPopulate.c:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/localDbPrepare.c:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/macros.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/ndb_error.hpp:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userHandle.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userInterface.c:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userHandle.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userInterface.cpp:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userTransaction.c:
mvdir
storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userTransaction.c:
mvdir
storage/ndb/test/ndbapi/old_dirs/restarter/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/restarter2/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/restarts/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/ronja/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/ronja/benchronja/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/ronja/initronja/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/telco/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/telco/readme:
mvdir
storage/ndb/test/ndbapi/old_dirs/testBackup/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testBasic/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testBlobs/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testDataBuffers/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testDict/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testGrep/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testIndex/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testInterpreter/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testMgm/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testNdbApi/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testNodeRestart/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testOIBasic/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testOIBasic/times.txt:
mvdir
storage/ndb/test/ndbapi/old_dirs/testOperations/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testOrderedIndex/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testRestartGci/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testScan/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testScanInterpreter/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testSystemRestart/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testTimeout/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/testTransactions/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/test_event/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/vw_test/Makefile:
mvdir
storage/ndb/test/ndbapi/old_dirs/vw_test/bcd.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/vw_test/script/client_start:
mvdir
storage/ndb/test/ndbapi/old_dirs/vw_test/utv.h:
mvdir
storage/ndb/test/ndbapi/old_dirs/vw_test/vcdrfunc.h:
mvdir
storage/ndb/test/ndbnet/test.run:
mvdir
storage/ndb/test/ndbnet/testError.run:
mvdir
storage/ndb/test/ndbnet/testMNF.run:
mvdir
storage/ndb/test/ndbnet/testNR.run:
mvdir
storage/ndb/test/ndbnet/testNR1.run:
mvdir
storage/ndb/test/ndbnet/testNR4.run:
mvdir
storage/ndb/test/ndbnet/testSRhang.run:
mvdir
storage/ndb/test/ndbnet/testTR295.run:
mvdir
storage/ndb/test/newtonapi/basic_test/Makefile:
mvdir
storage/ndb/test/newtonapi/basic_test/basic/Makefile:
mvdir
storage/ndb/test/newtonapi/basic_test/basic/basic.cpp:
mvdir
storage/ndb/test/newtonapi/basic_test/bulk_read/Makefile:
mvdir
storage/ndb/test/newtonapi/basic_test/bulk_read/br_test.cpp:
mvdir
storage/ndb/test/newtonapi/basic_test/common.cpp:
mvdir
storage/ndb/test/newtonapi/basic_test/common.hpp:
mvdir
storage/ndb/test/newtonapi/basic_test/ptr_binding/Makefile:
mvdir
storage/ndb/test/newtonapi/basic_test/ptr_binding/ptr_binding_test.cpp:
mvdir
storage/ndb/test/newtonapi/basic_test/too_basic.cpp:
mvdir
storage/ndb/test/newtonapi/perf_test/Makefile:
mvdir
storage/ndb/test/newtonapi/perf_test/perf.cpp:
mvdir
storage/ndb/test/odbc/SQL99_test/Makefile:
mvdir
storage/ndb/test/odbc/SQL99_test/SQL99_test.cpp:
mvdir
storage/ndb/test/odbc/SQL99_test/SQL99_test.h:
mvdir
storage/ndb/test/odbc/client/Makefile:
mvdir
storage/ndb/test/odbc/client/NDBT_ALLOCHANDLE.cpp:
mvdir
storage/ndb/test/odbc/client/NDBT_ALLOCHANDLE_HDBC.cpp:
mvdir
storage/ndb/test/odbc/client/NDBT_SQLConnect.cpp:
mvdir
storage/ndb/test/odbc/client/NDBT_SQLPrepare.cpp:
mvdir
storage/ndb/test/odbc/client/SQLAllocEnvTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLAllocHandleTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLAllocHandleTest_bf.cpp:
mvdir
storage/ndb/test/odbc/client/SQLBindColTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLBindParameterTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLCancelTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLCloseCursorTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLColAttributeTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLColAttributeTest1.cpp:
mvdir
storage/ndb/test/odbc/client/SQLColAttributeTest2.cpp:
mvdir
storage/ndb/test/odbc/client/SQLColAttributeTest3.cpp:
mvdir
storage/ndb/test/odbc/client/SQLConnectTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLCopyDescTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLDescribeColTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLDisconnectTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLDriverConnectTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLEndTranTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLErrorTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLExecDirectTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLExecuteTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLFetchScrollTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLFetchTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLFreeHandleTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLFreeStmtTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetConnectAttrTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetCursorNameTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetDataTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetDescFieldTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetDescRecTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetDiagFieldTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetDiagRecSimpleTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetDiagRecTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetEnvAttrTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetFunctionsTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetInfoTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetStmtAttrTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLGetTypeInfoTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLMoreResultsTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLNumResultColsTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLParamDataTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLPrepareTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLPutDataTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLRowCountTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLSetConnectAttrTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLSetCursorNameTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLSetDescFieldTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLSetDescRecTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLSetEnvAttrTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLSetStmtAttrTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLTablesTest.cpp:
mvdir
storage/ndb/test/odbc/client/SQLTransactTest.cpp:
mvdir
storage/ndb/test/odbc/client/common.hpp:
mvdir
storage/ndb/test/odbc/client/main.cpp:
mvdir
storage/ndb/test/odbc/dm-iodbc/Makefile:
mvdir
storage/ndb/test/odbc/dm-unixodbc/Makefile:
mvdir
storage/ndb/test/odbc/driver/Makefile:
mvdir
storage/ndb/test/odbc/driver/testOdbcDriver.cpp:
mvdir
storage/ndb/test/odbc/test_compiler/Makefile:
mvdir
storage/ndb/test/odbc/test_compiler/test_compiler.cpp:
mvdir
storage/ndb/test/run-test/16node-tests.txt:
mvdir
storage/ndb/test/run-test/Makefile.am:
mvdir
storage/ndb/test/run-test/README.ATRT:
mvdir
storage/ndb/test/run-test/README:
mvdir
storage/ndb/test/run-test/atrt-analyze-result.sh:
mvdir
storage/ndb/test/run-test/atrt-clear-result.sh:
mvdir
storage/ndb/test/run-test/atrt-example.tgz:
mvdir
storage/ndb/test/run-test/atrt-gather-result.sh:
mvdir
storage/ndb/test/run-test/atrt-mysql-test-run:
mvdir
storage/ndb/test/run-test/atrt-setup.sh:
mvdir
storage/ndb/test/run-test/atrt-testBackup:
mvdir
storage/ndb/test/run-test/basic.txt:
mvdir
storage/ndb/test/run-test/daily-basic-tests.txt:
mvdir
storage/ndb/test/run-test/daily-devel-tests.txt:
mvdir
storage/ndb/test/run-test/example.conf:
mvdir
storage/ndb/test/run-test/main.cpp:
mvdir
storage/ndb/test/run-test/make-config.sh:
mvdir
storage/ndb/test/run-test/make-html-reports.sh:
mvdir
storage/ndb/test/run-test/make-index.sh:
mvdir
storage/ndb/test/run-test/ndb-autotest.sh:
mvdir
storage/ndb/test/run-test/run-test.hpp:
mvdir
storage/ndb/test/src/CpcClient.cpp:
mvdir
storage/ndb/test/src/HugoAsynchTransactions.cpp:
mvdir
storage/ndb/test/src/HugoCalculator.cpp:
mvdir
storage/ndb/test/src/HugoOperations.cpp:
mvdir
storage/ndb/test/src/HugoTransactions.cpp:
mvdir
storage/ndb/test/src/Makefile.am:
mvdir
storage/ndb/test/src/NDBT_Error.cpp:
mvdir
storage/ndb/test/src/NDBT_Output.cpp:
mvdir
storage/ndb/test/src/NDBT_ResultRow.cpp:
mvdir
storage/ndb/test/src/NDBT_ReturnCodes.cpp:
mvdir
storage/ndb/test/src/NDBT_Table.cpp:
mvdir
storage/ndb/test/src/NDBT_Tables.cpp:
mvdir
storage/ndb/test/src/NDBT_Test.cpp:
mvdir
storage/ndb/test/src/NdbBackup.cpp:
mvdir
storage/ndb/test/src/NdbConfig.cpp:
mvdir
storage/ndb/test/src/NdbGrep.cpp:
mvdir
storage/ndb/test/src/NdbRestarter.cpp:
mvdir
storage/ndb/test/src/NdbRestarts.cpp:
mvdir
storage/ndb/test/src/NdbSchemaCon.cpp:
mvdir
storage/ndb/test/src/NdbSchemaOp.cpp:
mvdir
storage/ndb/test/src/UtilTransactions.cpp:
mvdir
storage/ndb/test/src/getarg.c:
mvdir
storage/ndb/test/tools/Makefile.am:
mvdir
storage/ndb/test/tools/copy_tab.cpp:
mvdir
storage/ndb/test/tools/cpcc.cpp:
mvdir
storage/ndb/test/tools/create_index.cpp:
mvdir
storage/ndb/test/tools/hugoCalculator.cpp:
mvdir
storage/ndb/test/tools/hugoFill.cpp:
mvdir
storage/ndb/test/tools/hugoLoad.cpp:
mvdir
storage/ndb/test/tools/hugoLockRecords.cpp:
mvdir
storage/ndb/test/tools/hugoPkDelete.cpp:
mvdir
storage/ndb/test/tools/hugoPkRead.cpp:
mvdir
storage/ndb/test/tools/hugoPkReadRecord.cpp:
mvdir
storage/ndb/test/tools/hugoPkUpdate.cpp:
mvdir
storage/ndb/test/tools/hugoScanRead.cpp:
mvdir
storage/ndb/test/tools/hugoScanUpdate.cpp:
mvdir
storage/ndb/test/tools/old_dirs/hugoCalculator/Makefile:
mvdir
storage/ndb/test/tools/old_dirs/hugoFill/Makefile:
mvdir
storage/ndb/test/tools/old_dirs/hugoLoad/Makefile:
mvdir
storage/ndb/test/tools/old_dirs/hugoLockRecords/Makefile:
mvdir
storage/ndb/test/tools/old_dirs/hugoPkDelete/Makefile:
mvdir
storage/ndb/test/tools/old_dirs/hugoPkRead/Makefile:
mvdir
storage/ndb/test/tools/restart.cpp:
mvdir
storage/ndb/test/tools/transproxy.cpp:
mvdir
storage/ndb/test/tools/verify_index.cpp:
mvdir
storage/ndb/test/tools/old_dirs/hugoPkReadRecord/Makefile:
mvdir
storage/ndb/test/tools/old_dirs/hugoPkUpdate/Makefile:
mvdir
storage/ndb/test/tools/old_dirs/hugoScanRead/Makefile:
mvdir
storage/ndb/test/tools/old_dirs/hugoScanUpdate/Makefile:
mvdir
storage/ndb/test/tools/old_dirs/restart/Makefile:
mvdir
storage/ndb/test/tools/old_dirs/transproxy/Makefile:
mvdir
storage/ndb/test/tools/old_dirs/verify_index/Makefile:
mvdir
storage/ndb/test/tools/old_dirs/waiter/waiter.cpp:
mvdir
storage/ndb/tools/Makefile.am:
mvdir
storage/ndb/tools/clean-links.sh:
mvdir
storage/ndb/tools/delete_all.cpp:
mvdir
storage/ndb/tools/desc.cpp:
mvdir
storage/ndb/tools/drop_index.cpp:
mvdir
storage/ndb/tools/drop_tab.cpp:
mvdir
storage/ndb/tools/listTables.cpp:
mvdir
storage/ndb/tools/make-errors.pl:
mvdir
storage/ndb/tools/make-links.sh:
mvdir
storage/ndb/tools/ndb_test_platform.cpp:
mvdir
storage/ndb/tools/ndbsql.cpp:
mvdir
storage/ndb/tools/old_dirs/copy_tab/Makefile:
mvdir
storage/ndb/tools/old_dirs/cpcc/Makefile:
mvdir
storage/ndb/tools/old_dirs/create_index/Makefile:
mvdir
storage/ndb/tools/old_dirs/delete_all/Makefile:
mvdir
storage/ndb/tools/old_dirs/desc/Makefile:
mvdir
storage/ndb/tools/old_dirs/drop_index/Makefile:
mvdir
storage/ndb/tools/old_dirs/drop_tab/Makefile:
mvdir
storage/ndb/tools/old_dirs/list_tables/Makefile:
mvdir
storage/ndb/tools/old_dirs/ndbnet/Makefile.PL:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Run.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/ndbnet.pl:
mvdir
storage/ndb/tools/old_dirs/ndbnet/ndbnetd.pl:
mvdir
storage/ndb/tools/old_dirs/ndbnet/ndbrun:
mvdir
storage/ndb/tools/rgrep:
mvdir
storage/ndb/tools/select_all.cpp:
mvdir
storage/ndb/tools/select_count.cpp:
mvdir
storage/ndb/tools/waiter.cpp:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Base.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Client.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Command.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Config.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Database.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Env.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Node.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeApi.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeDb.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeMgmt.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Server.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/ServerINET.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/ServerUNIX.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Run/Base.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Run/Database.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Run/Env.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Run/Node.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Base.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Dir.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Event.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/File.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/IO.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Lock.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Log.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Socket.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/SocketINET.pm:
mvdir
storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/SocketUNIX.pm:
mvdir
storage/ndb/tools/old_dirs/ndbsql/Makefile:
mvdir
storage/ndb/tools/old_dirs/select_all/Makefile:
mvdir
storage/ndb/tools/old_dirs/select_count/Makefile:
mvdir
storage/ndb/tools/old_dirs/src/counterviewer/CounterViewer.java:
mvdir
storage/ndb/tools/restore/Restore.cpp:
mvdir
storage/ndb/tools/restore/Restore.hpp:
mvdir
storage/ndb/tools/restore/consumer.cpp:
mvdir
storage/ndb/tools/restore/consumer.hpp:
mvdir
storage/ndb/tools/restore/consumer_printer.cpp:
mvdir
storage/ndb/tools/restore/consumer_printer.hpp:
mvdir
storage/ndb/tools/restore/consumer_restore.cpp:
mvdir
storage/ndb/tools/restore/consumer_restore.hpp:
mvdir
storage/ndb/tools/restore/consumer_restorem.cpp:
mvdir
storage/ndb/tools/restore/restore_main.cpp:
mvdir
storage/bdb/LICENSE:
mvdir
storage/bdb/Makefile.in:
mvdir
storage/bdb/btree/bt_compare.c:
mvdir
storage/bdb/btree/bt_conv.c:
mvdir
storage/bdb/btree/bt_curadj.c:
mvdir
storage/bdb/btree/bt_cursor.c:
mvdir
storage/bdb/btree/bt_delete.c:
mvdir
storage/bdb/btree/bt_method.c:
mvdir
storage/bdb/btree/bt_open.c:
mvdir
storage/bdb/btree/bt_put.c:
mvdir
storage/bdb/btree/bt_rec.c:
mvdir
storage/bdb/btree/bt_reclaim.c:
mvdir
storage/bdb/btree/bt_recno.c:
mvdir
storage/bdb/btree/bt_rsearch.c:
mvdir
storage/bdb/btree/bt_search.c:
mvdir
storage/bdb/btree/bt_split.c:
mvdir
storage/bdb/btree/bt_stat.c:
mvdir
storage/bdb/btree/bt_upgrade.c:
mvdir
storage/bdb/btree/bt_verify.c:
mvdir
storage/bdb/btree/btree.src:
mvdir
storage/bdb/build_unix/.IGNORE_ME:
mvdir
storage/bdb/build_vxworks/BerkeleyDB.wsp:
mvdir
storage/bdb/build_vxworks/dbdemo/README:
mvdir
storage/bdb/build_win32/Berkeley_DB.dsw:
mvdir
storage/bdb/build_win32/app_dsp.src:
mvdir
storage/bdb/build_win32/build_all.dsp:
mvdir
storage/bdb/build_win32/db_java_xa.dsp:
mvdir
storage/bdb/build_win32/db_java_xaj.mak:
mvdir
storage/bdb/build_win32/db_lib.dsp:
mvdir
storage/bdb/build_win32/db_test.src:
mvdir
storage/bdb/build_win32/dbkill.cpp:
mvdir
storage/bdb/build_win32/dllmain.c:
mvdir
storage/bdb/build_win32/dynamic_dsp.src:
mvdir
storage/bdb/build_win32/java_dsp.src:
mvdir
storage/bdb/build_win32/libdb_tcl.def:
mvdir
storage/bdb/build_win32/libdbrc.src:
mvdir
storage/bdb/build_win32/srcfile_dsp.src:
mvdir
storage/bdb/build_win32/static_dsp.src:
mvdir
storage/bdb/build_win32/tcl_dsp.src:
mvdir
storage/bdb/clib/getcwd.c:
mvdir
storage/bdb/clib/getopt.c:
mvdir
storage/bdb/clib/memcmp.c:
mvdir
storage/bdb/clib/memmove.c:
mvdir
storage/bdb/clib/raise.c:
mvdir
storage/bdb/clib/snprintf.c:
mvdir
storage/bdb/clib/strcasecmp.c:
mvdir
storage/bdb/clib/strdup.c:
mvdir
storage/bdb/clib/strerror.c:
mvdir
storage/bdb/clib/vsnprintf.c:
mvdir
storage/bdb/common/db_byteorder.c:
mvdir
storage/bdb/common/db_err.c:
mvdir
storage/bdb/common/db_getlong.c:
mvdir
storage/bdb/common/db_idspace.c:
mvdir
storage/bdb/common/db_log2.c:
mvdir
storage/bdb/common/util_arg.c:
mvdir
storage/bdb/common/util_cache.c:
mvdir
storage/bdb/common/util_log.c:
mvdir
storage/bdb/common/util_sig.c:
mvdir
storage/bdb/cxx/cxx_db.cpp:
mvdir
storage/bdb/cxx/cxx_dbc.cpp:
mvdir
storage/bdb/cxx/cxx_dbt.cpp:
mvdir
storage/bdb/cxx/cxx_env.cpp:
mvdir
storage/bdb/cxx/cxx_except.cpp:
mvdir
storage/bdb/cxx/cxx_lock.cpp:
mvdir
storage/bdb/cxx/cxx_logc.cpp:
mvdir
storage/bdb/cxx/cxx_mpool.cpp:
mvdir
storage/bdb/cxx/cxx_txn.cpp:
mvdir
storage/bdb/db/crdel.src:
mvdir
storage/bdb/db/crdel_rec.c:
mvdir
storage/bdb/db/db.c:
mvdir
storage/bdb/db/db.src:
mvdir
storage/bdb/db/db_am.c:
mvdir
storage/bdb/db/db_cam.c:
mvdir
storage/bdb/db/db_conv.c:
mvdir
storage/bdb/db/db_dispatch.c:
mvdir
storage/bdb/db/db_dup.c:
mvdir
storage/bdb/db/db_iface.c:
mvdir
storage/bdb/db/db_join.c:
mvdir
storage/bdb/db/db_meta.c:
mvdir
storage/bdb/db/db_method.c:
mvdir
storage/bdb/db/db_open.c:
mvdir
storage/bdb/db/db_overflow.c:
mvdir
storage/bdb/db/db_pr.c:
mvdir
storage/bdb/db/db_rec.c:
mvdir
storage/bdb/db/db_reclaim.c:
mvdir
storage/bdb/db/db_remove.c:
mvdir
storage/bdb/db/db_rename.c:
mvdir
storage/bdb/db/db_ret.c:
mvdir
storage/bdb/db/db_truncate.c:
mvdir
storage/bdb/db/db_upg.c:
mvdir
storage/bdb/db/db_upg_opd.c:
mvdir
storage/bdb/db/db_vrfy.c:
mvdir
storage/bdb/db/db_vrfyutil.c:
mvdir
storage/bdb/db185/db185.c:
mvdir
storage/bdb/db185/db185_int.in:
mvdir
storage/bdb/db_archive/db_archive.c:
mvdir
storage/bdb/db_checkpoint/db_checkpoint.c:
mvdir
storage/bdb/db_deadlock/db_deadlock.c:
mvdir
storage/bdb/db_dump/db_dump.c:
mvdir
storage/bdb/db_dump185/db_dump185.c:
mvdir
storage/bdb/db_load/db_load.c:
mvdir
storage/bdb/db_printlog/README:
mvdir
storage/bdb/db_printlog/commit.awk:
mvdir
storage/bdb/db_printlog/count.awk:
mvdir
storage/bdb/db_printlog/db_printlog.c:
mvdir
storage/bdb/db_printlog/dbname.awk:
mvdir
storage/bdb/db_printlog/fileid.awk:
mvdir
storage/bdb/db_printlog/logstat.awk:
mvdir
storage/bdb/db_printlog/pgno.awk:
mvdir
storage/bdb/db_printlog/range.awk:
mvdir
storage/bdb/db_printlog/rectype.awk:
mvdir
storage/bdb/db_printlog/status.awk:
mvdir
storage/bdb/db_printlog/txn.awk:
mvdir
storage/bdb/db_recover/db_recover.c:
mvdir
storage/bdb/db_stat/db_stat.c:
mvdir
storage/bdb/db_upgrade/db_upgrade.c:
mvdir
storage/bdb/db_verify/db_verify.c:
mvdir
storage/bdb/dbinc/btree.h:
mvdir
storage/bdb/dbinc/crypto.h:
mvdir
storage/bdb/dbinc/cxx_common.h:
mvdir
storage/bdb/dbinc/cxx_except.h:
mvdir
storage/bdb/dbinc/cxx_int.h:
mvdir
storage/bdb/dbinc/db.in:
mvdir
storage/bdb/dbinc/db_185.in:
mvdir
storage/bdb/dbinc/db_am.h:
mvdir
storage/bdb/dbinc/db_cxx.in:
mvdir
storage/bdb/dbinc/db_dispatch.h:
mvdir
storage/bdb/dbinc/db_int.in:
mvdir
storage/bdb/dbinc/db_join.h:
mvdir
storage/bdb/dbinc/db_page.h:
mvdir
storage/bdb/dbinc/db_server_int.h:
mvdir
storage/bdb/dbinc/db_shash.h:
mvdir
storage/bdb/dbinc/db_swap.h:
mvdir
storage/bdb/dbinc/db_upgrade.h:
mvdir
storage/bdb/dbinc/db_verify.h:
mvdir
storage/bdb/dbinc/debug.h:
mvdir
storage/bdb/dbinc/fop.h:
mvdir
storage/bdb/dbinc/globals.h:
mvdir
storage/bdb/dbinc/hash.h:
mvdir
storage/bdb/dbinc/hmac.h:
mvdir
storage/bdb/dbinc/lock.h:
mvdir
storage/bdb/dbinc/log.h:
mvdir
storage/bdb/dbinc/mp.h:
mvdir
storage/bdb/dbinc/mutex.h:
mvdir
storage/bdb/dbinc/os.h:
mvdir
storage/bdb/dbinc/qam.h:
mvdir
storage/bdb/dbinc/queue.h:
mvdir
storage/bdb/dbinc/region.h:
mvdir
storage/bdb/dbinc/rep.h:
mvdir
storage/bdb/dbinc/shqueue.h:
mvdir
storage/bdb/dbinc/tcl_db.h:
mvdir
storage/bdb/dbinc/txn.h:
mvdir
storage/bdb/dbinc/xa.h:
mvdir
storage/bdb/dbm/dbm.c:
mvdir
storage/bdb/dbreg/dbreg.c:
mvdir
storage/bdb/dbreg/dbreg.src:
mvdir
storage/bdb/dbreg/dbreg_rec.c:
mvdir
storage/bdb/dbreg/dbreg_util.c:
mvdir
storage/bdb/dist/Makefile.in:
mvdir
storage/bdb/dist/RELEASE:
mvdir
storage/bdb/dist/buildrel:
mvdir
storage/bdb/dist/config.guess:
mvdir
storage/bdb/dist/config.sub:
mvdir
storage/bdb/dist/configure.ac:
mvdir
storage/bdb/dist/db.ecd.in:
mvdir
storage/bdb/dist/db.spec.in:
mvdir
storage/bdb/dist/gen_inc.awk:
mvdir
storage/bdb/dist/gen_rec.awk:
mvdir
storage/bdb/dist/gen_rpc.awk:
mvdir
storage/bdb/dist/install-sh:
mvdir
storage/bdb/dist/ltmain.sh:
mvdir
storage/bdb/dist/pubdef.in:
mvdir
storage/bdb/dist/s_all:
mvdir
storage/bdb/dist/s_config:
mvdir
storage/bdb/dist/aclocal/config.ac:
mvdir
storage/bdb/dist/aclocal/cxx.ac:
mvdir
storage/bdb/dist/aclocal/gcc.ac:
mvdir
storage/bdb/dist/aclocal/libtool.ac:
mvdir
storage/bdb/dist/s_crypto:
mvdir
storage/bdb/dist/s_dir:
mvdir
storage/bdb/dist/s_include:
mvdir
storage/bdb/dist/s_javah:
mvdir
storage/bdb/dist/s_java:
mvdir
storage/bdb/dist/s_perm:
mvdir
storage/bdb/dist/s_readme:
mvdir
storage/bdb/dist/s_recover:
mvdir
storage/bdb/dist/s_rpc:
mvdir
storage/bdb/dist/s_symlink:
mvdir
storage/bdb/dist/s_tags:
mvdir
storage/bdb/dist/s_test:
mvdir
storage/bdb/dist/s_vxworks:
mvdir
storage/bdb/dist/s_win32_dsp:
mvdir
storage/bdb/dist/s_win32:
mvdir
storage/bdb/dist/srcfiles.in:
mvdir
storage/bdb/dist/vx_buildcd:
mvdir
storage/bdb/dist/vx_config.in:
mvdir
storage/bdb/dist/win_config.in:
mvdir
storage/bdb/dist/win_exports.in:
mvdir
storage/bdb/dist/aclocal/mutex.ac:
mvdir
storage/bdb/dist/aclocal/options.ac:
mvdir
storage/bdb/dist/aclocal/programs.ac:
mvdir
storage/bdb/dist/aclocal/sosuffix.ac:
mvdir
storage/bdb/dist/aclocal/tcl.ac:
mvdir
storage/bdb/dist/aclocal/types.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_check_class.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_check_classpath.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_check_junit.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_check_rqrd_class.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_java_options.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_jni_include_dirs.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_prog_jar.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_prog_java.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_prog_java_works.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_prog_javac.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_prog_javac_works.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_prog_javadoc.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_prog_javah.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_try_compile_java.ac:
mvdir
storage/bdb/dist/aclocal_java/ac_try_run_javac.ac:
mvdir
storage/bdb/dist/template/rec_ctemp:
mvdir
storage/bdb/dist/vx_2.0/BerkeleyDB.wpj:
mvdir
storage/bdb/dist/vx_2.0/wpj.in:
mvdir
storage/bdb/dist/vx_3.1/Makefile.custom:
mvdir
storage/bdb/dist/vx_3.1/cdf.1:
mvdir
storage/bdb/dist/vx_3.1/cdf.2:
mvdir
storage/bdb/dist/vx_3.1/cdf.3:
mvdir
storage/bdb/dist/vx_3.1/component.cdf:
mvdir
storage/bdb/dist/vx_3.1/component.wpj:
mvdir
storage/bdb/dist/vx_3.1/wpj.1:
mvdir
storage/bdb/dist/vx_3.1/wpj.2:
mvdir
storage/bdb/dist/vx_3.1/wpj.3:
mvdir
storage/bdb/dist/vx_3.1/wpj.4:
mvdir
storage/bdb/dist/vx_3.1/wpj.5:
mvdir
storage/bdb/dist/vx_setup/CONFIG.in:
mvdir
storage/bdb/dist/vx_setup/LICENSE.TXT:
mvdir
storage/bdb/dist/vx_setup/MESSAGES.TCL:
mvdir
storage/bdb/dist/vx_setup/README.in:
mvdir
storage/bdb/dist/vx_setup/SETUP.BMP:
mvdir
storage/bdb/dist/vx_setup/vx_allfile.in:
mvdir
storage/bdb/dist/vx_setup/vx_demofile.in:
mvdir
storage/bdb/dist/vx_setup/vx_setup.in:
mvdir
storage/bdb/env/db_salloc.c:
mvdir
storage/bdb/env/db_shash.c:
mvdir
storage/bdb/env/env_file.c:
mvdir
storage/bdb/env/env_method.c.b:
mvdir
storage/bdb/env/env_method.c:
mvdir
storage/bdb/env/env_open.c:
mvdir
storage/bdb/env/env_recover.c:
mvdir
storage/bdb/env/env_region.c:
mvdir
storage/bdb/fileops/fileops.src:
mvdir
storage/bdb/fileops/fop_basic.c:
mvdir
storage/bdb/fileops/fop_rec.c:
mvdir
storage/bdb/fileops/fop_util.c:
mvdir
storage/bdb/hash/hash.c:
mvdir
storage/bdb/hash/hash.src:
mvdir
storage/bdb/hash/hash_conv.c:
mvdir
storage/bdb/hash/hash_dup.c:
mvdir
storage/bdb/hash/hash_func.c:
mvdir
storage/bdb/hash/hash_meta.c:
mvdir
storage/bdb/hash/hash_method.c:
mvdir
storage/bdb/hash/hash_open.c:
mvdir
storage/bdb/hash/hash_page.c:
mvdir
storage/bdb/hash/hash_rec.c:
mvdir
storage/bdb/hash/hash_reclaim.c:
mvdir
storage/bdb/hash/hash_stat.c:
mvdir
storage/bdb/hash/hash_upgrade.c:
mvdir
storage/bdb/hash/hash_verify.c:
mvdir
storage/bdb/hmac/hmac.c:
mvdir
storage/bdb/hmac/sha1.c:
mvdir
storage/bdb/hsearch/hsearch.c:
mvdir
storage/bdb/libdb_java/checkapi.prl:
mvdir
storage/bdb/libdb_java/com_sleepycat_db_Db.h:
mvdir
storage/bdb/libdb_java/com_sleepycat_db_DbEnv.h:
mvdir
storage/bdb/libdb_java/com_sleepycat_db_DbLock.h:
mvdir
storage/bdb/libdb_java/com_sleepycat_db_DbLogc.h:
mvdir
storage/bdb/libdb_java/com_sleepycat_db_DbLsn.h:
mvdir
storage/bdb/libdb_java/com_sleepycat_db_DbTxn.h:
mvdir
storage/bdb/libdb_java/com_sleepycat_db_DbUtil.h:
mvdir
storage/bdb/libdb_java/com_sleepycat_db_Dbc.h:
mvdir
storage/bdb/libdb_java/com_sleepycat_db_Dbt.h:
mvdir
storage/bdb/libdb_java/com_sleepycat_db_xa_DbXAResource.h:
mvdir
storage/bdb/libdb_java/java_Db.c:
mvdir
storage/bdb/libdb_java/java_DbEnv.c:
mvdir
storage/bdb/libdb_java/java_DbLock.c:
mvdir
storage/bdb/libdb_java/java_DbLogc.c:
mvdir
storage/bdb/libdb_java/java_DbLsn.c:
mvdir
storage/bdb/libdb_java/java_DbTxn.c:
mvdir
storage/bdb/libdb_java/java_DbUtil.c:
mvdir
storage/bdb/libdb_java/java_DbXAResource.c:
mvdir
storage/bdb/libdb_java/java_Dbc.c:
mvdir
storage/bdb/libdb_java/java_Dbt.c:
mvdir
storage/bdb/libdb_java/java_info.c:
mvdir
storage/bdb/libdb_java/java_info.h:
mvdir
storage/bdb/libdb_java/java_locked.c:
mvdir
storage/bdb/libdb_java/java_locked.h:
mvdir
storage/bdb/libdb_java/java_util.c:
mvdir
storage/bdb/libdb_java/java_util.h:
mvdir
storage/bdb/lock/Design:
mvdir
storage/bdb/lock/lock.c:
mvdir
storage/bdb/lock/lock_deadlock.c:
mvdir
storage/bdb/lock/lock_method.c:
mvdir
storage/bdb/lock/lock_region.c:
mvdir
storage/bdb/lock/lock_stat.c:
mvdir
storage/bdb/lock/lock_util.c:
mvdir
storage/bdb/log/log.c:
mvdir
storage/bdb/log/log_archive.c:
mvdir
storage/bdb/log/log_compare.c:
mvdir
storage/bdb/log/log_get.c:
mvdir
storage/bdb/log/log_method.c:
mvdir
storage/bdb/log/log_put.c:
mvdir
storage/bdb/mp/mp_alloc.c:
mvdir
storage/bdb/mp/mp_bh.c:
mvdir
storage/bdb/mp/mp_fget.c:
mvdir
storage/bdb/mp/mp_fopen.c:
mvdir
storage/bdb/mp/mp_fput.c:
mvdir
storage/bdb/mp/mp_fset.c:
mvdir
storage/bdb/mp/mp_method.c:
mvdir
storage/bdb/mp/mp_region.c:
mvdir
storage/bdb/mp/mp_register.c:
mvdir
storage/bdb/mp/mp_stat.c:
mvdir
storage/bdb/mp/mp_sync.c:
mvdir
storage/bdb/mp/mp_trickle.c:
mvdir
storage/bdb/mutex/README:
mvdir
storage/bdb/mutex/mut_fcntl.c:
mvdir
storage/bdb/mutex/mut_pthread.c:
mvdir
storage/bdb/mutex/mut_tas.c:
mvdir
storage/bdb/mutex/mut_win32.c:
mvdir
storage/bdb/mutex/mutex.c:
mvdir
storage/bdb/mutex/tm.c:
mvdir
storage/bdb/mutex/uts4_cc.s:
mvdir
storage/bdb/os/os_abs.c:
mvdir
storage/bdb/os/os_alloc.c:
mvdir
storage/bdb/os/os_clock.c:
mvdir
storage/bdb/os/os_config.c:
mvdir
storage/bdb/os/os_dir.c:
mvdir
storage/bdb/os/os_errno.c:
mvdir
storage/bdb/os/os_fid.c:
mvdir
storage/bdb/os/os_fsync.c:
mvdir
storage/bdb/os/os_handle.c:
mvdir
storage/bdb/os/os_id.c:
mvdir
storage/bdb/os/os_map.c:
mvdir
storage/bdb/os/os_method.c:
mvdir
storage/bdb/os/os_oflags.c:
mvdir
storage/bdb/os/os_open.c:
mvdir
storage/bdb/os/os_region.c:
mvdir
storage/bdb/os/os_rename.c:
mvdir
storage/bdb/os/os_root.c:
mvdir
storage/bdb/os/os_rpath.c:
mvdir
storage/bdb/os/os_rw.c:
mvdir
storage/bdb/os/os_seek.c:
mvdir
storage/bdb/os/os_sleep.c:
mvdir
storage/bdb/os/os_spin.c:
mvdir
storage/bdb/os/os_stat.c:
mvdir
storage/bdb/os/os_tmpdir.c:
mvdir
storage/bdb/os/os_unlink.c:
mvdir
storage/bdb/os_vxworks/os_vx_abs.c:
mvdir
storage/bdb/os_vxworks/os_vx_config.c:
mvdir
storage/bdb/os_vxworks/os_vx_map.c:
mvdir
storage/bdb/os_win32/os_abs.c:
mvdir
storage/bdb/os_win32/os_clock.c:
mvdir
storage/bdb/os_win32/os_config.c:
mvdir
storage/bdb/os_win32/os_dir.c:
mvdir
storage/bdb/os_win32/os_errno.c:
mvdir
storage/bdb/os_win32/os_fid.c:
mvdir
storage/bdb/os_win32/os_fsync.c:
mvdir
storage/bdb/os_win32/os_handle.c:
mvdir
storage/bdb/os_win32/os_map.c:
mvdir
storage/bdb/os_win32/os_open.c:
mvdir
storage/bdb/os_win32/os_rename.c:
mvdir
storage/bdb/os_win32/os_rw.c:
mvdir
storage/bdb/os_win32/os_seek.c:
mvdir
storage/bdb/os_win32/os_sleep.c:
mvdir
storage/bdb/os_win32/os_spin.c:
mvdir
storage/bdb/os_win32/os_stat.c:
mvdir
storage/bdb/os_win32/os_type.c:
mvdir
storage/bdb/perl/BerkeleyDB/BerkeleyDB.pm:
mvdir
storage/bdb/perl/BerkeleyDB/BerkeleyDB.pod.P:
mvdir
storage/bdb/perl/BerkeleyDB/BerkeleyDB.pod:
mvdir
storage/bdb/perl/BerkeleyDB/BerkeleyDB.xs:
mvdir
storage/bdb/perl/BerkeleyDB/Changes:
mvdir
storage/bdb/perl/BerkeleyDB/MANIFEST:
mvdir
storage/bdb/perl/BerkeleyDB/Makefile.PL:
mvdir
storage/bdb/perl/BerkeleyDB/README:
mvdir
storage/bdb/perl/BerkeleyDB/Todo:
mvdir
storage/bdb/perl/BerkeleyDB/config.in:
mvdir
storage/bdb/perl/BerkeleyDB/constants.h:
mvdir
storage/bdb/perl/BerkeleyDB/constants.xs:
mvdir
storage/bdb/perl/BerkeleyDB/dbinfo:
mvdir
storage/bdb/perl/BerkeleyDB/mkconsts:
mvdir
storage/bdb/perl/BerkeleyDB/mkpod:
mvdir
storage/bdb/perl/BerkeleyDB/BerkeleyDB/Btree.pm:
mvdir
storage/bdb/perl/BerkeleyDB/BerkeleyDB/Hash.pm:
mvdir
storage/bdb/perl/BerkeleyDB/hints/dec_osf.pl:
mvdir
storage/bdb/perl/BerkeleyDB/hints/irix_6_5.pl:
mvdir
storage/bdb/perl/BerkeleyDB/hints/solaris.pl:
mvdir
storage/bdb/perl/BerkeleyDB/patches/5.004_01:
mvdir
storage/bdb/perl/BerkeleyDB/patches/5.004_02:
mvdir
storage/bdb/perl/BerkeleyDB/patches/5.004_03:
mvdir
storage/bdb/perl/BerkeleyDB/patches/5.004_04:
mvdir
storage/bdb/perl/BerkeleyDB/patches/5.004_05:
mvdir
storage/bdb/perl/BerkeleyDB/patches/5.004:
mvdir
storage/bdb/perl/BerkeleyDB/patches/5.005_01:
mvdir
storage/bdb/perl/BerkeleyDB/patches/5.005_02:
mvdir
storage/bdb/perl/BerkeleyDB/patches/5.005_03:
mvdir
storage/bdb/perl/BerkeleyDB/patches/5.005:
mvdir
storage/bdb/perl/BerkeleyDB/patches/5.6.0:
mvdir
storage/bdb/perl/BerkeleyDB/ppport.h:
mvdir
storage/bdb/perl/BerkeleyDB/scan:
mvdir
storage/bdb/perl/BerkeleyDB/t/btree.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/destroy.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/env.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/examples.t.T:
mvdir
storage/bdb/perl/BerkeleyDB/t/examples.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/examples3.t.T:
mvdir
storage/bdb/perl/BerkeleyDB/t/examples3.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/filter.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/hash.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/join.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/mldbm.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/queue.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/recno.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/strict.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/subdb.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/txn.t:
mvdir
storage/bdb/perl/BerkeleyDB/typemap:
mvdir
storage/bdb/perl/BerkeleyDB/t/unknown.t:
mvdir
storage/bdb/perl/BerkeleyDB/t/util.pm:
mvdir
storage/bdb/perl/DB_File/Changes:
mvdir
storage/bdb/perl/DB_File/DB_File.pm:
mvdir
storage/bdb/perl/DB_File/DB_File.xs:
mvdir
storage/bdb/perl/DB_File/DB_File_BS:
mvdir
storage/bdb/perl/DB_File/MANIFEST:
mvdir
storage/bdb/perl/DB_File/Makefile.PL:
mvdir
storage/bdb/perl/DB_File/README:
mvdir
storage/bdb/perl/DB_File/config.in:
mvdir
storage/bdb/perl/DB_File/dbinfo:
mvdir
storage/bdb/perl/DB_File/fallback.h:
mvdir
storage/bdb/perl/DB_File/fallback.xs:
mvdir
storage/bdb/perl/DB_File/hints/dynixptx.pl:
mvdir
storage/bdb/perl/DB_File/hints/sco.pl:
mvdir
storage/bdb/perl/DB_File/patches/5.004_01:
mvdir
storage/bdb/perl/DB_File/patches/5.004_02:
mvdir
storage/bdb/perl/DB_File/patches/5.004_03:
mvdir
storage/bdb/perl/DB_File/patches/5.004_04:
mvdir
storage/bdb/perl/DB_File/patches/5.004_05:
mvdir
storage/bdb/perl/DB_File/patches/5.004:
mvdir
storage/bdb/perl/DB_File/patches/5.005_01:
mvdir
storage/bdb/perl/DB_File/patches/5.005_02:
mvdir
storage/bdb/perl/DB_File/patches/5.005_03:
mvdir
storage/bdb/perl/DB_File/patches/5.005:
mvdir
storage/bdb/perl/DB_File/patches/5.6.0:
mvdir
storage/bdb/perl/DB_File/ppport.h:
mvdir
storage/bdb/perl/DB_File/t/db-btree.t:
mvdir
storage/bdb/perl/DB_File/t/db-hash.t:
mvdir
storage/bdb/perl/DB_File/t/db-recno.t:
mvdir
storage/bdb/perl/DB_File/typemap:
mvdir
storage/bdb/perl/DB_File/version.c:
mvdir
storage/bdb/qam/qam.c:
mvdir
storage/bdb/qam/qam.src:
mvdir
storage/bdb/qam/qam_conv.c:
mvdir
storage/bdb/qam/qam_files.c:
mvdir
storage/bdb/qam/qam_method.c:
mvdir
storage/bdb/qam/qam_open.c:
mvdir
storage/bdb/qam/qam_rec.c:
mvdir
storage/bdb/qam/qam_stat.c:
mvdir
storage/bdb/qam/qam_upgrade.c:
mvdir
storage/bdb/qam/qam_verify.c:
mvdir
storage/bdb/rep/rep_method.c:
mvdir
storage/bdb/rep/rep_record.c:
mvdir
storage/bdb/rep/rep_region.c:
mvdir
storage/bdb/rep/rep_util.c:
mvdir
storage/bdb/rpc_client/client.c:
mvdir
storage/bdb/rpc_client/gen_client_ret.c:
mvdir
storage/bdb/rpc_server/c/db_server_proc.c.in:
mvdir
storage/bdb/rpc_server/c/db_server_util.c:
mvdir
storage/bdb/rpc_server/clsrv.html:
mvdir
storage/bdb/rpc_server/cxx/db_server_cxxproc.cpp:
mvdir
storage/bdb/rpc_server/cxx/db_server_cxxutil.cpp:
mvdir
storage/bdb/rpc_server/java/DbDispatcher.java:
mvdir
storage/bdb/rpc_server/java/DbServer.java:
mvdir
storage/bdb/rpc_server/java/FreeList.java:
mvdir
storage/bdb/rpc_server/java/LocalIterator.java:
mvdir
storage/bdb/rpc_server/java/README:
mvdir
storage/bdb/rpc_server/java/RpcDb.java:
mvdir
storage/bdb/rpc_server/java/RpcDbEnv.java:
mvdir
storage/bdb/rpc_server/java/RpcDbTxn.java:
mvdir
storage/bdb/rpc_server/java/RpcDbc.java:
mvdir
storage/bdb/rpc_server/java/Timer.java:
mvdir
storage/bdb/rpc_server/java/jrpcgen.jar:
mvdir
storage/bdb/rpc_server/java/oncrpc.jar:
mvdir
storage/bdb/rpc_server/rpc.src:
mvdir
storage/bdb/rpc_server/java/gen/DbServerStub.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_associate_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_associate_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_bt_maxkey_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_bt_maxkey_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_bt_minkey_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_bt_minkey_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_close_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_close_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_create_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_create_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_cursor_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_cursor_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_del_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_del_reply.java:
mvdir
storage/bdb/rpc_server/java/s_jrpcgen:
mvdir
storage/bdb/rpc_server/java/gen/__db_encrypt_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_encrypt_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_extentsize_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_extentsize_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_flags_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_flags_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_get_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_get_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_h_ffactor_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_h_ffactor_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_h_nelem_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_h_nelem_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_join_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_join_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_key_range_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_key_range_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_lorder_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_lorder_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_open_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_open_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_pagesize_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_pagesize_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_pget_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_pget_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_put_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_put_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_re_delim_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_re_delim_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_re_len_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_re_len_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_re_pad_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_re_pad_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_remove_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_remove_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_rename_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_rename_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_stat_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_stat_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_sync_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_sync_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_truncate_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__db_truncate_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_close_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_close_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_count_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_count_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_del_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_del_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_dup_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_dup_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_get_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_get_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_pget_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_pget_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_put_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__dbc_put_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_cachesize_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_cachesize_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_close_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_close_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_create_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_create_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_dbremove_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_dbremove_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_dbrename_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_dbrename_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_encrypt_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_encrypt_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_flags_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_flags_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_open_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_open_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_remove_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__env_remove_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__txn_abort_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__txn_abort_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__txn_begin_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__txn_begin_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__txn_commit_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__txn_commit_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__txn_discard_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__txn_discard_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__txn_prepare_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__txn_prepare_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/__txn_recover_msg.java:
mvdir
storage/bdb/rpc_server/java/gen/__txn_recover_reply.java:
mvdir
storage/bdb/rpc_server/java/gen/db_server.java:
mvdir
storage/bdb/tcl/tcl_compat.c:
mvdir
storage/bdb/tcl/tcl_db.c:
mvdir
storage/bdb/tcl/tcl_db_pkg.c:
mvdir
storage/bdb/tcl/docs/db.html:
mvdir
storage/bdb/tcl/docs/env.html:
mvdir
storage/bdb/tcl/docs/historic.html:
mvdir
storage/bdb/tcl/docs/index.html:
mvdir
storage/bdb/tcl/docs/library.html:
mvdir
storage/bdb/tcl/docs/lock.html:
mvdir
storage/bdb/tcl/docs/log.html:
mvdir
storage/bdb/tcl/docs/mpool.html:
mvdir
storage/bdb/tcl/docs/rep.html:
mvdir
storage/bdb/tcl/docs/test.html:
mvdir
storage/bdb/tcl/docs/txn.html:
mvdir
storage/bdb/tcl/tcl_dbcursor.c:
mvdir
storage/bdb/tcl/tcl_env.c:
mvdir
storage/bdb/tcl/tcl_internal.c:
mvdir
storage/bdb/tcl/tcl_lock.c:
mvdir
storage/bdb/tcl/tcl_log.c:
mvdir
storage/bdb/tcl/tcl_mp.c:
mvdir
storage/bdb/tcl/tcl_rep.c:
mvdir
storage/bdb/tcl/tcl_txn.c:
mvdir
storage/bdb/tcl/tcl_util.c:
mvdir
storage/bdb/test/archive.tcl:
mvdir
storage/bdb/test/bigfile001.tcl:
mvdir
storage/bdb/test/bigfile002.tcl:
mvdir
storage/bdb/test/byteorder.tcl:
mvdir
storage/bdb/test/conscript.tcl:
mvdir
storage/bdb/test/dbm.tcl:
mvdir
storage/bdb/test/dbscript.tcl:
mvdir
storage/bdb/test/ddoyscript.tcl:
mvdir
storage/bdb/test/ddscript.tcl:
mvdir
storage/bdb/test/dead001.tcl:
mvdir
storage/bdb/test/dead002.tcl:
mvdir
storage/bdb/test/dead003.tcl:
mvdir
storage/bdb/test/dead004.tcl:
mvdir
storage/bdb/test/dead005.tcl:
mvdir
storage/bdb/test/dead006.tcl:
mvdir
storage/bdb/test/dead007.tcl:
mvdir
storage/bdb/test/env001.tcl:
mvdir
storage/bdb/test/env002.tcl:
mvdir
storage/bdb/test/env003.tcl:
mvdir
storage/bdb/test/env004.tcl:
mvdir
storage/bdb/test/env005.tcl:
mvdir
storage/bdb/test/env006.tcl:
mvdir
storage/bdb/test/env007.tcl:
mvdir
storage/bdb/test/env008.tcl:
mvdir
storage/bdb/test/env009.tcl:
mvdir
storage/bdb/test/env010.tcl:
mvdir
storage/bdb/test/env011.tcl:
mvdir
storage/bdb/test/hsearch.tcl:
mvdir
storage/bdb/test/join.tcl:
mvdir
storage/bdb/test/lock001.tcl:
mvdir
storage/bdb/test/lock002.tcl:
mvdir
storage/bdb/test/lock003.tcl:
mvdir
storage/bdb/test/lock004.tcl:
mvdir
storage/bdb/test/lock005.tcl:
mvdir
storage/bdb/test/lockscript.tcl:
mvdir
storage/bdb/test/log001.tcl:
mvdir
storage/bdb/test/log002.tcl:
mvdir
storage/bdb/test/log003.tcl:
mvdir
storage/bdb/test/log004.tcl:
mvdir
storage/bdb/test/log005.tcl:
mvdir
storage/bdb/test/logtrack.tcl:
mvdir
storage/bdb/test/mdbscript.tcl:
mvdir
storage/bdb/test/memp001.tcl:
mvdir
storage/bdb/test/memp002.tcl:
mvdir
storage/bdb/test/memp003.tcl:
mvdir
storage/bdb/test/mpoolscript.tcl:
mvdir
storage/bdb/test/mutex001.tcl:
mvdir
storage/bdb/test/mutex002.tcl:
mvdir
storage/bdb/test/mutex003.tcl:
mvdir
storage/bdb/test/mutexscript.tcl:
mvdir
storage/bdb/test/ndbm.tcl:
mvdir
storage/bdb/test/parallel.tcl:
mvdir
storage/bdb/test/recd001.tcl:
mvdir
storage/bdb/test/recd002.tcl:
mvdir
storage/bdb/test/recd003.tcl:
mvdir
storage/bdb/test/recd004.tcl:
mvdir
storage/bdb/test/recd005.tcl:
mvdir
storage/bdb/test/recd006.tcl:
mvdir
storage/bdb/test/recd007.tcl:
mvdir
storage/bdb/test/recd008.tcl:
mvdir
storage/bdb/test/recd009.tcl:
mvdir
storage/bdb/test/recd010.tcl:
mvdir
storage/bdb/test/recd011.tcl:
mvdir
storage/bdb/test/recd012.tcl:
mvdir
storage/bdb/test/recd013.tcl:
mvdir
storage/bdb/test/recd014.tcl:
mvdir
storage/bdb/test/recd015.tcl:
mvdir
storage/bdb/test/recd016.tcl:
mvdir
storage/bdb/test/recd017.tcl:
mvdir
storage/bdb/test/recd018.tcl:
mvdir
storage/bdb/test/recd019.tcl:
mvdir
storage/bdb/test/recd020.tcl:
mvdir
storage/bdb/test/recd15scr.tcl:
mvdir
storage/bdb/test/recdscript.tcl:
mvdir
storage/bdb/test/rep001.tcl:
mvdir
storage/bdb/test/rep002.tcl:
mvdir
storage/bdb/test/rep003.tcl:
mvdir
storage/bdb/test/rep004.tcl:
mvdir
storage/bdb/test/rep005.tcl:
mvdir
storage/bdb/test/reputils.tcl:
mvdir
storage/bdb/test/rpc001.tcl:
mvdir
storage/bdb/test/rpc002.tcl:
mvdir
storage/bdb/test/rpc003.tcl:
mvdir
storage/bdb/test/rpc004.tcl:
mvdir
storage/bdb/test/rpc005.tcl:
mvdir
storage/bdb/test/rsrc001.tcl:
mvdir
storage/bdb/test/rsrc002.tcl:
mvdir
storage/bdb/test/rsrc003.tcl:
mvdir
storage/bdb/test/rsrc004.tcl:
mvdir
storage/bdb/test/sdb001.tcl:
mvdir
storage/bdb/test/sdb002.tcl:
mvdir
storage/bdb/test/sdb003.tcl:
mvdir
storage/bdb/test/sdb004.tcl:
mvdir
storage/bdb/test/sdb005.tcl:
mvdir
storage/bdb/test/sdb006.tcl:
mvdir
storage/bdb/test/sdb007.tcl:
mvdir
storage/bdb/test/sdb008.tcl:
mvdir
storage/bdb/test/sdb009.tcl:
mvdir
storage/bdb/test/sdb010.tcl:
mvdir
storage/bdb/test/sdb011.tcl:
mvdir
storage/bdb/test/sdb012.tcl:
mvdir
storage/bdb/test/sdbscript.tcl:
mvdir
storage/bdb/test/sdbtest001.tcl:
mvdir
storage/bdb/test/sdbtest002.tcl:
mvdir
storage/bdb/test/sdbutils.tcl:
mvdir
storage/bdb/test/sec001.tcl:
mvdir
storage/bdb/test/sec002.tcl:
mvdir
storage/bdb/test/shelltest.tcl:
mvdir
storage/bdb/test/si001.tcl:
mvdir
storage/bdb/test/si002.tcl:
mvdir
storage/bdb/test/si003.tcl:
mvdir
storage/bdb/test/si004.tcl:
mvdir
storage/bdb/test/si005.tcl:
mvdir
storage/bdb/test/si006.tcl:
mvdir
storage/bdb/test/sindex.tcl:
mvdir
storage/bdb/test/sysscript.tcl:
mvdir
storage/bdb/test/test.tcl:
mvdir
storage/bdb/test/test001.tcl:
mvdir
storage/bdb/test/test002.tcl:
mvdir
storage/bdb/test/test003.tcl:
mvdir
storage/bdb/test/test004.tcl:
mvdir
storage/bdb/test/test005.tcl:
mvdir
storage/bdb/test/test006.tcl:
mvdir
storage/bdb/test/test007.tcl:
mvdir
storage/bdb/test/test008.tcl:
mvdir
storage/bdb/test/test009.tcl:
mvdir
storage/bdb/test/test010.tcl:
mvdir
storage/bdb/test/test011.tcl:
mvdir
storage/bdb/test/test012.tcl:
mvdir
storage/bdb/test/test013.tcl:
mvdir
storage/bdb/test/test014.tcl:
mvdir
storage/bdb/test/test015.tcl:
mvdir
storage/bdb/test/test016.tcl:
mvdir
storage/bdb/test/test017.tcl:
mvdir
storage/bdb/test/test018.tcl:
mvdir
storage/bdb/test/test019.tcl:
mvdir
storage/bdb/test/test020.tcl:
mvdir
storage/bdb/test/test021.tcl:
mvdir
storage/bdb/test/test022.tcl:
mvdir
storage/bdb/test/test023.tcl:
mvdir
storage/bdb/test/test024.tcl:
mvdir
storage/bdb/test/test025.tcl:
mvdir
storage/bdb/test/test026.tcl:
mvdir
storage/bdb/test/test027.tcl:
mvdir
storage/bdb/test/test028.tcl:
mvdir
storage/bdb/test/test029.tcl:
mvdir
storage/bdb/test/test030.tcl:
mvdir
storage/bdb/test/test031.tcl:
mvdir
storage/bdb/test/test032.tcl:
mvdir
storage/bdb/test/test033.tcl:
mvdir
storage/bdb/test/test034.tcl:
mvdir
storage/bdb/test/test035.tcl:
mvdir
storage/bdb/test/test036.tcl:
mvdir
storage/bdb/test/test037.tcl:
mvdir
storage/bdb/test/test038.tcl:
mvdir
storage/bdb/test/test039.tcl:
mvdir
storage/bdb/test/test040.tcl:
mvdir
storage/bdb/test/test041.tcl:
mvdir
storage/bdb/test/test042.tcl:
mvdir
storage/bdb/test/test043.tcl:
mvdir
storage/bdb/test/test044.tcl:
mvdir
storage/bdb/test/test045.tcl:
mvdir
storage/bdb/test/test046.tcl:
mvdir
storage/bdb/test/test047.tcl:
mvdir
storage/bdb/test/test048.tcl:
mvdir
storage/bdb/test/test049.tcl:
mvdir
storage/bdb/test/test050.tcl:
mvdir
storage/bdb/test/test051.tcl:
mvdir
storage/bdb/test/test052.tcl:
mvdir
storage/bdb/test/test053.tcl:
mvdir
storage/bdb/test/test054.tcl:
mvdir
storage/bdb/test/test055.tcl:
mvdir
storage/bdb/test/test056.tcl:
mvdir
storage/bdb/test/test057.tcl:
mvdir
storage/bdb/test/test058.tcl:
mvdir
storage/bdb/test/test059.tcl:
mvdir
storage/bdb/test/test060.tcl:
mvdir
storage/bdb/test/test061.tcl:
mvdir
storage/bdb/test/test062.tcl:
mvdir
storage/bdb/test/test063.tcl:
mvdir
storage/bdb/test/test064.tcl:
mvdir
storage/bdb/test/test065.tcl:
mvdir
storage/bdb/test/test066.tcl:
mvdir
storage/bdb/test/test067.tcl:
mvdir
storage/bdb/test/test068.tcl:
mvdir
storage/bdb/test/test069.tcl:
mvdir
storage/bdb/test/test070.tcl:
mvdir
storage/bdb/test/test071.tcl:
mvdir
storage/bdb/test/test072.tcl:
mvdir
storage/bdb/test/test073.tcl:
mvdir
storage/bdb/test/test074.tcl:
mvdir
storage/bdb/test/test075.tcl:
mvdir
storage/bdb/test/test076.tcl:
mvdir
storage/bdb/test/test077.tcl:
mvdir
storage/bdb/test/test078.tcl:
mvdir
storage/bdb/test/test079.tcl:
mvdir
storage/bdb/test/test080.tcl:
mvdir
storage/bdb/test/test081.tcl:
mvdir
storage/bdb/test/test082.tcl:
mvdir
storage/bdb/test/test083.tcl:
mvdir
storage/bdb/test/test084.tcl:
mvdir
storage/bdb/test/test085.tcl:
mvdir
storage/bdb/test/test086.tcl:
mvdir
storage/bdb/test/test087.tcl:
mvdir
storage/bdb/test/test088.tcl:
mvdir
storage/bdb/test/test089.tcl:
mvdir
storage/bdb/test/test090.tcl:
mvdir
storage/bdb/test/test091.tcl:
mvdir
storage/bdb/test/test092.tcl:
mvdir
storage/bdb/test/test093.tcl:
mvdir
storage/bdb/test/test094.tcl:
mvdir
storage/bdb/test/test095.tcl:
mvdir
storage/bdb/test/test096.tcl:
mvdir
storage/bdb/test/test097.tcl:
mvdir
storage/bdb/test/test098.tcl:
mvdir
storage/bdb/test/test099.tcl:
mvdir
storage/bdb/test/test100.tcl:
mvdir
storage/bdb/test/test101.tcl:
mvdir
storage/bdb/test/testparams.tcl:
mvdir
storage/bdb/test/testutils.tcl:
mvdir
storage/bdb/test/txn001.tcl:
mvdir
storage/bdb/test/txn002.tcl:
mvdir
storage/bdb/test/txn003.tcl:
mvdir
storage/bdb/test/txn004.tcl:
mvdir
storage/bdb/test/txn005.tcl:
mvdir
storage/bdb/test/txn006.tcl:
mvdir
storage/bdb/test/txn007.tcl:
mvdir
storage/bdb/test/txn008.tcl:
mvdir
storage/bdb/test/txn009.tcl:
mvdir
storage/bdb/test/txnscript.tcl:
mvdir
storage/bdb/test/update.tcl:
mvdir
storage/bdb/test/scr001/chk.code:
mvdir
storage/bdb/test/scr002/chk.def:
mvdir
storage/bdb/test/scr003/chk.define:
mvdir
storage/bdb/test/scr004/chk.javafiles:
mvdir
storage/bdb/test/scr005/chk.nl:
mvdir
storage/bdb/test/scr006/chk.offt:
mvdir
storage/bdb/test/scr007/chk.proto:
mvdir
storage/bdb/test/scr008/chk.pubdef:
mvdir
storage/bdb/test/scr009/chk.srcfiles:
mvdir
storage/bdb/test/scr010/chk.str:
mvdir
storage/bdb/test/scr010/spell.ok:
mvdir
storage/bdb/test/scr011/chk.tags:
mvdir
storage/bdb/test/scr012/chk.vx_code:
mvdir
storage/bdb/test/scr013/chk.stats:
mvdir
storage/bdb/test/scr014/chk.err:
mvdir
storage/bdb/test/scr015/README:
mvdir
storage/bdb/test/scr015/TestConstruct01.cpp:
mvdir
storage/bdb/test/scr015/TestConstruct01.testerr:
mvdir
storage/bdb/test/scr015/TestConstruct01.testout:
mvdir
storage/bdb/test/scr015/TestExceptInclude.cpp:
mvdir
storage/bdb/test/scr015/TestGetSetMethods.cpp:
mvdir
storage/bdb/test/scr015/TestKeyRange.cpp:
mvdir
storage/bdb/test/scr015/TestKeyRange.testin:
mvdir
storage/bdb/test/scr015/TestKeyRange.testout:
mvdir
storage/bdb/test/upgrade.tcl:
mvdir
storage/bdb/test/wordlist:
mvdir
storage/bdb/test/wrap.tcl:
mvdir
storage/bdb/test/scr015/TestLogc.cpp:
mvdir
storage/bdb/test/scr015/TestLogc.testout:
mvdir
storage/bdb/test/scr015/TestSimpleAccess.cpp:
mvdir
storage/bdb/test/scr015/TestSimpleAccess.testout:
mvdir
storage/bdb/test/scr015/TestTruncate.cpp:
mvdir
storage/bdb/test/scr015/TestTruncate.testout:
mvdir
storage/bdb/test/scr015/chk.cxxtests:
mvdir
storage/bdb/test/scr015/ignore:
mvdir
storage/bdb/test/scr015/testall:
mvdir
storage/bdb/test/scr015/testone:
mvdir
storage/bdb/test/scr016/CallbackTest.java:
mvdir
storage/bdb/test/scr016/CallbackTest.testout:
mvdir
storage/bdb/test/scr016/README:
mvdir
storage/bdb/test/scr016/TestAppendRecno.java:
mvdir
storage/bdb/test/scr016/TestAppendRecno.testout:
mvdir
storage/bdb/test/scr016/TestAssociate.java:
mvdir
storage/bdb/test/scr016/TestAssociate.testout:
mvdir
storage/bdb/test/scr016/TestClosedDb.java:
mvdir
storage/bdb/test/scr016/TestClosedDb.testout:
mvdir
storage/bdb/test/scr016/TestConstruct01.java:
mvdir
storage/bdb/test/scr016/TestConstruct01.testerr:
mvdir
storage/bdb/test/scr016/TestConstruct01.testout:
mvdir
storage/bdb/test/scr016/TestConstruct02.java:
mvdir
storage/bdb/test/scr016/TestConstruct02.testout:
mvdir
storage/bdb/test/scr016/TestDbtFlags.java:
mvdir
storage/bdb/test/scr016/TestDbtFlags.testerr:
mvdir
storage/bdb/test/scr016/TestDbtFlags.testout:
mvdir
storage/bdb/test/scr016/TestGetSetMethods.java:
mvdir
storage/bdb/test/scr016/TestKeyRange.java:
mvdir
storage/bdb/test/scr016/TestKeyRange.testout:
mvdir
storage/bdb/test/scr016/TestLockVec.java:
mvdir
storage/bdb/test/scr016/TestLockVec.testout:
mvdir
storage/bdb/test/scr016/TestLogc.java:
mvdir
storage/bdb/test/scr016/TestLogc.testout:
mvdir
storage/bdb/test/scr016/TestOpenEmpty.java:
mvdir
storage/bdb/test/scr016/TestOpenEmpty.testerr:
mvdir
storage/bdb/test/scr016/TestReplication.java:
mvdir
storage/bdb/test/scr016/TestRpcServer.java:
mvdir
storage/bdb/test/scr016/TestSameDbt.java:
mvdir
storage/bdb/test/scr016/TestSameDbt.testout:
mvdir
storage/bdb/test/scr016/TestSimpleAccess.java:
mvdir
storage/bdb/test/scr016/TestSimpleAccess.testout:
mvdir
storage/bdb/test/scr016/TestStat.java:
mvdir
storage/bdb/test/scr016/TestStat.testout:
mvdir
storage/bdb/test/scr016/TestTruncate.java:
mvdir
storage/bdb/test/scr016/TestTruncate.testout:
mvdir
storage/bdb/test/scr016/TestUtil.java:
mvdir
storage/bdb/test/scr016/TestXAServlet.java:
mvdir
storage/bdb/test/scr016/chk.javatests:
mvdir
storage/bdb/test/scr016/ignore:
mvdir
storage/bdb/test/scr016/testall:
mvdir
storage/bdb/test/scr016/testone:
mvdir
storage/bdb/test/scr017/O.BH:
mvdir
storage/bdb/test/scr017/O.R:
mvdir
storage/bdb/test/scr017/chk.db185:
mvdir
storage/bdb/test/scr017/t.c:
mvdir
storage/bdb/test/scr018/chk.comma:
mvdir
storage/bdb/test/scr018/t.c:
mvdir
storage/bdb/test/scr019/chk.include:
mvdir
storage/bdb/test/scr020/chk.inc:
mvdir
storage/bdb/test/scr021/chk.flags:
mvdir
storage/bdb/test/scr022/chk.rr:
mvdir
storage/bdb/txn/txn.c:
mvdir
storage/bdb/txn/txn.src:
mvdir
storage/bdb/txn/txn_method.c:
mvdir
storage/bdb/txn/txn_rec.c:
mvdir
storage/bdb/txn/txn_recover.c:
mvdir
storage/bdb/txn/txn_region.c:
mvdir
storage/bdb/txn/txn_stat.c:
mvdir
storage/bdb/txn/txn_util.c:
mvdir
storage/bdb/xa/xa.c:
mvdir
storage/bdb/xa/xa_db.c:
mvdir
storage/bdb/xa/xa_map.c:
mvdir
Diffstat (limited to 'myisam')
87 files changed, 0 insertions, 35173 deletions
diff --git a/myisam/.cvsignore b/myisam/.cvsignore deleted file mode 100644 index ef6d92c6e18..00000000000 --- a/myisam/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -ft_eval -ft_test1 -mi_test1 -mi_test2 -mi_test3 -rt_test -sp_test -myisamchk -myisamlog -myisampack diff --git a/myisam/ChangeLog b/myisam/ChangeLog deleted file mode 100644 index 504202be43f..00000000000 --- a/myisam/ChangeLog +++ /dev/null @@ -1,150 +0,0 @@ -2000-11-27 Michael Widenius <monty@mysql.com> - -* Changed mi_create.c to use less stack. - -2000-08-23 Michael Widenius <monty@mysql.com> - -* Fixed bug when comparing DECIMAL/NUMERIC key parts. - -2000-08-17 Michael Widenius <monty@mysql.com> - -* Add a new flag in share.staus so that we can quickly check if a table - is analyzed or not! - -2000-07-02 Michael Widenius <monty@mysql.com> - -* Added safety margin to guard against full index file. - -2000-05-22 Michael Widenius <monty@mysql.com> - -* Fixed that --join works with myisampack. - -2000-05-14 Michael Widenius <monty@mysql.com> - -* Don't lock datafile during myisamchk (only indexfile is locked; This is good - enough for all MyISAM functions); This made it possible to close datafile - in rep_by_sort(). - -2000-05-04 Michael Widenius <monty@mysql.com> - -* Fixed bug in code that scanned after rows in a crashed table. - This could cause an infinite loop when repairing tables. - -2000-04-26 Michael Widenius <monty@mysql.com> - -* Fixed bug when doing read_next after a delete/insert which balanced key - pages (In this case one internal buffer was wrongly reused) - -2000-04-21 Michael Widenius <monty@tik.pp.sci.fi> - -* Changed mi_find_halfpos() to return key, key_length and pos after key. -* Don't join or split key buffers in the middle when inserting a key - that is bigger than all other keys; This will improve inserts when - doing these in sorted order. - -2000-04-04 Michael Widenius <monty@mysql.com> - -* Added support for different languages on key part level. - -2000-02-23 Michael Widenius <monty@monty.pp.sci.fi> - -* Fixed that myisamchk works properly with RAID. - -2000-02-07 Michael Widenius <monty@tik.pp.sci.fi> - -* Added delete and rename of tables (works with RAID tables) - -2000-01-29 Michael Widenius <monty@monty.pp.sci.fi> - -* Fixed the sorting of index works with prefix-packed keys. - -1999-11-24 Michael Widenius <monty@monty.pp.sci.fi> - -* Fixed that DECIMAL() keys are sorted correct for negative numbers. - -1999-11-22 Michael Widenius <monty@monty.pp.sci.fi> - -* removed 'NO_LOCKING' macros. -* Added function mi_rnext_same -* Added support for concurrent reads. - -1999-11-05 Michael Widenius <monty@tik.pp.sci.fi> - -* Added function mi_scan(). -* Changed all functions to return error number in case of errors. - -1999-08-17 Michael Widenius <monty@tik.pp.sci.fi> - -* Added option DELAY_KEY_WRITE to tables and mi_open() - -1999-08-10 Michael Widenius <monty@tik.pp.sci.fi> - -* Added support of HA_READ_PREFIX_LAST to mi_rkey(). This finds the last - row with the given prefix. - -Mon Aug 2 13:54:35 1999 Michael Widenius <monty@bitch.pp.sci.fi> - -* Added data- and key-file-length to myisamchk. -* Fixed some problems with null and space packed keys. - -1999-07-15 Michael Widenius <monty@tik.pp.sci.fi> - -* The following options are for COUNT(DISTINCT ..) -* Added option HA_EXTRA_NO_ROWS; In this case only the index tree is updated -* Added mi_delete_all_rows() - -1999-07-13 Michael Widenius <monty@tik.pp.sci.fi> - -* Added special handling of tempoary tables - -1999-06-12 Michael Widenius <monty@monty.pp.sci.fi> - -* Added optional checksum for file and for each dynamic-length row -* Added unique constraint checking - -1999-05-06 Michael Widenius <monty@tik.pp.sci.fi> - -* All index blocks of the same size now share the same key block delete link - -1999-03-17 Michael Widenius <monty@monty.pp.sci.fi> - -* Different key packing code depending on if the first key part - is a variable length column (space packed, BLOB or VARCHAR) -* The create interface allows one to specify a key segment to start and - end one a specific bit. (The bit handling isn't yet implemented) -* Added more tests to 'test1' - -1999-03-16 Michael Widenius <monty@monty.pp.sci.fi> - -* Added option -m to myisamchk as an alternative to -e (-m is faster but - not as quite as safe as -e). -* Added option --fast to not check not changed tables. -* The first update will set a bit that the table has been changed. -* The first update to a table increments a 'open_count' field. This will - be reset on close. This will allow myisamchk to find tables that hasn't - been properly closed! -* Support for true VARCHAR columns - -1999-03-01 Michael Widenius <monty@monty.pp.sci.fi> - -* Dynamic length blocks are double linked to allow easy reallocation - of block lengths. This will help that the dynamic length data will not be - as fragmented as with ISAM. -* Extended mypack_isam to compress BLOB/TEXT columns. -* Allow keys on BLOB. - -1999-02-06 Michael Widenius <monty@monty.pp.sci.fi> - -* Keys, key pointers and all varibles in the index file are stored in - high-endian-order to get better compression. -* Allow NULL on keys - -1998-10-29 Michael Widenius <monty@monty.pp.sci.fi> - -* All data is stored in low-endian order - (This means that the files will be architecture and OS independent) -* All record numbers are now of type 'ha_rows' and file pointer are now of type - my_off_t. One can use files with 32-64 bit pointers with a 32bit or 64bit - record handling. - Currently the code is limited to 5 bytes pointers, but this is real easy - to change. diff --git a/myisam/Makefile.am b/myisam/Makefile.am deleted file mode 100644 index e77e46cb7a3..00000000000 --- a/myisam/Makefile.am +++ /dev/null @@ -1,108 +0,0 @@ -# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -EXTRA_DIST = mi_test_all.sh mi_test_all.res -pkgdata_DATA = mi_test_all mi_test_all.res - -INCLUDES = -I$(top_srcdir)/include -LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \ - $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/dbug/libdbug.a \ - $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ -pkglib_LIBRARIES = libmyisam.a -bin_PROGRAMS = myisamchk myisamlog myisampack myisam_ftdump -myisamchk_DEPENDENCIES= $(LIBRARIES) -myisamlog_DEPENDENCIES= $(LIBRARIES) -myisampack_DEPENDENCIES=$(LIBRARIES) -noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test #ft_test1 ft_eval -noinst_HEADERS = myisamdef.h rt_index.h rt_key.h rt_mbr.h sp_defs.h fulltext.h ftdefs.h ft_test1.h ft_eval.h -mi_test1_DEPENDENCIES= $(LIBRARIES) -mi_test2_DEPENDENCIES= $(LIBRARIES) -mi_test3_DEPENDENCIES= $(LIBRARIES) -#ft_test1_DEPENDENCIES= $(LIBRARIES) -#ft_eval_DEPENDENCIES= $(LIBRARIES) -myisam_ftdump_DEPENDENCIES= $(LIBRARIES) -rt_test_DEPENDENCIES= $(LIBRARIES) -sp_test_DEPENDENCIES= $(LIBRARIES) -libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \ - mi_rnext.c mi_rnext_same.c \ - mi_search.c mi_page.c mi_key.c mi_locking.c \ - mi_rrnd.c mi_scan.c mi_cache.c \ - mi_statrec.c mi_packrec.c mi_dynrec.c \ - mi_update.c mi_write.c mi_unique.c \ - mi_delete.c \ - mi_rprev.c mi_rfirst.c mi_rlast.c mi_rsame.c \ - mi_rsamepos.c mi_panic.c mi_close.c mi_create.c\ - mi_range.c mi_dbug.c mi_checksum.c mi_log.c \ - mi_changed.c mi_static.c mi_delete_all.c \ - mi_delete_table.c mi_rename.c mi_check.c \ - mi_keycache.c mi_preload.c \ - ft_parser.c ft_stopwords.c ft_static.c \ - ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c \ - rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c -CLEANFILES = test?.MY? FT?.MY? isam.log mi_test_all rt_test.MY? sp_test.MY? -DEFS = -DMAP_TO_USE_RAID - -# Move to automake rules ? -prolint:; plparse -b -u -hF1 "-width(0,0)" "-format=%f:%l:\s%t:%n\s%m" \ - "-elib(????)" "+elib(?3??)" my.lnt $(nisam_SOURCES) - -SUFFIXES = .sh - -.sh: - @RM@ -f $@ $@-t - @SED@ \ - -e 's!@''bindir''@!$(bindir)!g' \ - -e 's!@''scriptdir''@!$(bindir)!g' \ - -e 's!@''prefix''@!$(prefix)!g' \ - -e 's!@''datadir''@!$(datadir)!g' \ - -e 's!@''localstatedir''@!$(localstatedir)!g' \ - -e 's!@''libexecdir''@!$(libexecdir)!g' \ - -e 's!@''CC''@!@CC@!'\ - -e 's!@''CXX''@!@CXX@!'\ - -e 's!@''GXX''@!@GXX@!'\ - -e 's!@''PERL''@!@PERL@!' \ - -e 's!@''CFLAGS''@!@SAVE_CFLAGS@!'\ - -e 's!@''CXXFLAGS''@!@SAVE_CXXFLAGS@!'\ - -e 's!@''LDFLAGS''@!@SAVE_LDFLAGS@!'\ - -e 's!@''VERSION''@!@VERSION@!' \ - -e 's!@''MYSQL_SERVER_SUFFIX''@!@MYSQL_SERVER_SUFFIX@!' \ - -e 's!@''COMPILATION_COMMENT''@!@COMPILATION_COMMENT@!' \ - -e 's!@''MACHINE_TYPE''@!@MACHINE_TYPE@!' \ - -e 's!@''HOSTNAME''@!@HOSTNAME@!' \ - -e 's!@''SYSTEM_TYPE''@!@SYSTEM_TYPE@!' \ - -e 's!@''CHECK_PID''@!@CHECK_PID@!' \ - -e 's!@''FIND_PROC''@!@FIND_PROC@!' \ - -e 's!@''MYSQLD_DEFAULT_SWITCHES''@!@MYSQLD_DEFAULT_SWITCHES@!' \ - -e 's!@''MYSQL_UNIX_ADDR''@!@MYSQL_UNIX_ADDR@!' \ - -e 's!@''IS_LINUX''@!@IS_LINUX@!' \ - -e "s!@""CONF_COMMAND""@!@CONF_COMMAND@!" \ - -e 's!@''MYSQLD_USER''@!@MYSQLD_USER@!' \ - -e 's!@''sysconfdir''@!@sysconfdir@!' \ - -e 's!@''SHORT_MYSQL_INTRO''@!@SHORT_MYSQL_INTRO@!' \ - -e 's!@''SHARED_LIB_VERSION''@!@SHARED_LIB_VERSION@!' \ - -e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \ - -e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \ - -e 's!@''MYSQL_TCP_PORT''@!@MYSQL_TCP_PORT@!' \ - -e 's!@''PERL_DBI_VERSION''@!@PERL_DBI_VERSION@!' \ - -e 's!@''PERL_DBD_VERSION''@!@PERL_DBD_VERSION@!' \ - -e 's!@''PERL_DATA_DUMPER''@!@PERL_DATA_DUMPER@!' \ - $< > $@-t - @CHMOD@ +x $@-t - @MV@ $@-t $@ - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/myisam/NEWS b/myisam/NEWS deleted file mode 100644 index bb1f141610b..00000000000 --- a/myisam/NEWS +++ /dev/null @@ -1,66 +0,0 @@ -New features compared to NISAM: - -- All file positions have type my_off_t; This enables one to use big - files (2^63 byte) by defining my_off_t to be longlong on OS that supports - big files. -- When creating a table, one can now specify the maximum data file length. - This will be used to calculate the length of row pointers. -- All key segments have their own language definition. -- Some changes to support more types: - The biggest change is that the interface allows MY_ISAM will support - variable length integer types. (Only the interface is implemented) -- All data is stored with low byte first; This makes the data machine - independent. -- All number keys are stored with high byte first to give better packing. -- Support for a true VARCHAR type; A VARCHAR column starts with a length - stored on 2 bytes. -- Tables with VARCHAR may have fixed or dynamic record length. -- There are now 2 different ways to pack keys: - - If the first key part is a space stripped CHAR, a VARCHAR or a BLOB the - 'packed' method is used. This only prefix-compresses the first - key part. - - In other cases prefix packing is used (This also includes the record - pointer into the prefix packing). A key may in the best case be - packed on 2 bytes. -- VARCHAR and CHAR may be up to 65K -- Index on BLOB and VARCHAR. -- One can now have NULL in an index. This takes 0-1 bytes / key. -- MYISAM will allow one to specify one AUTO_INCREMENT column; MYISAM will - automaticly update this on INSERT/UPDATE. The AUTO_INCREMENT value can be - reset with myisamchk. -- Max key length will be 500 by default; In cases of longer keys than 250, - a bigger key block size than the default of 1024 byes is used for this key. -- Max number of keys enlarged to 32 as default. This can be enlarged to 64 - without having to recompile myisamchk. -- There is a flag in the MYISAM header that tells if the index file (.MYI) - was closed correctly. -- myisamchk will now mark tables as checked. 'myisamchk --fast' will only - check those tables that doesn't have this mark. -- 'myisamchk -a' stores statistic for key parts (and not only for whole keys - as in NISAM). -- Dynamic size rows will now be much less fragmented when mixing deletes with - update and insert. This is done by automaticly combine adjacent deleted - blocks and by extending blocks if the next block is deleted. -- For dynamic size rows, the delete link contains a pointer to itself - (to make repairs easier). -- myisampack (called pack_isam in NISAM) can pack BLOB and VARCHAR - columns. -- One can now disable any key from update; In NISAM one could only disable - the last x keys. -- One can have a UNIQUE constraint on anything (including BLOBS). - This is implemented by a key that contains a hashed number of the whole - record and before inserting a new record, MyISAM will check all records - with the same hash for dupplicates. -- When creating the table, one can define that MyISAM should maintain - a CRC for the whole table (to make isamchk even better). In the case of - dynamic size rows, one will in this case get 1 byte checksum for each row. - (This is a great help for debugging, but it can also be used to keep - MyISAM table 'extra' safe. -- Temporary tables will not write not flushed keys to file on close and - not wait on 'disk full' conditions. - -Interface changes compared to NISAM: - -- mi_create() - - keyinfo->seg must be allocated explicitely. - - One must put number of key segments in keyinfo diff --git a/myisam/TODO b/myisam/TODO deleted file mode 100644 index cad9486e1bb..00000000000 --- a/myisam/TODO +++ /dev/null @@ -1,7 +0,0 @@ -TODO: - -- Let packisam find the optimal way to store keys. -- kill when using 'myisamchk' should remove all temporary files. -- Text search index - (Sergei A. Golub is working on this) -- Add '%' packed to myisamchk for compressed tables with blobs. diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c deleted file mode 100644 index 530f0d56c4c..00000000000 --- a/myisam/ft_boolean_search.c +++ /dev/null @@ -1,735 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ - -/* TODO: add caching - pre-read several index entries at once */ - -#define FT_CORE -#include "ftdefs.h" - -/* search with boolean queries */ - -static double _wghts[11]= -{ - 0.131687242798354, - 0.197530864197531, - 0.296296296296296, - 0.444444444444444, - 0.666666666666667, - 1.000000000000000, - 1.500000000000000, - 2.250000000000000, - 3.375000000000000, - 5.062500000000000, - 7.593750000000000}; -static double *wghts=_wghts+5; /* wghts[i] = 1.5**i */ - -static double _nwghts[11]= -{ - -0.065843621399177, - -0.098765432098766, - -0.148148148148148, - -0.222222222222222, - -0.333333333333334, - -0.500000000000000, - -0.750000000000000, - -1.125000000000000, - -1.687500000000000, - -2.531250000000000, - -3.796875000000000}; -static double *nwghts=_nwghts+5; /* nwghts[i] = -0.5*1.5**i */ - -#define FTB_FLAG_TRUNC 1 -/* At most one of the following flags can be set */ -#define FTB_FLAG_YES 2 -#define FTB_FLAG_NO 4 -#define FTB_FLAG_WONLY 8 - -typedef struct st_ftb_expr FTB_EXPR; -struct st_ftb_expr -{ - FTB_EXPR *up; - uint flags; -/* ^^^^^^^^^^^^^^^^^^ FTB_{EXPR,WORD} common section */ - my_off_t docid[2]; - float weight; - float cur_weight; - LIST *phrase; /* phrase words */ - uint yesses; /* number of "yes" words matched */ - uint nos; /* number of "no" words matched */ - uint ythresh; /* number of "yes" words in expr */ - uint yweaks; /* number of "yes" words for scan only */ -}; - -typedef struct st_ftb_word -{ - FTB_EXPR *up; - uint flags; -/* ^^^^^^^^^^^^^^^^^^ FTB_{EXPR,WORD} common section */ - my_off_t docid[2]; /* for index search and for scan */ - my_off_t key_root; - MI_KEYDEF *keyinfo; - float weight; - uint ndepth; - uint len; - uchar off; - byte word[1]; -} FTB_WORD; - -typedef struct st_ft_info -{ - struct _ft_vft *please; - MI_INFO *info; - CHARSET_INFO *charset; - FTB_EXPR *root; - FTB_WORD **list; - MEM_ROOT mem_root; - QUEUE queue; - TREE no_dupes; - my_off_t lastpos; - uint keynr; - uchar with_scan; - enum { UNINITIALIZED, READY, INDEX_SEARCH, INDEX_DONE } state; -} FTB; - -static int FTB_WORD_cmp(my_off_t *v, FTB_WORD *a, FTB_WORD *b) -{ - int i; - - /* if a==curdoc, take it as a < b */ - if (v && a->docid[0] == *v) - return -1; - - /* ORDER BY docid, ndepth DESC */ - i=CMP_NUM(a->docid[0], b->docid[0]); - if (!i) - i=CMP_NUM(b->ndepth,a->ndepth); - return i; -} - -static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b) -{ - /* ORDER BY word DESC, ndepth DESC */ - int i= mi_compare_text(cs, (uchar*) (*b)->word+1,(*b)->len-1, - (uchar*) (*a)->word+1,(*a)->len-1,0,0); - if (!i) - i=CMP_NUM((*b)->ndepth,(*a)->ndepth); - return i; -} - -static void _ftb_parse_query(FTB *ftb, byte **start, byte *end, - FTB_EXPR *up, uint depth, byte *up_quot) -{ - byte res; - FTB_PARAM param; - FT_WORD w; - FTB_WORD *ftbw; - FTB_EXPR *ftbe; - FT_WORD *phrase_word; - LIST *phrase_list; - uint extra=HA_FT_WLEN+ftb->info->s->rec_reflength; /* just a shortcut */ - - if (ftb->state != UNINITIALIZED) - return; - - param.prev=' '; - param.quot= up_quot; - while ((res=ft_get_word(ftb->charset,start,end,&w,¶m))) - { - int r=param.plusminus; - float weight= (float) (param.pmsign ? nwghts : wghts)[(r>5)?5:((r<-5)?-5:r)]; - switch (res) { - case 1: /* word found */ - ftbw=(FTB_WORD *)alloc_root(&ftb->mem_root, - sizeof(FTB_WORD) + - (param.trunc ? MI_MAX_KEY_BUFF : - w.len*ftb->charset->mbmaxlen+extra)); - ftbw->len=w.len+1; - ftbw->flags=0; - ftbw->off=0; - if (param.yesno>0) ftbw->flags|=FTB_FLAG_YES; - if (param.yesno<0) ftbw->flags|=FTB_FLAG_NO; - if (param.trunc) ftbw->flags|=FTB_FLAG_TRUNC; - ftbw->weight=weight; - ftbw->up=up; - ftbw->docid[0]=ftbw->docid[1]=HA_OFFSET_ERROR; - ftbw->ndepth= (param.yesno<0) + depth; - ftbw->key_root=HA_OFFSET_ERROR; - memcpy(ftbw->word+1, w.pos, w.len); - ftbw->word[0]=w.len; - if (param.yesno > 0) up->ythresh++; - queue_insert(& ftb->queue, (byte *)ftbw); - ftb->with_scan|=(param.trunc & FTB_FLAG_TRUNC); - case 4: /* not indexed word (stopword or too short/long) */ - if (! up_quot) break; - phrase_word= (FT_WORD *)alloc_root(&ftb->mem_root, sizeof(FT_WORD)); - phrase_list= (LIST *)alloc_root(&ftb->mem_root, sizeof(LIST)); - phrase_word->pos= w.pos; - phrase_word->len= w.len; - phrase_list->data= (void *)phrase_word; - up->phrase= list_add(up->phrase, phrase_list); - break; - case 2: /* left bracket */ - ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR)); - ftbe->flags=0; - if (param.yesno>0) ftbe->flags|=FTB_FLAG_YES; - if (param.yesno<0) ftbe->flags|=FTB_FLAG_NO; - ftbe->weight=weight; - ftbe->up=up; - ftbe->ythresh=ftbe->yweaks=0; - ftbe->docid[0]=ftbe->docid[1]=HA_OFFSET_ERROR; - ftbe->phrase= NULL; - if (param.quot) ftb->with_scan|=2; - if (param.yesno > 0) up->ythresh++; - _ftb_parse_query(ftb, start, end, ftbe, depth+1, param.quot); - param.quot=0; - break; - case 3: /* right bracket */ - if (up_quot) up->phrase= list_reverse(up->phrase); - return; - } - } - return; -} - -static int _ftb_no_dupes_cmp(void* not_used __attribute__((unused)), - const void *a,const void *b) -{ - return CMP_NUM((*((my_off_t*)a)), (*((my_off_t*)b))); -} - -/* returns 1 if the search was finished (must-word wasn't found) */ -static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) -{ - int r; - int subkeys=1; - my_bool can_go_down; - MI_INFO *info=ftb->info; - uint off, extra=HA_FT_WLEN+info->s->base.rec_reflength; - byte *lastkey_buf=ftbw->word+ftbw->off; - - LINT_INIT(off); - if (ftbw->flags & FTB_FLAG_TRUNC) - lastkey_buf+=ftbw->len; - - if (init_search) - { - ftbw->key_root=info->s->state.key_root[ftb->keynr]; - ftbw->keyinfo=info->s->keyinfo+ftb->keynr; - - r=_mi_search(info, ftbw->keyinfo, (uchar*) ftbw->word, ftbw->len, - SEARCH_FIND | SEARCH_BIGGER, ftbw->key_root); - } - else - { - r=_mi_search(info, ftbw->keyinfo, (uchar*) lastkey_buf, - USE_WHOLE_KEY, SEARCH_BIGGER, ftbw->key_root); - } - - can_go_down=(!ftbw->off && (init_search || (ftbw->flags & FTB_FLAG_TRUNC))); - /* Skip rows inserted by concurrent insert */ - while (!r) - { - if (can_go_down) - { - /* going down ? */ - off=info->lastkey_length-extra; - subkeys=ft_sintXkorr(info->lastkey+off); - } - if (subkeys<0 || info->lastpos < info->state->data_file_length) - break; - r= _mi_search_next(info, ftbw->keyinfo, info->lastkey, - info->lastkey_length, - SEARCH_BIGGER, ftbw->key_root); - } - - if (!r && !ftbw->off) - { - r= mi_compare_text(ftb->charset, - info->lastkey+1, - info->lastkey_length-extra-1, - (uchar*) ftbw->word+1, - ftbw->len-1, - (my_bool) (ftbw->flags & FTB_FLAG_TRUNC),0); - } - - if (r) /* not found */ - { - if (!ftbw->off || !(ftbw->flags & FTB_FLAG_TRUNC)) - { - ftbw->docid[0]=HA_OFFSET_ERROR; - if ((ftbw->flags & FTB_FLAG_YES) && ftbw->up->up==0) - { - /* - This word MUST BE present in every document returned, - so we can stop the search right now - */ - ftb->state=INDEX_DONE; - return 1; /* search is done */ - } - else - return 0; - } - - /* going up to the first-level tree to continue search there */ - _mi_dpointer(info, (uchar*) (lastkey_buf+HA_FT_WLEN), ftbw->key_root); - ftbw->key_root=info->s->state.key_root[ftb->keynr]; - ftbw->keyinfo=info->s->keyinfo+ftb->keynr; - ftbw->off=0; - return _ft2_search(ftb, ftbw, 0); - } - - /* matching key found */ - memcpy(lastkey_buf, info->lastkey, info->lastkey_length); - if (lastkey_buf == ftbw->word) - ftbw->len=info->lastkey_length-extra; - - /* going down ? */ - if (subkeys<0) - { - /* - yep, going down, to the second-level tree - TODO here: subkey-based optimization - */ - ftbw->off=off; - ftbw->key_root=info->lastpos; - ftbw->keyinfo=& info->s->ft2_keyinfo; - r=_mi_search_first(info, ftbw->keyinfo, ftbw->key_root); - DBUG_ASSERT(r==0); /* found something */ - memcpy(lastkey_buf+off, info->lastkey, info->lastkey_length); - } - ftbw->docid[0]=info->lastpos; - return 0; -} - -static void _ftb_init_index_search(FT_INFO *ftb) -{ - int i; - FTB_WORD *ftbw; - - if ((ftb->state != READY && ftb->state !=INDEX_DONE) || - ftb->keynr == NO_SUCH_KEY) - return; - ftb->state=INDEX_SEARCH; - - for (i=ftb->queue.elements; i; i--) - { - ftbw=(FTB_WORD *)(ftb->queue.root[i]); - - if (ftbw->flags & FTB_FLAG_TRUNC) - { - /* - special treatment for truncation operator - 1. there are some (besides this) +words - | no need to search in the index, it can never ADD new rows - | to the result, and to remove half-matched rows we do scan anyway - 2. -trunc* - | same as 1. - 3. in 1 and 2, +/- need not be on the same expr. level, - but can be on any upper level, as in +word +(trunc1* trunc2*) - 4. otherwise - | We have to index-search for this prefix. - | It may cause duplicates, as in the index (sorted by <word,docid>) - | <aaaa,row1> - | <aabb,row2> - | <aacc,row1> - | Searching for "aa*" will find row1 twice... - */ - FTB_EXPR *ftbe; - for (ftbe=(FTB_EXPR*)ftbw; - ftbe->up && !(ftbe->up->flags & FTB_FLAG_TRUNC); - ftbe->up->flags|= FTB_FLAG_TRUNC, ftbe=ftbe->up) - { - if (ftbe->flags & FTB_FLAG_NO || /* 2 */ - ftbe->up->ythresh - ftbe->up->yweaks >1) /* 1 */ - { - FTB_EXPR *top_ftbe=ftbe->up; - ftbw->docid[0]=HA_OFFSET_ERROR; - for (ftbe=(FTB_EXPR *)ftbw; - ftbe != top_ftbe && !(ftbe->flags & FTB_FLAG_NO); - ftbe=ftbe->up) - ftbe->up->yweaks++; - ftbe=0; - break; - } - } - if (!ftbe) - continue; - /* 4 */ - if (!is_tree_inited(& ftb->no_dupes)) - init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t), - _ftb_no_dupes_cmp,0,0,0); - else - reset_tree(& ftb->no_dupes); - } - - ftbw->off=0; /* in case of reinit */ - if (_ft2_search(ftb, ftbw, 1)) - return; - } - queue_fix(& ftb->queue); -} - - -FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, - uint query_len, CHARSET_INFO *cs) -{ - FTB *ftb; - FTB_EXPR *ftbe; - uint res; - - if (!(ftb=(FTB *)my_malloc(sizeof(FTB), MYF(MY_WME)))) - return 0; - ftb->please= (struct _ft_vft *) & _ft_vft_boolean; - ftb->state=UNINITIALIZED; - ftb->info=info; - ftb->keynr=keynr; - ftb->charset=cs; - DBUG_ASSERT(keynr==NO_SUCH_KEY || cs == info->s->keyinfo[keynr].seg->charset); - ftb->with_scan=0; - ftb->lastpos=HA_OFFSET_ERROR; - bzero(& ftb->no_dupes, sizeof(TREE)); - - init_alloc_root(&ftb->mem_root, 1024, 1024); - - /* - Hack: instead of init_queue, we'll use reinit queue to be able - to alloc queue with alloc_root() - */ - res=ftb->queue.max_elements=1+query_len/(min(ft_min_word_len,2)+1); - if (!(ftb->queue.root= - (byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*)))) - goto err; - reinit_queue(& ftb->queue, res, 0, 0, - (int (*)(void*,byte*,byte*))FTB_WORD_cmp, 0); - if (!(ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR)))) - goto err; - ftbe->weight=1; - ftbe->flags=FTB_FLAG_YES; - ftbe->nos=1; - ftbe->up=0; - ftbe->ythresh=ftbe->yweaks=0; - ftbe->docid[0]=ftbe->docid[1]=HA_OFFSET_ERROR; - ftbe->phrase= NULL; - ftb->root=ftbe; - _ftb_parse_query(ftb, &query, query+query_len, ftbe, 0, NULL); - ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root, - sizeof(FTB_WORD *)*ftb->queue.elements); - memcpy(ftb->list, ftb->queue.root+1, sizeof(FTB_WORD *)*ftb->queue.elements); - qsort2(ftb->list, ftb->queue.elements, sizeof(FTB_WORD *), - (qsort2_cmp)FTB_WORD_cmp_list, ftb->charset); - if (ftb->queue.elements<2) ftb->with_scan &= ~FTB_FLAG_TRUNC; - ftb->state=READY; - return ftb; -err: - free_root(& ftb->mem_root, MYF(0)); - my_free((gptr)ftb,MYF(0)); - return 0; -} - - -/* - Checks if given buffer matches phrase list. - - SYNOPSIS - _ftb_check_phrase() - s0 start of buffer - e0 end of buffer - phrase broken into list phrase - cs charset info - - RETURN VALUE - 1 is returned if phrase found, 0 else. -*/ - -static int _ftb_check_phrase(const byte *s0, const byte *e0, - LIST *phrase, CHARSET_INFO *cs) -{ - FT_WORD h_word; - const byte *h_start= s0; - DBUG_ENTER("_ftb_strstr"); - DBUG_ASSERT(phrase); - - while (ft_simple_get_word(cs, (byte **)&h_start, e0, &h_word, FALSE)) - { - FT_WORD *n_word; - LIST *phrase_element= phrase; - const byte *h_start1= h_start; - for (;;) - { - n_word= (FT_WORD *)phrase_element->data; - if (my_strnncoll(cs, h_word.pos, h_word.len, n_word->pos, n_word->len)) - break; - if (! (phrase_element= phrase_element->next)) - DBUG_RETURN(1); - if (! ft_simple_get_word(cs, (byte **)&h_start1, e0, &h_word, FALSE)) - DBUG_RETURN(0); - } - } - DBUG_RETURN(0); -} - - -static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig) -{ - FT_SEG_ITERATOR ftsi; - FTB_EXPR *ftbe; - float weight=ftbw->weight; - int yn=ftbw->flags, ythresh, mode=(ftsi_orig != 0); - my_off_t curdoc=ftbw->docid[mode]; - - for (ftbe=ftbw->up; ftbe; ftbe=ftbe->up) - { - ythresh = ftbe->ythresh - (mode ? 0 : ftbe->yweaks); - if (ftbe->docid[mode] != curdoc) - { - ftbe->cur_weight=0; - ftbe->yesses=ftbe->nos=0; - ftbe->docid[mode]=curdoc; - } - if (ftbe->nos) - break; - if (yn & FTB_FLAG_YES) - { - weight /= ftbe->ythresh; - ftbe->cur_weight += weight; - if ((int) ++ftbe->yesses == ythresh) - { - yn=ftbe->flags; - weight=ftbe->cur_weight*ftbe->weight; - if (mode && ftbe->phrase) - { - int not_found=1; - - memcpy(&ftsi, ftsi_orig, sizeof(ftsi)); - while (_mi_ft_segiterator(&ftsi) && not_found) - { - if (!ftsi.pos) - continue; - not_found = ! _ftb_check_phrase(ftsi.pos, ftsi.pos+ftsi.len, - ftbe->phrase, ftb->charset); - } - if (not_found) break; - } /* ftbe->quot */ - } - else - break; - } - else - if (yn & FTB_FLAG_NO) - { - /* - NOTE: special sort function of queue assures that all - (yn & FTB_FLAG_NO) != 0 - events for every particular subexpression will - "auto-magically" happen BEFORE all the - (yn & FTB_FLAG_YES) != 0 events. So no - already matched expression can become not-matched again. - */ - ++ftbe->nos; - break; - } - else - { - if (ftbe->ythresh) - weight/=3; - ftbe->cur_weight += weight; - if ((int) ftbe->yesses < ythresh) - break; - if (!(yn & FTB_FLAG_WONLY)) - yn= ((int) ftbe->yesses++ == ythresh) ? ftbe->flags : FTB_FLAG_WONLY ; - weight*= ftbe->weight; - } - } -} - - -int ft_boolean_read_next(FT_INFO *ftb, char *record) -{ - FTB_EXPR *ftbe; - FTB_WORD *ftbw; - MI_INFO *info=ftb->info; - my_off_t curdoc; - - if (ftb->state != INDEX_SEARCH && ftb->state != INDEX_DONE) - return -1; - - /* black magic ON */ - if ((int) _mi_check_index(info, ftb->keynr) < 0) - return my_errno; - if (_mi_readinfo(info, F_RDLCK, 1)) - return my_errno; - /* black magic OFF */ - - if (!ftb->queue.elements) - return my_errno=HA_ERR_END_OF_FILE; - - /* Attention!!! Address of a local variable is used here! See err: label */ - ftb->queue.first_cmp_arg=(void *)&curdoc; - - while (ftb->state == INDEX_SEARCH && - (curdoc=((FTB_WORD *)queue_top(& ftb->queue))->docid[0]) != - HA_OFFSET_ERROR) - { - while (curdoc == (ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0]) - { - _ftb_climb_the_tree(ftb, ftbw, 0); - - /* update queue */ - _ft2_search(ftb, ftbw, 0); - queue_replaced(& ftb->queue); - } - - ftbe=ftb->root; - if (ftbe->docid[0]==curdoc && ftbe->cur_weight>0 && - ftbe->yesses>=(ftbe->ythresh-ftbe->yweaks) && !ftbe->nos) - { - /* curdoc matched ! */ - if (is_tree_inited(&ftb->no_dupes) && - tree_insert(&ftb->no_dupes, &curdoc, 0, - ftb->no_dupes.custom_arg)->count >1) - /* but it managed already to get past this line once */ - continue; - - info->lastpos=curdoc; - /* Clear all states, except that the table was updated */ - info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - - if (!(*info->read_record)(info,curdoc,record)) - { - info->update|= HA_STATE_AKTIV; /* Record is read */ - if (ftb->with_scan && ft_boolean_find_relevance(ftb,record,0)==0) - continue; /* no match */ - my_errno=0; - goto err; - } - goto err; - } - } - ftb->state=INDEX_DONE; - my_errno=HA_ERR_END_OF_FILE; -err: - ftb->queue.first_cmp_arg=(void *)0; - return my_errno; -} - - -float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) -{ - FT_WORD word; - FTB_WORD *ftbw; - FTB_EXPR *ftbe; - FT_SEG_ITERATOR ftsi, ftsi2; - const byte *end; - my_off_t docid=ftb->info->lastpos; - - if (docid == HA_OFFSET_ERROR) - return -2.0; - if (!ftb->queue.elements) - return 0; - - if (ftb->state != INDEX_SEARCH && docid <= ftb->lastpos) - { - FTB_EXPR *x; - uint i; - - for (i=0; i < ftb->queue.elements; i++) - { - ftb->list[i]->docid[1]=HA_OFFSET_ERROR; - for (x=ftb->list[i]->up; x; x=x->up) - x->docid[1]=HA_OFFSET_ERROR; - } - } - - ftb->lastpos=docid; - - if (ftb->keynr==NO_SUCH_KEY) - _mi_ft_segiterator_dummy_init(record, length, &ftsi); - else - _mi_ft_segiterator_init(ftb->info, ftb->keynr, record, &ftsi); - memcpy(&ftsi2, &ftsi, sizeof(ftsi)); - - while (_mi_ft_segiterator(&ftsi)) - { - if (!ftsi.pos) - continue; - - end=ftsi.pos+ftsi.len; - while (ft_simple_get_word(ftb->charset, (byte **) &ftsi.pos, - (byte *) end, &word, TRUE)) - { - int a, b, c; - for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2) - { - ftbw=ftb->list[c]; - if (mi_compare_text(ftb->charset, (uchar*) word.pos, word.len, - (uchar*) ftbw->word+1, ftbw->len-1, - (my_bool) (ftbw->flags&FTB_FLAG_TRUNC),0) >0) - b=c; - else - a=c; - } - for (; c>=0; c--) - { - ftbw=ftb->list[c]; - if (mi_compare_text(ftb->charset, (uchar*) word.pos, word.len, - (uchar*) ftbw->word+1,ftbw->len-1, - (my_bool) (ftbw->flags&FTB_FLAG_TRUNC),0)) - break; - if (ftbw->docid[1] == docid) - continue; - ftbw->docid[1]=docid; - _ftb_climb_the_tree(ftb, ftbw, &ftsi2); - } - } - } - - ftbe=ftb->root; - if (ftbe->docid[1]==docid && ftbe->cur_weight>0 && - ftbe->yesses>=ftbe->ythresh && !ftbe->nos) - { /* row matched ! */ - return ftbe->cur_weight; - } - else - { /* match failed ! */ - return 0.0; - } -} - - -void ft_boolean_close_search(FT_INFO *ftb) -{ - if (is_tree_inited(& ftb->no_dupes)) - { - delete_tree(& ftb->no_dupes); - } - free_root(& ftb->mem_root, MYF(0)); - my_free((gptr)ftb,MYF(0)); -} - - -float ft_boolean_get_relevance(FT_INFO *ftb) -{ - return ftb->root->cur_weight; -} - - -void ft_boolean_reinit_search(FT_INFO *ftb) -{ - _ftb_init_index_search(ftb); -} - diff --git a/myisam/ft_eval.c b/myisam/ft_eval.c deleted file mode 100644 index 34248c69f20..00000000000 --- a/myisam/ft_eval.c +++ /dev/null @@ -1,253 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code - added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */ - -#include "ftdefs.h" -#include "ft_eval.h" -#include <stdarg.h> -#include <my_getopt.h> - -static void print_error(int exit_code, const char *fmt,...); -static void get_options(int argc, char *argv[]); -static int create_record(char *pos, FILE *file); -static void usage(); - -static struct my_option my_long_options[] = -{ - {"", 's', "", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"", 'q', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", 'S', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", '#', "", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"", 'V', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", '?', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", 'h', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} -}; - -int main(int argc, char *argv[]) -{ - MI_INFO *file; - int i,j; - - MY_INIT(argv[0]); - get_options(argc,argv); - bzero((char*)recinfo,sizeof(recinfo)); - - /* First define 2 columns */ - recinfo[0].type=FIELD_SKIP_ENDSPACE; - recinfo[0].length=docid_length; - recinfo[1].type=FIELD_BLOB; - recinfo[1].length= 4+mi_portable_sizeof_char_ptr; - - /* Define a key over the first column */ - keyinfo[0].seg=keyseg; - keyinfo[0].keysegs=1; - keyinfo[0].seg[0].type= HA_KEYTYPE_TEXT; - keyinfo[0].seg[0].flag= HA_BLOB_PART; - keyinfo[0].seg[0].start=recinfo[0].length; - keyinfo[0].seg[0].length=key_length; - keyinfo[0].seg[0].null_bit=0; - keyinfo[0].seg[0].null_pos=0; - keyinfo[0].seg[0].bit_start=4; - keyinfo[0].seg[0].language=MY_CHARSET_CURRENT; - keyinfo[0].flag = HA_FULLTEXT; - - if (!silent) - printf("- Creating isam-file\n"); - if (mi_create(filename,1,keyinfo,2,recinfo,0,NULL,(MI_CREATE_INFO*) 0,0)) - goto err; - if (!(file=mi_open(filename,2,0))) - goto err; - if (!silent) - printf("Initializing stopwords\n"); - ft_init_stopwords(stopwordlist); - - if (!silent) - printf("- Writing key:s\n"); - - my_errno=0; - i=0; - while (create_record(record,df)) - { - error=mi_write(file,record); - if (error) - printf("I= %2d mi_write: %d errno: %d\n",i,error,my_errno); - i++; - } - fclose(df); - - if (mi_close(file)) goto err; - if (!silent) - printf("- Reopening file\n"); - if (!(file=mi_open(filename,2,0))) goto err; - if (!silent) - printf("- Reading rows with key\n"); - for (i=1;create_record(record,qf);i++) - { - FT_DOCLIST *result; - double w; - int t, err; - - result=ft_nlq_init_search(file,0,blob_record,(uint) strlen(blob_record),1); - if (!result) - { - printf("Query %d failed with errno %3d\n",i,my_errno); - goto err; - } - if (!silent) - printf("Query %d. Found: %d.\n",i,result->ndocs); - for (j=0;(err=ft_nlq_read_next(result, read_record))==0;j++) - { - t=uint2korr(read_record); - w=ft_nlq_get_relevance(result); - printf("%d %.*s %f\n",i,t,read_record+2,w); - } - if (err != HA_ERR_END_OF_FILE) - { - printf("ft_read_next %d failed with errno %3d\n",j,my_errno); - goto err; - } - ft_nlq_close_search(result); - } - - if (mi_close(file)) goto err; - my_end(MY_CHECK_ERROR); - - return (0); - - err: - printf("got error: %3d when using myisam-database\n",my_errno); - return 1; /* skip warning */ - -} - - -static my_bool -get_one_option(int optid, const struct my_option *opt __attribute__((unused)), - char *argument) -{ - switch (optid) { - case 's': - if (stopwordlist && stopwordlist != ft_precompiled_stopwords) - break; - { - FILE *f; char s[HA_FT_MAXLEN]; int i=0,n=SWL_INIT; - - if (!(stopwordlist=(const char**) malloc(n*sizeof(char *)))) - print_error(1,"malloc(%d)",n*sizeof(char *)); - if (!(f=fopen(argument,"r"))) - print_error(1,"fopen(%s)",argument); - while (!feof(f)) - { - if (!(fgets(s,HA_FT_MAXLEN,f))) - print_error(1,"fgets(s,%d,%s)",HA_FT_MAXLEN,argument); - if (!(stopwordlist[i++]=strdup(s))) - print_error(1,"strdup(%s)",s); - if (i >= n) - { - n+=SWL_PLUS; - if (!(stopwordlist=(const char**) realloc((char*) stopwordlist, - n*sizeof(char *)))) - print_error(1,"realloc(%d)",n*sizeof(char *)); - } - } - fclose(f); - stopwordlist[i]=NULL; - break; - } - case 'q': silent=1; break; - case 'S': if (stopwordlist==ft_precompiled_stopwords) stopwordlist=NULL; break; - case '#': - DEBUGGER_ON; - DBUG_PUSH (argument); - break; - case 'V': - case '?': - case 'h': - usage(); - exit(1); - } - return 0; -} - - -static void get_options(int argc, char *argv[]) -{ - int ho_error; - - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) - exit(ho_error); - - if (!(d_file=argv[optind])) print_error(1,"No d_file"); - if (!(df=fopen(d_file,"r"))) - print_error(1,"fopen(%s)",d_file); - if (!(q_file=argv[optind+1])) print_error(1,"No q_file"); - if (!(qf=fopen(q_file,"r"))) - print_error(1,"fopen(%s)",q_file); - return; -} /* get options */ - - -static int create_record(char *pos, FILE *file) -{ - uint tmp; char *ptr; - - bzero((char *)pos,MAX_REC_LENGTH); - - /* column 1 - VARCHAR */ - if (!(fgets(pos+2,MAX_REC_LENGTH-32,file))) - { - if (feof(file)) - return 0; - else - print_error(1,"fgets(docid) - 1"); - } - tmp=(uint) strlen(pos+2)-1; - int2store(pos,tmp); - pos+=recinfo[0].length; - - /* column 2 - BLOB */ - - if (!(fgets(blob_record,MAX_BLOB_LENGTH,file))) - print_error(1,"fgets(docid) - 2"); - tmp=(uint) strlen(blob_record); - int4store(pos,tmp); - ptr=blob_record; - memcpy_fixed(pos+4,&ptr,sizeof(char*)); - return 1; -} - -/* VARARGS */ - -static void print_error(int exit_code, const char *fmt,...) -{ - va_list args; - - va_start(args,fmt); - fprintf(stderr,"%s: error: ",my_progname); - VOID(vfprintf(stderr, fmt, args)); - VOID(fputc('\n',stderr)); - fflush(stderr); - va_end(args); - exit(exit_code); -} - - -static void usage() -{ - printf("%s [options]\n", my_progname); - my_print_help(my_long_options); - my_print_variables(my_long_options); -} diff --git a/myisam/ft_eval.h b/myisam/ft_eval.h deleted file mode 100644 index 5501fe9d34b..00000000000 --- a/myisam/ft_eval.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & Sergei A. Golubchik - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ - -const char **stopwordlist=ft_precompiled_stopwords; - -#define MAX_REC_LENGTH 128 -#define MAX_BLOB_LENGTH 60000 -char record[MAX_REC_LENGTH], read_record[MAX_REC_LENGTH+MAX_BLOB_LENGTH]; -char blob_record[MAX_BLOB_LENGTH+20*20]; - -char *filename= (char*) "EVAL"; - -int silent=0, error=0; - -uint key_length=MAX_BLOB_LENGTH,docid_length=32; -char *d_file, *q_file; -FILE *df,*qf; - -MI_COLUMNDEF recinfo[3]; -MI_KEYDEF keyinfo[2]; -HA_KEYSEG keyseg[10]; - -#define SWL_INIT 500 -#define SWL_PLUS 50 - -#define MAX_LINE_LENGTH 128 -char line[MAX_LINE_LENGTH]; diff --git a/myisam/ft_nlq_search.c b/myisam/ft_nlq_search.c deleted file mode 100644 index 7a506fd11c6..00000000000 --- a/myisam/ft_nlq_search.c +++ /dev/null @@ -1,360 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ - -#define FT_CORE -#include "ftdefs.h" - -/* search with natural language queries */ - -typedef struct ft_doc_rec -{ - my_off_t dpos; - double weight; -} FT_DOC; - -struct st_ft_info -{ - struct _ft_vft *please; - MI_INFO *info; - int ndocs; - int curdoc; - FT_DOC doc[1]; -}; - -typedef struct st_all_in_one -{ - MI_INFO *info; - uint keynr; - CHARSET_INFO *charset; - uchar *keybuff; - TREE dtree; -} ALL_IN_ONE; - -typedef struct st_ft_superdoc -{ - FT_DOC doc; - FT_WORD *word_ptr; - double tmp_weight; -} FT_SUPERDOC; - -static int FT_SUPERDOC_cmp(void* cmp_arg __attribute__((unused)), - FT_SUPERDOC *p1, FT_SUPERDOC *p2) -{ - if (p1->doc.dpos < p2->doc.dpos) - return -1; - if (p1->doc.dpos == p2->doc.dpos) - return 0; - return 1; -} - -static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) -{ - int subkeys, r; - uint keylen, doc_cnt; - FT_SUPERDOC sdoc, *sptr; - TREE_ELEMENT *selem; - double gweight=1; - MI_INFO *info=aio->info; - uchar *keybuff=aio->keybuff; - MI_KEYDEF *keyinfo=info->s->keyinfo+aio->keynr; - my_off_t key_root=info->s->state.key_root[aio->keynr]; - uint extra=HA_FT_WLEN+info->s->base.rec_reflength; -#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT - float tmp_weight; -#else -#error -#endif - - DBUG_ENTER("walk_and_match"); - - word->weight=LWS_FOR_QUERY; - - keylen=_ft_make_key(info,aio->keynr,(char*) keybuff,word,0); - keylen-=HA_FT_WLEN; - doc_cnt=0; - - /* Skip rows inserted by current inserted */ - for (r=_mi_search(info, keyinfo, keybuff, keylen, SEARCH_FIND, key_root) ; - !r && - (subkeys=ft_sintXkorr(info->lastkey+info->lastkey_length-extra)) > 0 && - info->lastpos >= info->state->data_file_length ; - r= _mi_search_next(info, keyinfo, info->lastkey, - info->lastkey_length, SEARCH_BIGGER, key_root)) - ; - - info->update|= HA_STATE_AKTIV; /* for _mi_test_if_changed() */ - - /* The following should be safe, even if we compare doubles */ - while (!r && gweight) - { - - if (keylen && - mi_compare_text(aio->charset,info->lastkey+1, - info->lastkey_length-extra-1, keybuff+1,keylen-1,0,0)) - break; - - if (subkeys<0) - { - if (doc_cnt) - DBUG_RETURN(1); /* index is corrupted */ - /* - TODO here: unsafe optimization, should this word - be skipped (based on subkeys) ? - */ - keybuff+=keylen; - keyinfo=& info->s->ft2_keyinfo; - key_root=info->lastpos; - keylen=0; - r=_mi_search_first(info, keyinfo, key_root); - goto do_skip; - } -#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT - tmp_weight=*(float*)&subkeys; -#else -#error -#endif - /* The following should be safe, even if we compare doubles */ - if (tmp_weight==0) - DBUG_RETURN(doc_cnt); /* stopword, doc_cnt should be 0 */ - - sdoc.doc.dpos=info->lastpos; - - /* saving document matched into dtree */ - if (!(selem=tree_insert(&aio->dtree, &sdoc, 0, aio->dtree.custom_arg))) - DBUG_RETURN(1); - - sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem); - - if (selem->count==1) /* document's first match */ - sptr->doc.weight=0; - else - sptr->doc.weight+=sptr->tmp_weight*sptr->word_ptr->weight; - - sptr->word_ptr=word; - sptr->tmp_weight=tmp_weight; - - doc_cnt++; - - gweight=word->weight*GWS_IN_USE; - if (gweight < 0 || doc_cnt > 2000000) - gweight=0; - - if (_mi_test_if_changed(info) == 0) - r=_mi_search_next(info, keyinfo, info->lastkey, info->lastkey_length, - SEARCH_BIGGER, key_root); - else - r=_mi_search(info, keyinfo, info->lastkey, info->lastkey_length, - SEARCH_BIGGER, key_root); -do_skip: - while ((subkeys=ft_sintXkorr(info->lastkey+info->lastkey_length-extra)) > 0 && - !r && info->lastpos >= info->state->data_file_length) - r= _mi_search_next(info, keyinfo, info->lastkey, info->lastkey_length, - SEARCH_BIGGER, key_root); - - } - word->weight=gweight; - - DBUG_RETURN(0); -} - - -static int walk_and_copy(FT_SUPERDOC *from, - uint32 count __attribute__((unused)), FT_DOC **to) -{ - DBUG_ENTER("walk_and_copy"); - from->doc.weight+=from->tmp_weight*from->word_ptr->weight; - (*to)->dpos=from->doc.dpos; - (*to)->weight=from->doc.weight; - (*to)++; - DBUG_RETURN(0); -} - -static int walk_and_push(FT_SUPERDOC *from, - uint32 count __attribute__((unused)), QUEUE *best) -{ - DBUG_ENTER("walk_and_copy"); - from->doc.weight+=from->tmp_weight*from->word_ptr->weight; - set_if_smaller(best->elements, ft_query_expansion_limit-1); - queue_insert(best, (byte *)& from->doc); - DBUG_RETURN(0); -} - - -static int FT_DOC_cmp(void *unused __attribute__((unused)), - FT_DOC *a, FT_DOC *b) -{ - return sgn(b->weight - a->weight); -} - - -FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query, - uint query_len, uint flags, byte *record) -{ - TREE wtree; - ALL_IN_ONE aio; - FT_DOC *dptr; - FT_INFO *dlist=NULL; - my_off_t saved_lastpos=info->lastpos; - DBUG_ENTER("ft_init_nlq_search"); - -/* black magic ON */ - if ((int) (keynr = _mi_check_index(info,keynr)) < 0) - DBUG_RETURN(NULL); - if (_mi_readinfo(info,F_RDLCK,1)) - DBUG_RETURN(NULL); -/* black magic OFF */ - - aio.info=info; - aio.keynr=keynr; - aio.charset=info->s->keyinfo[keynr].seg->charset; - aio.keybuff=info->lastkey+info->s->base.max_key_length; - - bzero(&wtree,sizeof(wtree)); - - init_tree(&aio.dtree,0,0,sizeof(FT_SUPERDOC),(qsort_cmp2)&FT_SUPERDOC_cmp,0, - NULL, NULL); - - ft_parse_init(&wtree, aio.charset); - if (ft_parse(&wtree,query,query_len,0)) - goto err; - - if (tree_walk(&wtree, (tree_walk_action)&walk_and_match, &aio, - left_root_right)) - goto err; - - if (flags & FT_EXPAND && ft_query_expansion_limit) - { - QUEUE best; - init_queue(&best,ft_query_expansion_limit,0,0, (queue_compare) &FT_DOC_cmp, - 0); - tree_walk(&aio.dtree, (tree_walk_action) &walk_and_push, - &best, left_root_right); - while (best.elements) - { - my_off_t docid=((FT_DOC *)queue_remove(& best, 0))->dpos; - if (!(*info->read_record)(info,docid,record)) - { - info->update|= HA_STATE_AKTIV; - _mi_ft_parse(&wtree, info, keynr, record,1); - } - } - delete_queue(&best); - reset_tree(&aio.dtree); - if (tree_walk(&wtree, (tree_walk_action)&walk_and_match, &aio, - left_root_right)) - goto err; - - } - - /* - If ndocs == 0, this will not allocate RAM for FT_INFO.doc[], - so if ndocs == 0, FT_INFO.doc[] must not be accessed. - */ - dlist=(FT_INFO *)my_malloc(sizeof(FT_INFO)+ - sizeof(FT_DOC)*(aio.dtree.elements_in_tree-1), - MYF(0)); - if (!dlist) - goto err; - - dlist->please= (struct _ft_vft *) & _ft_vft_nlq; - dlist->ndocs=aio.dtree.elements_in_tree; - dlist->curdoc=-1; - dlist->info=aio.info; - dptr=dlist->doc; - - tree_walk(&aio.dtree, (tree_walk_action) &walk_and_copy, - &dptr, left_root_right); - - if (flags & FT_SORTED) - qsort2(dlist->doc, dlist->ndocs, sizeof(FT_DOC), (qsort2_cmp)&FT_DOC_cmp, 0); - -err: - delete_tree(&aio.dtree); - delete_tree(&wtree); - info->lastpos=saved_lastpos; - DBUG_RETURN(dlist); -} - - -int ft_nlq_read_next(FT_INFO *handler, char *record) -{ - MI_INFO *info= (MI_INFO *) handler->info; - - if (++handler->curdoc >= handler->ndocs) - { - --handler->curdoc; - return HA_ERR_END_OF_FILE; - } - - info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - - info->lastpos=handler->doc[handler->curdoc].dpos; - if (!(*info->read_record)(info,info->lastpos,record)) - { - info->update|= HA_STATE_AKTIV; /* Record is read */ - return 0; - } - return my_errno; -} - - -float ft_nlq_find_relevance(FT_INFO *handler, - byte *record __attribute__((unused)), - uint length __attribute__((unused))) -{ - int a,b,c; - FT_DOC *docs=handler->doc; - my_off_t docid=handler->info->lastpos; - - if (docid == HA_POS_ERROR) - return -5.0; - - /* Assuming docs[] is sorted by dpos... */ - - for (a=0, b=handler->ndocs, c=(a+b)/2; b-a>1; c=(a+b)/2) - { - if (docs[c].dpos > docid) - b=c; - else - a=c; - } - /* bounds check to avoid accessing unallocated handler->doc */ - if (a < handler->ndocs && docs[a].dpos == docid) - return (float) docs[a].weight; - else - return 0.0; -} - - -void ft_nlq_close_search(FT_INFO *handler) -{ - my_free((gptr)handler,MYF(0)); -} - - -float ft_nlq_get_relevance(FT_INFO *handler) -{ - return (float) handler->doc[handler->curdoc].weight; -} - - -void ft_nlq_reinit_search(FT_INFO *handler) -{ - handler->curdoc=-1; -} - diff --git a/myisam/ft_parser.c b/myisam/ft_parser.c deleted file mode 100644 index 2fad2363ae2..00000000000 --- a/myisam/ft_parser.c +++ /dev/null @@ -1,249 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ - -#include "ftdefs.h" - -typedef struct st_ft_docstat { - FT_WORD *list; - uint uniq; - double sum; -} FT_DOCSTAT; - -static int FT_WORD_cmp(CHARSET_INFO* cs, FT_WORD *w1, FT_WORD *w2) -{ - return mi_compare_text(cs, (uchar*) w1->pos, w1->len, - (uchar*) w2->pos, w2->len, 0, 0); -} - -static int walk_and_copy(FT_WORD *word,uint32 count,FT_DOCSTAT *docstat) -{ - word->weight=LWS_IN_USE; - docstat->sum+=word->weight; - memcpy_fixed((docstat->list)++,word,sizeof(FT_WORD)); - return 0; -} - -/* transforms tree of words into the array, applying normalization */ - -FT_WORD * ft_linearize(TREE *wtree) -{ - FT_WORD *wlist,*p; - FT_DOCSTAT docstat; - DBUG_ENTER("ft_linearize"); - - if ((wlist=(FT_WORD *) my_malloc(sizeof(FT_WORD)* - (1+wtree->elements_in_tree),MYF(0)))) - { - docstat.list=wlist; - docstat.uniq=wtree->elements_in_tree; - docstat.sum=0; - tree_walk(wtree,(tree_walk_action)&walk_and_copy,&docstat,left_root_right); - } - delete_tree(wtree); - if (!wlist) - DBUG_RETURN(NULL); - - docstat.list->pos=NULL; - - for (p=wlist;p->pos;p++) - { - p->weight=PRENORM_IN_USE; - } - - for (p=wlist;p->pos;p++) - { - p->weight/=NORM_IN_USE; - } - - DBUG_RETURN(wlist); -} - -my_bool ft_boolean_check_syntax_string(const byte *str) -{ - uint i, j; - - if (!str || - (strlen(str)+1 != sizeof(ft_boolean_syntax)) || - (str[0] != ' ' && str[1] != ' ')) - return 1; - for (i=0; i<sizeof(ft_boolean_syntax); i++) - { - /* limiting to 7-bit ascii only */ - if ((unsigned char)(str[i]) > 127 || my_isalnum(default_charset_info, str[i])) - return 1; - for (j=0; j<i; j++) - if (str[i] == str[j] && (i != 11 || j != 10)) - return 1; - } - return 0; -} - -/* - RETURN VALUE - 0 - eof - 1 - word found - 2 - left bracket - 3 - right bracket - 4 - stopword found -*/ -byte ft_get_word(CHARSET_INFO *cs, byte **start, byte *end, - FT_WORD *word, FTB_PARAM *param) -{ - byte *doc=*start; - uint mwc, length, mbl; - - param->yesno=(FTB_YES==' ') ? 1 : (param->quot != 0); - param->plusminus=param->pmsign=0; - - while (doc<end) - { - for (;doc<end;doc++) - { - if (true_word_char(cs,*doc)) break; - if (*doc == FTB_RQUOT && param->quot) - { - param->quot=doc; - *start=doc+1; - return 3; /* FTB_RBR */ - } - if (!param->quot) - { - if (*doc == FTB_LBR || *doc == FTB_RBR || *doc == FTB_LQUOT) - { - /* param->prev=' '; */ - *start=doc+1; - if (*doc == FTB_LQUOT) param->quot=*start; - return (*doc == FTB_RBR)+2; - } - if (param->prev == ' ') - { - if (*doc == FTB_YES ) { param->yesno=+1; continue; } else - if (*doc == FTB_EGAL) { param->yesno= 0; continue; } else - if (*doc == FTB_NO ) { param->yesno=-1; continue; } else - if (*doc == FTB_INC ) { param->plusminus++; continue; } else - if (*doc == FTB_DEC ) { param->plusminus--; continue; } else - if (*doc == FTB_NEG ) { param->pmsign=!param->pmsign; continue; } - } - } - param->prev=*doc; - param->yesno=(FTB_YES==' ') ? 1 : (param->quot != 0); - param->plusminus=param->pmsign=0; - } - - mwc=length=0; - for (word->pos=doc; doc<end; length++, mbl=my_mbcharlen(cs, *(uchar *)doc), doc+=(mbl ? mbl : 1)) - if (true_word_char(cs,*doc)) - mwc=0; - else if (!misc_word_char(*doc) || mwc++) - break; - - param->prev='A'; /* be sure *prev is true_word_char */ - word->len= (uint)(doc-word->pos) - mwc; - if ((param->trunc=(doc<end && *doc == FTB_TRUNC))) - doc++; - - if (((length >= ft_min_word_len && !is_stopword(word->pos, word->len)) - || param->trunc) && length < ft_max_word_len) - { - *start=doc; - return 1; - } - else if (length) /* make sure length > 0 (if start contains spaces only) */ - { - *start= doc; - return 4; - } - } - if (param->quot) - { - param->quot=*start=doc; - return 3; /* FTB_RBR */ - } - return 0; -} - -byte ft_simple_get_word(CHARSET_INFO *cs, byte **start, const byte *end, - FT_WORD *word, my_bool skip_stopwords) -{ - byte *doc= *start; - uint mwc, length, mbl; - DBUG_ENTER("ft_simple_get_word"); - - do - { - for (;; doc++) - { - if (doc >= end) DBUG_RETURN(0); - if (true_word_char(cs, *doc)) break; - } - - mwc= length= 0; - for (word->pos=doc; doc<end; length++, mbl=my_mbcharlen(cs, *(uchar *)doc), doc+=(mbl ? mbl : 1)) - if (true_word_char(cs,*doc)) - mwc= 0; - else if (!misc_word_char(*doc) || mwc++) - break; - - word->len= (uint)(doc-word->pos) - mwc; - - if (skip_stopwords == FALSE || - (length >= ft_min_word_len && length < ft_max_word_len && - !is_stopword(word->pos, word->len))) - { - *start= doc; - DBUG_RETURN(1); - } - } while (doc < end); - DBUG_RETURN(0); -} - -void ft_parse_init(TREE *wtree, CHARSET_INFO *cs) -{ - DBUG_ENTER("ft_parse_init"); - if (!is_tree_inited(wtree)) - init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp,0,NULL, cs); - DBUG_VOID_RETURN; -} - -int ft_parse(TREE *wtree, byte *doc, int doclen, my_bool with_alloc) -{ - byte *end=doc+doclen; - FT_WORD w; - DBUG_ENTER("ft_parse"); - - while (ft_simple_get_word(wtree->custom_arg, &doc, end, &w, TRUE)) - { - if (with_alloc) - { - byte *ptr; - /* allocating the data in the tree - to avoid mallocs and frees */ - DBUG_ASSERT(wtree->with_delete==0); - ptr=(byte *)alloc_root(& wtree->mem_root,w.len); - memcpy(ptr, w.pos, w.len); - w.pos=ptr; - } - if (!tree_insert(wtree, &w, 0, wtree->custom_arg)) - goto err; - } - DBUG_RETURN(0); - -err: - delete_tree(wtree); - DBUG_RETURN(1); -} - diff --git a/myisam/ft_static.c b/myisam/ft_static.c deleted file mode 100644 index e221950f445..00000000000 --- a/myisam/ft_static.c +++ /dev/null @@ -1,628 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ - -#include "ftdefs.h" - -ulong ft_min_word_len=4; -ulong ft_max_word_len=HA_FT_MAXCHARLEN; -ulong ft_query_expansion_limit=5; -char ft_boolean_syntax[]="+ -><()~*:\"\"&|"; - -const HA_KEYSEG ft_keysegs[FT_SEGS]={ -{ - 0, /* charset */ - HA_FT_WLEN, /* start */ - 0, /* null_pos */ - 0, /* Bit pos */ - HA_VAR_LENGTH_PART | HA_PACK_KEY, /* flag */ - HA_FT_MAXBYTELEN, /* length */ - HA_KEYTYPE_VARTEXT2, /* type */ - 63, /* language (will be overwritten) */ - 0, /* null_bit */ - 2, 0, 0 /* bit_start, bit_end, bit_length */ -}, -{ - /* - Note, this (and the last HA_KEYTYPE_END) segment should NOT - be packed in any way, otherwise w_search() won't be able to - update key entry 'in vivo' - */ - 0, 0, 0, 0, HA_NO_SORT, HA_FT_WLEN, HA_FT_WTYPE, 63, 0, 0, 0, 0 -} -}; - -const struct _ft_vft _ft_vft_nlq = { - ft_nlq_read_next, ft_nlq_find_relevance, ft_nlq_close_search, - ft_nlq_get_relevance, ft_nlq_reinit_search -}; -const struct _ft_vft _ft_vft_boolean = { - ft_boolean_read_next, ft_boolean_find_relevance, ft_boolean_close_search, - ft_boolean_get_relevance, ft_boolean_reinit_search -}; - - -FT_INFO *ft_init_search(uint flags, void *info, uint keynr, - byte *query, uint query_len, CHARSET_INFO *cs, - byte *record) -{ - FT_INFO *res; - if (flags & FT_BOOL) - res= ft_init_boolean_search((MI_INFO *)info, keynr, query, query_len,cs); - else - res= ft_init_nlq_search((MI_INFO *)info, keynr, query, query_len, flags, - record); - return res; -} - -const char *ft_stopword_file = 0; -const char *ft_precompiled_stopwords[] = { - -#ifdef COMPILE_STOPWORDS_IN - -/* This particular stopword list was taken from SMART distribution - ftp://ftp.cs.cornell.edu/pub/smart/smart.11.0.tar.Z - it was slightly modified to my taste, though - */ - - "a's", - "able", - "about", - "above", - "according", - "accordingly", - "across", - "actually", - "after", - "afterwards", - "again", - "against", - "ain't", - "all", - "allow", - "allows", - "almost", - "alone", - "along", - "already", - "also", - "although", - "always", - "am", - "among", - "amongst", - "an", - "and", - "another", - "any", - "anybody", - "anyhow", - "anyone", - "anything", - "anyway", - "anyways", - "anywhere", - "apart", - "appear", - "appreciate", - "appropriate", - "are", - "aren't", - "around", - "as", - "aside", - "ask", - "asking", - "associated", - "at", - "available", - "away", - "awfully", - "be", - "became", - "because", - "become", - "becomes", - "becoming", - "been", - "before", - "beforehand", - "behind", - "being", - "believe", - "below", - "beside", - "besides", - "best", - "better", - "between", - "beyond", - "both", - "brief", - "but", - "by", - "c'mon", - "c's", - "came", - "can", - "can't", - "cannot", - "cant", - "cause", - "causes", - "certain", - "certainly", - "changes", - "clearly", - "co", - "com", - "come", - "comes", - "concerning", - "consequently", - "consider", - "considering", - "contain", - "containing", - "contains", - "corresponding", - "could", - "couldn't", - "course", - "currently", - "definitely", - "described", - "despite", - "did", - "didn't", - "different", - "do", - "does", - "doesn't", - "doing", - "don't", - "done", - "down", - "downwards", - "during", - "each", - "edu", - "eg", - "eight", - "either", - "else", - "elsewhere", - "enough", - "entirely", - "especially", - "et", - "etc", - "even", - "ever", - "every", - "everybody", - "everyone", - "everything", - "everywhere", - "ex", - "exactly", - "example", - "except", - "far", - "few", - "fifth", - "first", - "five", - "followed", - "following", - "follows", - "for", - "former", - "formerly", - "forth", - "four", - "from", - "further", - "furthermore", - "get", - "gets", - "getting", - "given", - "gives", - "go", - "goes", - "going", - "gone", - "got", - "gotten", - "greetings", - "had", - "hadn't", - "happens", - "hardly", - "has", - "hasn't", - "have", - "haven't", - "having", - "he", - "he's", - "hello", - "help", - "hence", - "her", - "here", - "here's", - "hereafter", - "hereby", - "herein", - "hereupon", - "hers", - "herself", - "hi", - "him", - "himself", - "his", - "hither", - "hopefully", - "how", - "howbeit", - "however", - "i'd", - "i'll", - "i'm", - "i've", - "ie", - "if", - "ignored", - "immediate", - "in", - "inasmuch", - "inc", - "indeed", - "indicate", - "indicated", - "indicates", - "inner", - "insofar", - "instead", - "into", - "inward", - "is", - "isn't", - "it", - "it'd", - "it'll", - "it's", - "its", - "itself", - "just", - "keep", - "keeps", - "kept", - "know", - "knows", - "known", - "last", - "lately", - "later", - "latter", - "latterly", - "least", - "less", - "lest", - "let", - "let's", - "like", - "liked", - "likely", - "little", - "look", - "looking", - "looks", - "ltd", - "mainly", - "many", - "may", - "maybe", - "me", - "mean", - "meanwhile", - "merely", - "might", - "more", - "moreover", - "most", - "mostly", - "much", - "must", - "my", - "myself", - "name", - "namely", - "nd", - "near", - "nearly", - "necessary", - "need", - "needs", - "neither", - "never", - "nevertheless", - "new", - "next", - "nine", - "no", - "nobody", - "non", - "none", - "noone", - "nor", - "normally", - "not", - "nothing", - "novel", - "now", - "nowhere", - "obviously", - "of", - "off", - "often", - "oh", - "ok", - "okay", - "old", - "on", - "once", - "one", - "ones", - "only", - "onto", - "or", - "other", - "others", - "otherwise", - "ought", - "our", - "ours", - "ourselves", - "out", - "outside", - "over", - "overall", - "own", - "particular", - "particularly", - "per", - "perhaps", - "placed", - "please", - "plus", - "possible", - "presumably", - "probably", - "provides", - "que", - "quite", - "qv", - "rather", - "rd", - "re", - "really", - "reasonably", - "regarding", - "regardless", - "regards", - "relatively", - "respectively", - "right", - "said", - "same", - "saw", - "say", - "saying", - "says", - "second", - "secondly", - "see", - "seeing", - "seem", - "seemed", - "seeming", - "seems", - "seen", - "self", - "selves", - "sensible", - "sent", - "serious", - "seriously", - "seven", - "several", - "shall", - "she", - "should", - "shouldn't", - "since", - "six", - "so", - "some", - "somebody", - "somehow", - "someone", - "something", - "sometime", - "sometimes", - "somewhat", - "somewhere", - "soon", - "sorry", - "specified", - "specify", - "specifying", - "still", - "sub", - "such", - "sup", - "sure", - "t's", - "take", - "taken", - "tell", - "tends", - "th", - "than", - "thank", - "thanks", - "thanx", - "that", - "that's", - "thats", - "the", - "their", - "theirs", - "them", - "themselves", - "then", - "thence", - "there", - "there's", - "thereafter", - "thereby", - "therefore", - "therein", - "theres", - "thereupon", - "these", - "they", - "they'd", - "they'll", - "they're", - "they've", - "think", - "third", - "this", - "thorough", - "thoroughly", - "those", - "though", - "three", - "through", - "throughout", - "thru", - "thus", - "to", - "together", - "too", - "took", - "toward", - "towards", - "tried", - "tries", - "truly", - "try", - "trying", - "twice", - "two", - "un", - "under", - "unfortunately", - "unless", - "unlikely", - "until", - "unto", - "up", - "upon", - "us", - "use", - "used", - "useful", - "uses", - "using", - "usually", - "value", - "various", - "very", - "via", - "viz", - "vs", - "want", - "wants", - "was", - "wasn't", - "way", - "we", - "we'd", - "we'll", - "we're", - "we've", - "welcome", - "well", - "went", - "were", - "weren't", - "what", - "what's", - "whatever", - "when", - "whence", - "whenever", - "where", - "where's", - "whereafter", - "whereas", - "whereby", - "wherein", - "whereupon", - "wherever", - "whether", - "which", - "while", - "whither", - "who", - "who's", - "whoever", - "whole", - "whom", - "whose", - "why", - "will", - "willing", - "wish", - "with", - "within", - "without", - "won't", - "wonder", - "would", - "would", - "wouldn't", - "yes", - "yet", - "you", - "you'd", - "you'll", - "you're", - "you've", - "your", - "yours", - "yourself", - "yourselves", - "zero", -#endif - - NULL }; diff --git a/myisam/ft_stem.c b/myisam/ft_stem.c deleted file mode 100644 index 846d5d2247f..00000000000 --- a/myisam/ft_stem.c +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ - -/* mulitingual stem */ diff --git a/myisam/ft_stopwords.c b/myisam/ft_stopwords.c deleted file mode 100644 index ab51afb0e82..00000000000 --- a/myisam/ft_stopwords.c +++ /dev/null @@ -1,129 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ - -#include "ftdefs.h" -#include "my_handler.h" - -typedef struct st_ft_stopwords -{ - const char * pos; - uint len; -} FT_STOPWORD; - -static TREE *stopwords3=NULL; - -static int FT_STOPWORD_cmp(void* cmp_arg __attribute__((unused)), - FT_STOPWORD *w1, FT_STOPWORD *w2) -{ - return mi_compare_text(default_charset_info, - (uchar *)w1->pos,w1->len, - (uchar *)w2->pos,w2->len,0,0); -} - -static void FT_STOPWORD_free(FT_STOPWORD *w, TREE_FREE action, - void *arg __attribute__((unused))) -{ - if (action == free_free) - my_free((gptr) w->pos, MYF(0)); -} - -static int ft_add_stopword(const char *w) -{ - FT_STOPWORD sw; - return !w || - (((sw.len= (uint) strlen(sw.pos=w)) >= ft_min_word_len) && - (tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL)); -} - -int ft_init_stopwords() -{ - if (!stopwords3) - { - if (!(stopwords3=(TREE *)my_malloc(sizeof(TREE),MYF(0)))) - return -1; - init_tree(stopwords3,0,0,sizeof(FT_STOPWORD),(qsort_cmp2)&FT_STOPWORD_cmp, - 0, - (ft_stopword_file ? (tree_element_free)&FT_STOPWORD_free : 0), - NULL); - } - - if (ft_stopword_file) - { - File fd; - uint len; - byte *buffer, *start, *end; - FT_WORD w; - int error=-1; - - if (!*ft_stopword_file) - return 0; - - if ((fd=my_open(ft_stopword_file, O_RDONLY, MYF(MY_WME))) == -1) - return -1; - len=(uint)my_seek(fd, 0L, MY_SEEK_END, MYF(0)); - my_seek(fd, 0L, MY_SEEK_SET, MYF(0)); - if (!(start=buffer=my_malloc(len+1, MYF(MY_WME)))) - goto err0; - len=my_read(fd, buffer, len, MYF(MY_WME)); - end=start+len; - while (ft_simple_get_word(default_charset_info, &start, end, &w, TRUE)) - { - if (ft_add_stopword(my_strdup_with_length(w.pos, w.len, MYF(0)))) - goto err1; - } - error=0; -err1: - my_free(buffer, MYF(0)); -err0: - my_close(fd, MYF(MY_WME)); - return error; - } - else - { - /* compatibility mode: to be removed */ - char **sws=(char **)ft_precompiled_stopwords; - - for (;*sws;sws++) - { - if (ft_add_stopword(*sws)) - return -1; - } - ft_stopword_file="(built-in)"; /* for SHOW VARIABLES */ - } - return 0; -} - -int is_stopword(char *word, uint len) -{ - FT_STOPWORD sw; - sw.pos=word; - sw.len=len; - return tree_search(stopwords3,&sw, stopwords3->custom_arg) != NULL; -} - - -void ft_free_stopwords() -{ - if (stopwords3) - { - delete_tree(stopwords3); /* purecov: inspected */ - my_free((char*) stopwords3,MYF(0)); - stopwords3=0; - } - ft_stopword_file= 0; -} diff --git a/myisam/ft_test1.c b/myisam/ft_test1.c deleted file mode 100644 index 14be9aa1e8c..00000000000 --- a/myisam/ft_test1.c +++ /dev/null @@ -1,316 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code - added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */ - -#include "ftdefs.h" -#include "ft_test1.h" -#include <my_getopt.h> - -static int key_field=FIELD_VARCHAR,extra_field=FIELD_SKIP_ENDSPACE; -static uint key_length=200,extra_length=50; -static int key_type=HA_KEYTYPE_TEXT; -static int verbose=0,silent=0,skip_update=0, - no_keys=0,no_stopwords=0,no_search=0,no_fulltext=0; -static int create_flag=0,error=0; - -#define MAX_REC_LENGTH 300 -static char record[MAX_REC_LENGTH],read_record[MAX_REC_LENGTH]; - -static int run_test(const char *filename); -static void get_options(int argc, char *argv[]); -static void create_record(char *, int); -static void usage(); - -static struct my_option my_long_options[] = -{ - {"", 'v', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", '?', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", 'h', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", 'V', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", 'v', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", 's', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", 'N', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", 'S', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", 'K', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", 'F', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", 'U', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"", '#', "", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} -}; - -int main(int argc, char *argv[]) -{ - MY_INIT(argv[0]); - - get_options(argc,argv); - - exit(run_test("FT1")); -} - -static MI_COLUMNDEF recinfo[3]; -static MI_KEYDEF keyinfo[2]; -static HA_KEYSEG keyseg[10]; - -static int run_test(const char *filename) -{ - MI_INFO *file; - int i,j; - my_off_t pos; - - bzero((char*) recinfo,sizeof(recinfo)); - - /* First define 2 columns */ - recinfo[0].type=extra_field; - recinfo[0].length= (extra_field == FIELD_BLOB ? 4 + mi_portable_sizeof_char_ptr : - extra_length); - if (extra_field == FIELD_VARCHAR) - recinfo[0].length+= HA_VARCHAR_PACKLENGTH(extra_length); - recinfo[1].type=key_field; - recinfo[1].length= (key_field == FIELD_BLOB ? 4+mi_portable_sizeof_char_ptr : - key_length); - if (key_field == FIELD_VARCHAR) - recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length); - - /* Define a key over the first column */ - keyinfo[0].seg=keyseg; - keyinfo[0].keysegs=1; - keyinfo[0].seg[0].type= key_type; - keyinfo[0].seg[0].flag= (key_field == FIELD_BLOB) ? HA_BLOB_PART: - (key_field == FIELD_VARCHAR) ? HA_VAR_LENGTH_PART:0; - keyinfo[0].seg[0].start=recinfo[0].length; - keyinfo[0].seg[0].length=key_length; - keyinfo[0].seg[0].null_bit= 0; - keyinfo[0].seg[0].null_pos=0; - keyinfo[0].seg[0].language= default_charset_info->number; - keyinfo[0].flag = (no_fulltext?HA_PACK_KEY:HA_FULLTEXT); - - if (!silent) - printf("- Creating isam-file\n"); - if (mi_create(filename,(no_keys?0:1),keyinfo,2,recinfo,0,NULL, - (MI_CREATE_INFO*) 0, create_flag)) - goto err; - if (!(file=mi_open(filename,2,0))) - goto err; - - if (!silent) - printf("- %s stopwords\n",no_stopwords?"Skipping":"Initializing"); - ft_init_stopwords(no_stopwords?NULL:ft_precompiled_stopwords); - - if (!silent) - printf("- Writing key:s\n"); - - my_errno=0; - for (i=NUPD ; i<NDATAS; i++ ) - { - create_record(record,i); - error=mi_write(file,record); - if (verbose || error) - printf("I= %2d mi_write: %d errno: %d, record: %s\n", - i,error,my_errno,data[i].f0); - } - - if (!skip_update) - { - if (!silent) - printf("- Updating rows\n"); - - /* Read through all rows and update them */ - pos=(ha_rows) 0; - i=0; - while ((error=mi_rrnd(file,read_record,pos)) == 0) - { - create_record(record,NUPD-i-1); - if (mi_update(file,read_record,record)) - { - printf("Can't update row: %.*s, error: %d\n", - keyinfo[0].seg[0].length,record,my_errno); - } - if(++i == NUPD) break; - pos=HA_OFFSET_ERROR; - } - if (i != NUPD) - printf("Found %d of %d rows\n", i,NUPD); - } - - if (mi_close(file)) goto err; - if(no_search) return 0; - if (!silent) - printf("- Reopening file\n"); - if (!(file=mi_open(filename,2,0))) goto err; - if (!silent) - printf("- Reading rows with key\n"); - for (i=0 ; i < NQUERIES ; i++) - { - FT_DOCLIST *result; - result=ft_nlq_init_search(file,0,(char*) query[i],strlen(query[i]),1); - if(!result) - { - printf("Query %d: `%s' failed with errno %3d\n",i,query[i],my_errno); - continue; - } - printf("Query %d: `%s'. Found: %d. Top five documents:\n", - i,query[i],result->ndocs); - for (j=0;j<5;j++) - { - double w; int err; - err= ft_nlq_read_next(result, read_record); - if (err==HA_ERR_END_OF_FILE) - { - printf("No more matches!\n"); - break; - } - else if (err) - { - printf("ft_read_next %d failed with errno %3d\n",j,my_errno); - break; - } - w=ft_nlq_get_relevance(result); - if (key_field == FIELD_VARCHAR) - { - uint l; - char *p; - p=recinfo[0].length+read_record; - l=uint2korr(p); - printf("%10.7f: %.*s\n",w,(int) l,p+2); - } - else - printf("%10.7f: %.*s\n",w,recinfo[1].length, - recinfo[0].length+read_record); - } - ft_nlq_close_search(result); - } - - if (mi_close(file)) goto err; - my_end(MY_CHECK_ERROR); - - return (0); -err: - printf("got error: %3d when using myisam-database\n",my_errno); - return 1; /* skip warning */ -} - -static char blob_key[MAX_REC_LENGTH]; -/* static char blob_record[MAX_REC_LENGTH+20*20]; */ - -void create_record(char *pos, int n) -{ - bzero((char*) pos,MAX_REC_LENGTH); - if (recinfo[0].type == FIELD_BLOB) - { - uint tmp; - char *ptr; - strnmov(blob_key,data[n].f0,keyinfo[0].seg[0].length); - tmp=strlen(blob_key); - int4store(pos,tmp); - ptr=blob_key; - memcpy_fixed(pos+4,&ptr,sizeof(char*)); - pos+=recinfo[0].length; - } - else if (recinfo[0].type == FIELD_VARCHAR) - { - uint tmp; - /* -1 is here because pack_length is stored in seg->length */ - uint pack_length= HA_VARCHAR_PACKLENGTH(keyinfo[0].seg[0].length-1); - strnmov(pos+pack_length,data[n].f0,keyinfo[0].seg[0].length); - tmp=strlen(pos+pack_length); - if (pack_length == 1) - *pos= (char) tmp; - else - int2store(pos,tmp); - pos+=recinfo[0].length; - } - else - { - strnmov(pos,data[n].f0,keyinfo[0].seg[0].length); - pos+=recinfo[0].length; - } - if (recinfo[1].type == FIELD_BLOB) - { - uint tmp; - char *ptr; - strnmov(blob_key,data[n].f2,keyinfo[0].seg[0].length); - tmp=strlen(blob_key); - int4store(pos,tmp); - ptr=blob_key; - memcpy_fixed(pos+4,&ptr,sizeof(char*)); - pos+=recinfo[1].length; - } - else if (recinfo[1].type == FIELD_VARCHAR) - { - uint tmp; - /* -1 is here because pack_length is stored in seg->length */ - uint pack_length= HA_VARCHAR_PACKLENGTH(keyinfo[0].seg[0].length-1); - strnmov(pos+pack_length,data[n].f2,keyinfo[0].seg[0].length); - tmp=strlen(pos+1); - if (pack_length == 1) - *pos= (char) tmp; - else - int2store(pos,tmp); - pos+=recinfo[1].length; - } - else - { - strnmov(pos,data[n].f2,keyinfo[0].seg[0].length); - pos+=recinfo[1].length; - } -} - - -static my_bool -get_one_option(int optid, const struct my_option *opt __attribute__((unused)), - char *argument) -{ - switch(optid) { - case 'v': verbose=1; break; - case 's': silent=1; break; - case 'F': no_fulltext=1; no_search=1; - case 'U': skip_update=1; break; - case 'K': no_keys=no_search=1; break; - case 'N': no_search=1; break; - case 'S': no_stopwords=1; break; - case '#': - DEBUGGER_ON; - DBUG_PUSH (argument); - break; - case 'V': - case '?': - case 'h': - usage(); - exit(1); - } - return 0; -} - -/* Read options */ - -static void get_options(int argc,char *argv[]) -{ - int ho_error; - - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) - exit(ho_error); - return; -} /* get options */ - - -static void usage() -{ - printf("%s [options]\n", my_progname); - my_print_help(my_long_options); - my_print_variables(my_long_options); -} diff --git a/myisam/ft_test1.h b/myisam/ft_test1.h deleted file mode 100644 index e360244057b..00000000000 --- a/myisam/ft_test1.h +++ /dev/null @@ -1,421 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ - -#define NUPD 20 -#define NDATAS 389 -struct { const char *f0, *f2; } data[NDATAS] = { - {"1", "General Information about MySQL"}, - {"1.1", "What is MySQL?"}, - {"1.2", "About this manual"}, - {"1.3", "History of MySQL"}, - {"1.4", "The main features of MySQL"}, - {"1.5", "General SQL information and tutorials"}, - {"1.6", "Useful MySQL-related links"}, - {"1.7", "What are stored procedures and triggers and so on?"}, - {"2", "MySQL mailing lists and how to ask questions/give error (bug) reports"}, - {"2.1", "Subscribing to/un-subscribing from the MySQL mailing list"}, - {"2.2", "Asking questions or reporting bugs"}, - {"2.3", "I think I have found a bug. What information do you need to help me?"}, - {"2.3.1", "MySQL keeps crashing"}, - {"2.4", "Guidelines for answering questions on the mailing list"}, - {"3", "Licensing or When do I have/want to pay for MySQL?"}, - {"3.1", "How much does MySQL cost?"}, - {"3.2", "How do I get commercial support?"}, - {"3.2.1", "Types of commercial support"}, - {"3.2.1.1", "Basic email support"}, - {"3.2.1.2", "Extended email support"}, -/*------------------------------- NUPD=20 -------------------------------*/ - {"3.2.1.3", "Asking: Login support"}, - {"3.2.1.4", "Extended login support"}, - {"3.3", "How do I pay for licenses/support?"}, - {"3.4", "Who do I contact when I want more information about licensing/support?"}, - {"3.5", "What Copyright does MySQL use?"}, - {"3.6", "When may I distribute MySQL commercially without a fee?"}, - {"3.7", "I want to sell a product that can be configured to use MySQL"}, - {"3.8", "I am running a commercial web server using MySQL"}, - {"3.9", "Do I need a license to sell commercial Perl/tcl/PHP/Web+ etc applications?"}, - {"3.10", "Possible future changes in the licensing"}, - {"4", "Compiling and installing MySQL"}, - {"4.1", "How do I get MySQL?"}, - {"4.2", "Which MySQL version should I use?"}, - {"4.3", "How/when will you release updates?"}, - {"4.4", "What operating systems does MySQL support?"}, - {"4.5", "Compiling MySQL from source code"}, - {"4.5.1", "Quick installation overview"}, - {"4.5.2", "Usual configure switches"}, - {"4.5.3", "Applying a patch"}, - {"4.6", "Problems compiling?"}, - {"4.7", "General compilation notes"}, - {"4.8", "MIT-pthreads notes (FreeBSD)"}, - {"4.9", "Perl installation comments"}, - {"4.10", "Special things to consider for some machine/OS combinations"}, - {"4.10.1", "Solaris notes"}, - {"4.10.2", "SunOS 4 notes"}, - {"4.10.3", "Linux notes for all versions"}, - {"4.10.3.1", "Linux-x86 notes"}, - {"4.10.3.2", "RedHat 5.0"}, - {"4.10.3.3", "RedHat 5.1"}, - {"4.10.3.4", "Linux-Sparc notes"}, - {"4.10.3.5", "Linux-Alpha notes"}, - {"4.10.3.6", "MkLinux notes"}, - {"4.10.4", "Alpha-DEC-Unix notes"}, - {"4.10.5", "Alpha-DEC-OSF1 notes"}, - {"4.10.6", "SGI-IRIX notes"}, - {"4.10.7", "FreeBSD notes"}, - {"4.10.7.1", "FreeBSD-3.0 notes"}, - {"4.10.8", "BSD/OS 2.# notes"}, - {"4.10.8.1", "BSD/OS 3.# notes"}, - {"4.10.9", "SCO notes"}, - {"4.10.10", "SCO Unixware 7.0 notes"}, - {"4.10.11", "IBM-AIX notes"}, - {"4.10.12", "HP-UX notes"}, - {"4.11", "TcX binaries"}, - {"4.12", "Win32 notes"}, - {"4.13", "Installation instructions for MySQL binary releases"}, - {"4.13.1", "How to get MySQL Perl support working"}, - {"4.13.2", "Linux notes"}, - {"4.13.3", "HP-UX notes"}, - {"4.13.4", "Linking client libraries"}, - {"4.14", "Problems running mysql_install_db"}, - {"4.15", "Problems starting MySQL"}, - {"4.16", "Automatic start/stop of MySQL"}, - {"4.17", "Option files"}, - {"5", "How standards-compatible is MySQL?"}, - {"5.1", "What extensions has MySQL to ANSI SQL92?"}, - {"5.2", "What functionality is missing in MySQL?"}, - {"5.2.1", "Sub-selects"}, - {"5.2.2", "SELECT INTO TABLE"}, - {"5.2.3", "Transactions"}, - {"5.2.4", "Triggers"}, - {"5.2.5", "Foreign Keys"}, - {"5.2.5.1", "Some reasons NOT to use FOREIGN KEYS"}, - {"5.2.6", "Views"}, - {"5.2.7", "-- as start of a comment"}, - {"5.3", "What standards does MySQL follow?"}, - {"5.4", "What functions exist only for compatibility?"}, - {"5.5", "Limitations of BLOB and TEXT types"}, - {"5.6", "How to cope without COMMIT-ROLLBACK"}, - {"6", "The MySQL access privilege system"}, - {"6.1", "What the privilege system does"}, - {"6.2", "Connecting to the MySQL server"}, - {"6.2.1", "Keeping your password secure"}, - {"6.3", "Privileges provided by MySQL"}, - {"6.4", "How the privilege system works"}, - {"6.5", "The privilege tables"}, - {"6.6", "Setting up the initial MySQL privileges"}, - {"6.7", "Adding new user privileges to MySQL"}, - {"6.8", "An example permission setup"}, - {"6.9", "Causes of Access denied errors"}, - {"6.10", "How to make MySQL secure against crackers"}, - {"7", "MySQL language reference"}, - {"7.1", "Literals: how to write strings and numbers"}, - {"7.1.1", "Strings"}, - {"7.1.2", "Numbers"}, - {"7.1.3", "NULL values"}, - {"7.1.4", "Database, table, index, column and alias names"}, - {"7.1.4.1", "Case sensitivity in names"}, - {"7.2", "Column types"}, - {"7.2.1", "Column type storage requirements"}, - {"7.2.5", "Numeric types"}, - {"7.2.6", "Date and time types"}, - {"7.2.6.1", "The DATE type"}, - {"7.2.6.2", "The TIME type"}, - {"7.2.6.3", "The DATETIME type"}, - {"7.2.6.4", "The TIMESTAMP type"}, - {"7.2.6.5", "The YEAR type"}, - {"7.2.6.6", "Miscellaneous date and time properties"}, - {"7.2.7", "String types"}, - {"7.2.7.1", "The CHAR and VARCHAR types"}, - {"7.2.7.2", "The BLOB and TEXT types"}, - {"7.2.7.3", "The ENUM type"}, - {"7.2.7.4", "The SET type"}, - {"7.2.8", "Choosing the right type for a column"}, - {"7.2.9", "Column indexes"}, - {"7.2.10", "Multiple-column indexes"}, - {"7.2.11", "Using column types from other database engines"}, - {"7.3", "Functions for use in SELECT and WHERE clauses"}, - {"7.3.1", "Grouping functions"}, - {"7.3.2", "Normal arithmetic operations"}, - {"7.3.3", "Bit functions"}, - {"7.3.4", "Logical operations"}, - {"7.3.5", "Comparison operators"}, - {"7.3.6", "String comparison functions"}, - {"7.3.7", "Control flow functions"}, - {"7.3.8", "Mathematical functions"}, - {"7.3.9", "String functions"}, - {"7.3.10", "Date and time functions"}, - {"7.3.11", "Miscellaneous functions"}, - {"7.3.12", "Functions for use with GROUP BY clauses"}, - {"7.4", "CREATE DATABASE syntax"}, - {"7.5", "DROP DATABASE syntax"}, - {"7.6", "CREATE TABLE syntax"}, - {"7.7", "ALTER TABLE syntax"}, - {"7.8", "OPTIMIZE TABLE syntax"}, - {"7.9", "DROP TABLE syntax"}, - {"7.10", "DELETE syntax"}, - {"7.11", "SELECT syntax"}, - {"7.12", "JOIN syntax"}, - {"7.13", "INSERT syntax"}, - {"7.14", "REPLACE syntax"}, - {"7.15", "LOAD DATA INFILE syntax"}, - {"7.16", "UPDATE syntax"}, - {"7.17", "USE syntax"}, - {"7.18", "SHOW syntax (Get information about tables, columns...)"}, - {"7.19", "EXPLAIN syntax (Get information about a SELECT)"}, - {"7.20", "DESCRIBE syntax (Get information about columns)"}, - {"7.21", "LOCK TABLES/UNLOCK TABLES syntax"}, - {"7.22", "SET OPTION syntax"}, - {"7.23", "GRANT syntax (Compatibility function)"}, - {"7.24", "CREATE INDEX syntax (Compatibility function)"}, - {"7.25", "DROP INDEX syntax (Compatibility function)"}, - {"7.26", "Comment syntax"}, - {"7.27", "CREATE FUNCTION/DROP FUNCTION syntax"}, - {"7.28", "Is MySQL picky about reserved words?"}, - {"8", "Example SQL queries"}, - {"8.1", "Queries from twin project"}, - {"8.1.1", "Find all non-distributed twins"}, - {"8.1.2", "Show a table on twin pair status"}, - {"9", "How safe/stable is MySQL?"}, - {"9.1", "How stable is MySQL?"}, - {"9.2", "Why are there is so many releases of MySQL?"}, - {"9.3", "Checking a table for errors"}, - {"9.4", "How to repair tables"}, - {"9.5", "Is there anything special to do when upgrading/downgrading MySQL?"}, - {"9.5.1", "Upgrading from a 3.21 version to 3.22"}, - {"9.5.2", "Upgrading from a 3.20 version to 3.21"}, - {"9.5.3", "Upgrading to another architecture"}, - {"9.6", "Year 2000 compliance"}, - {"10", "MySQL Server functions"}, - {"10.1", "What languages are supported by MySQL?"}, - {"10.1.1", "Character set used for data & sorting"}, - {"10.2", "The update log"}, - {"10.3", "How big can MySQL tables be?"}, - {"11", "Getting maximum performance from MySQL"}, - {"11.1", "How does one change the size of MySQL buffers?"}, - {"11.2", "How compiling and linking affects the speed of MySQL"}, - {"11.3", "How does MySQL use memory?"}, - {"11.4", "How does MySQL use indexes?"}, - {"11.5", "What optimizations are done on WHERE clauses?"}, - {"11.6", "How does MySQL open & close tables?"}, - {"11.6.0.1", "What are the drawbacks of creating possibly thousands of tables in a database?"}, - {"11.7", "How does MySQL lock tables?"}, - {"11.8", "How should I arrange my table to be as fast/small as possible?"}, - {"11.9", "What affects the speed of INSERT statements?"}, - {"11.10", "What affects the speed DELETE statements?"}, - {"11.11", "How do I get MySQL to run at full speed?"}, - {"11.12", "What are the different row formats? Or, when should VARCHAR/CHAR be used?"}, - {"11.13", "Why so many open tables?"}, - {"12", "MySQL benchmark suite"}, - {"13", "MySQL Utilites"}, - {"13.1", "Overview of the different MySQL programs"}, - {"13.2", "The MySQL table check, optimize and repair program"}, - {"13.2.1", "isamchk memory use"}, - {"13.2.2", "Getting low-level table information"}, - {"13.3", "The MySQL compressed read-only table generator"}, - {"14", "Adding new functions to MySQL"}, - {"15", "MySQL ODBC Support"}, - {"15.1", "Operating systems supported by MyODBC"}, - {"15.2", "How to report problems with MyODBC"}, - {"15.3", "Programs known to work with MyODBC"}, - {"15.4", "How to fill in the various fields in the ODBC administrator program"}, - {"15.5", "How to get the value of an AUTO_INCREMENT column in ODBC"}, - {"16", "Problems and common errors"}, - {"16.1", "Some common errors when using MySQL"}, - {"16.1.1", "MySQL server has gone away error"}, - {"16.1.2", "Can't connect to local MySQL server error"}, - {"16.1.3", "Out of memory error"}, - {"16.1.4", "Packet too large error"}, - {"16.1.5", "The table is full error"}, - {"16.1.6", "Commands out of sync error in client"}, - {"16.1.7", "Removing user error"}, - {"16.2", "How MySQL handles a full disk"}, - {"16.3", "How to run SQL commands from a text file"}, - {"16.4", "Where MySQL stores temporary files"}, - {"16.5", "Access denied error"}, - {"16.6", "How to run MySQL as a normal user"}, - {"16.7", "Problems with file permissions"}, - {"16.8", "File not found"}, - {"16.9", "Problems using DATE columns"}, - {"16.10", "Case sensitivity in searches"}, - {"16.11", "Problems with NULL values"}, - {"17", "Solving some common problems with MySQL"}, - {"17.1", "Database replication"}, - {"17.2", "Database backups"}, - {"18", "MySQL client tools and API's"}, - {"18.1", "MySQL C API"}, - {"18.2", "C API datatypes"}, - {"18.3", "C API function overview"}, - {"18.4", "C API function descriptions"}, - {"18.4.1", "mysql_affected_rows()"}, - {"18.4.2", "mysql_close()"}, - {"18.4.3", "mysql_connect()"}, - {"18.4.4", "mysql_create_db()"}, - {"18.4.5", "mysql_data_seek()"}, - {"18.4.6", "mysql_debug()"}, - {"18.4.7", "mysql_drop_db()"}, - {"18.4.8", "mysql_dump_debug_info()"}, - {"18.4.9", "mysql_eof()"}, - {"18.4.10", "mysql_errno()"}, - {"18.4.11", "mysql_error()"}, - {"18.4.12", "mysql_escape_string()"}, - {"18.4.13", "mysql_fetch_field()"}, - {"18.4.14", "mysql_fetch_fields()"}, - {"18.4.15", "mysql_fetch_field_direct()"}, - {"18.4.16", "mysql_fetch_lengths()"}, - {"18.4.17", "mysql_fetch_row()"}, - {"18.4.18", "mysql_field_seek()"}, - {"18.4.19", "mysql_field_tell()"}, - {"18.4.20", "mysql_free_result()"}, - {"18.4.21", "mysql_get_client_info()"}, - {"18.4.22", "mysql_get_host_info()"}, - {"18.4.23", "mysql_get_proto_info()"}, - {"18.4.24", "mysql_get_server_info()"}, - {"18.4.25", "mysql_info()"}, - {"18.4.26", "mysql_init()"}, - {"18.4.27", "mysql_insert_id()"}, - {"18.4.28", "mysql_kill()"}, - {"18.4.29", "mysql_list_dbs()"}, - {"18.4.30", "mysql_list_fields()"}, - {"18.4.31", "mysql_list_processes()"}, - {"18.4.32", "mysql_list_tables()"}, - {"18.4.33", "mysql_num_fields()"}, - {"18.4.34", "mysql_num_rows()"}, - {"18.4.35", "mysql_query()"}, - {"18.4.36", "mysql_real_connect()"}, - {"18.4.37", "mysql_real_query()"}, - {"18.4.38", "mysql_reload()"}, - {"18.4.39", "mysql_row_tell()"}, - {"18.4.40", "mysql_select_db()"}, - {"18.4.41", "mysql_shutdown()"}, - {"18.4.42", "mysql_stat()"}, - {"18.4.43", "mysql_store_result()"}, - {"18.4.44", "mysql_thread_id()"}, - {"18.4.45", "mysql_use_result()"}, - {"18.4.46", "Why is it that after mysql_query() returns success, mysql_store_result() sometimes returns NULL?"}, - {"18.4.47", "What results can I get from a query?"}, - {"18.4.48", "How can I get the unique ID for the last inserted row?"}, - {"18.4.49", "Problems linking with the C API"}, - {"18.4.50", "How to make a thread-safe client"}, - {"18.5", "MySQL Perl API's"}, - {"18.5.1", "DBI with DBD::mysql"}, - {"18.5.1.1", "The DBI interface"}, - {"18.5.1.2", "More DBI/DBD information"}, - {"18.6", "MySQL Java connectivity (JDBC)"}, - {"18.7", "MySQL PHP API's"}, - {"18.8", "MySQL C++ API's"}, - {"18.9", "MySQL Python API's"}, - {"18.10", "MySQL TCL API's"}, - {"19", "How MySQL compares to other databases"}, - {"19.1", "How MySQL compares to mSQL"}, - {"19.1.1", "How to convert mSQL tools for MySQL"}, - {"19.1.2", "How mSQL and MySQL client/server communications protocols differ"}, - {"19.1.3", "How mSQL 2.0 SQL syntax differs from MySQL"}, - {"19.2", "How MySQL compares to PostgreSQL"}, - {"A", "Some users of MySQL"}, - {"B", "Contributed programs"}, - {"C", "Contributors to MySQL"}, - {"D", "MySQL change history"}, - {"19.3", "Changes in release 3.22.x (Alpha version)"}, - {"19.3.1", "Changes in release 3.22.7"}, - {"19.3.2", "Changes in release 3.22.6"}, - {"19.3.3", "Changes in release 3.22.5"}, - {"19.3.4", "Changes in release 3.22.4"}, - {"19.3.5", "Changes in release 3.22.3"}, - {"19.3.6", "Changes in release 3.22.2"}, - {"19.3.7", "Changes in release 3.22.1"}, - {"19.3.8", "Changes in release 3.22.0"}, - {"19.4", "Changes in release 3.21.x"}, - {"19.4.1", "Changes in release 3.21.33"}, - {"19.4.2", "Changes in release 3.21.32"}, - {"19.4.3", "Changes in release 3.21.31"}, - {"19.4.4", "Changes in release 3.21.30"}, - {"19.4.5", "Changes in release 3.21.29"}, - {"19.4.6", "Changes in release 3.21.28"}, - {"19.4.7", "Changes in release 3.21.27"}, - {"19.4.8", "Changes in release 3.21.26"}, - {"19.4.9", "Changes in release 3.21.25"}, - {"19.4.10", "Changes in release 3.21.24"}, - {"19.4.11", "Changes in release 3.21.23"}, - {"19.4.12", "Changes in release 3.21.22"}, - {"19.4.13", "Changes in release 3.21.21a"}, - {"19.4.14", "Changes in release 3.21.21"}, - {"19.4.15", "Changes in release 3.21.20"}, - {"19.4.16", "Changes in release 3.21.19"}, - {"19.4.17", "Changes in release 3.21.18"}, - {"19.4.18", "Changes in release 3.21.17"}, - {"19.4.19", "Changes in release 3.21.16"}, - {"19.4.20", "Changes in release 3.21.15"}, - {"19.4.21", "Changes in release 3.21.14b"}, - {"19.4.22", "Changes in release 3.21.14a"}, - {"19.4.23", "Changes in release 3.21.13"}, - {"19.4.24", "Changes in release 3.21.12"}, - {"19.4.25", "Changes in release 3.21.11"}, - {"19.4.26", "Changes in release 3.21.10"}, - {"19.4.27", "Changes in release 3.21.9"}, - {"19.4.28", "Changes in release 3.21.8"}, - {"19.4.29", "Changes in release 3.21.7"}, - {"19.4.30", "Changes in release 3.21.6"}, - {"19.4.31", "Changes in release 3.21.5"}, - {"19.4.32", "Changes in release 3.21.4"}, - {"19.4.33", "Changes in release 3.21.3"}, - {"19.4.34", "Changes in release 3.21.2"}, - {"19.4.35", "Changes in release 3.21.0"}, - {"19.5", "Changes in release 3.20.x"}, - {"19.5.1", "Changes in release 3.20.18"}, - {"19.5.2", "Changes in release 3.20.17"}, - {"19.5.3", "Changes in release 3.20.16"}, - {"19.5.4", "Changes in release 3.20.15"}, - {"19.5.5", "Changes in release 3.20.14"}, - {"19.5.6", "Changes in release 3.20.13"}, - {"19.5.7", "Changes in release 3.20.11"}, - {"19.5.8", "Changes in release 3.20.10"}, - {"19.5.9", "Changes in release 3.20.9"}, - {"19.5.10", "Changes in release 3.20.8"}, - {"19.5.11", "Changes in release 3.20.7"}, - {"19.5.12", "Changes in release 3.20.6"}, - {"19.5.13", "Changes in release 3.20.3"}, - {"19.5.14", "Changes in release 3.20.0"}, - {"19.6", "Changes in release 3.19.x"}, - {"19.6.1", "Changes in release 3.19.5"}, - {"19.6.2", "Changes in release 3.19.4"}, - {"19.6.3", "Changes in release 3.19.3"}, - {"E", "Known errors and design deficiencies in MySQL"}, - {"F", "List of things we want to add to MySQL in the future (The TODO)"}, - {"19.7", "Things that must done in the real near future"}, - {"19.8", "Things that have to be done sometime"}, - {"19.9", "Some things we don't have any plans to do"}, - {"G", "Comments on porting to other systems"}, - {"19.10", "Debugging MySQL"}, - {"19.11", "Comments about RTS threads"}, - {"19.12", "What is the difference between different thread packages?"}, - {"H", "Description of MySQL regular expression syntax"}, - {"I", "What is Unireg?"}, - {"J", "The MySQL server license"}, - {"K", "The MySQL license for Microsoft operating systems"}, - {"*", "SQL command, type and function index"}, - {"*", "Concept Index"} -}; - -#define NQUERIES 5 -const char *query[NQUERIES]={ - "mysql information and manual", - "upgrading from previous version", - "column indexes", - "against about after more right the with/without", /* stopwords test */ - "mysql license and copyright" -}; diff --git a/myisam/ft_update.c b/myisam/ft_update.c deleted file mode 100644 index b8cd925bf4f..00000000000 --- a/myisam/ft_update.c +++ /dev/null @@ -1,350 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ - -/* functions to work with full-text indices */ - -#include "ftdefs.h" -#include <math.h> - -void _mi_ft_segiterator_init(MI_INFO *info, uint keynr, const byte *record, - FT_SEG_ITERATOR *ftsi) -{ - DBUG_ENTER("_mi_ft_segiterator_init"); - - ftsi->num=info->s->keyinfo[keynr].keysegs; - ftsi->seg=info->s->keyinfo[keynr].seg; - ftsi->rec=record; - DBUG_VOID_RETURN; -} - -void _mi_ft_segiterator_dummy_init(const byte *record, uint len, - FT_SEG_ITERATOR *ftsi) -{ - DBUG_ENTER("_mi_ft_segiterator_dummy_init"); - - ftsi->num=1; - ftsi->seg=0; - ftsi->pos=record; - ftsi->len=len; - DBUG_VOID_RETURN; -} - -/* - This function breaks convention "return 0 in success" - but it's easier to use like this - - while(_mi_ft_segiterator()) - - so "1" means "OK", "0" means "EOF" -*/ - -uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi) -{ - DBUG_ENTER("_mi_ft_segiterator"); - - if (!ftsi->num) - DBUG_RETURN(0); - - ftsi->num--; - if (!ftsi->seg) - DBUG_RETURN(1); - - ftsi->seg--; - - if (ftsi->seg->null_bit && - (ftsi->rec[ftsi->seg->null_pos] & ftsi->seg->null_bit)) - { - ftsi->pos=0; - DBUG_RETURN(1); - } - ftsi->pos= ftsi->rec+ftsi->seg->start; - if (ftsi->seg->flag & HA_VAR_LENGTH_PART) - { - uint pack_length= (ftsi->seg->bit_start); - ftsi->len= (pack_length == 1 ? (uint) *(uchar*) ftsi->pos : - uint2korr(ftsi->pos)); - ftsi->pos+= pack_length; /* Skip VARCHAR length */ - DBUG_RETURN(1); - } - if (ftsi->seg->flag & HA_BLOB_PART) - { - ftsi->len=_mi_calc_blob_length(ftsi->seg->bit_start,ftsi->pos); - memcpy_fixed((char*) &ftsi->pos, ftsi->pos+ftsi->seg->bit_start, - sizeof(char*)); - DBUG_RETURN(1); - } - ftsi->len=ftsi->seg->length; - DBUG_RETURN(1); -} - - -/* parses a document i.e. calls ft_parse for every keyseg */ - -uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, - const byte *record, my_bool with_alloc) -{ - FT_SEG_ITERATOR ftsi; - DBUG_ENTER("_mi_ft_parse"); - - _mi_ft_segiterator_init(info, keynr, record, &ftsi); - - ft_parse_init(parsed, info->s->keyinfo[keynr].seg->charset); - while (_mi_ft_segiterator(&ftsi)) - { - if (ftsi.pos) - if (ft_parse(parsed, (byte *)ftsi.pos, ftsi.len, with_alloc)) - DBUG_RETURN(1); - } - DBUG_RETURN(0); -} - -FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, const byte *record) -{ - TREE ptree; - DBUG_ENTER("_mi_ft_parserecord"); - - bzero((char*) &ptree, sizeof(ptree)); - if (_mi_ft_parse(&ptree, info, keynr, record,0)) - DBUG_RETURN(NULL); - - DBUG_RETURN(ft_linearize(&ptree)); -} - -static int _mi_ft_store(MI_INFO *info, uint keynr, byte *keybuf, - FT_WORD *wlist, my_off_t filepos) -{ - uint key_length; - DBUG_ENTER("_mi_ft_store"); - - for (; wlist->pos; wlist++) - { - key_length=_ft_make_key(info,keynr,keybuf,wlist,filepos); - if (_mi_ck_write(info,keynr,(uchar*) keybuf,key_length)) - DBUG_RETURN(1); - } - DBUG_RETURN(0); -} - -static int _mi_ft_erase(MI_INFO *info, uint keynr, byte *keybuf, - FT_WORD *wlist, my_off_t filepos) -{ - uint key_length, err=0; - DBUG_ENTER("_mi_ft_erase"); - - for (; wlist->pos; wlist++) - { - key_length=_ft_make_key(info,keynr,keybuf,wlist,filepos); - if (_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length)) - err=1; - } - DBUG_RETURN(err); -} - -/* - Compares an appropriate parts of two WORD_KEY keys directly out of records - returns 1 if they are different -*/ - -#define THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT 1 -#define GEE_THEY_ARE_ABSOLUTELY_IDENTICAL 0 - -int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2) -{ - FT_SEG_ITERATOR ftsi1, ftsi2; - CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset; - DBUG_ENTER("_mi_ft_cmp"); - - _mi_ft_segiterator_init(info, keynr, rec1, &ftsi1); - _mi_ft_segiterator_init(info, keynr, rec2, &ftsi2); - - while (_mi_ft_segiterator(&ftsi1) && _mi_ft_segiterator(&ftsi2)) - { - if ((ftsi1.pos != ftsi2.pos) && - (!ftsi1.pos || !ftsi2.pos || - mi_compare_text(cs, (uchar*) ftsi1.pos,ftsi1.len, - (uchar*) ftsi2.pos,ftsi2.len,0,0))) - DBUG_RETURN(THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT); - } - DBUG_RETURN(GEE_THEY_ARE_ABSOLUTELY_IDENTICAL); -} - - -/* update a document entry */ - -int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf, - const byte *oldrec, const byte *newrec, my_off_t pos) -{ - int error= -1; - FT_WORD *oldlist,*newlist, *old_word, *new_word; - CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset; - uint key_length; - int cmp, cmp2; - DBUG_ENTER("_mi_ft_update"); - - if (!(old_word=oldlist=_mi_ft_parserecord(info, keynr, oldrec))) - goto err0; - if (!(new_word=newlist=_mi_ft_parserecord(info, keynr, newrec))) - goto err1; - - error=0; - while(old_word->pos && new_word->pos) - { - cmp= mi_compare_text(cs, (uchar*) old_word->pos,old_word->len, - (uchar*) new_word->pos,new_word->len,0,0); - cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5); - - if (cmp < 0 || cmp2) - { - key_length=_ft_make_key(info,keynr,keybuf,old_word,pos); - if ((error=_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length))) - goto err2; - } - if (cmp > 0 || cmp2) - { - key_length=_ft_make_key(info,keynr,keybuf,new_word,pos); - if ((error=_mi_ck_write(info,keynr,(uchar*) keybuf,key_length))) - goto err2; - } - if (cmp<=0) old_word++; - if (cmp>=0) new_word++; - } - if (old_word->pos) - error=_mi_ft_erase(info,keynr,keybuf,old_word,pos); - else if (new_word->pos) - error=_mi_ft_store(info,keynr,keybuf,new_word,pos); - -err2: - my_free((char*) newlist,MYF(0)); -err1: - my_free((char*) oldlist,MYF(0)); -err0: - DBUG_RETURN(error); -} - - -/* adds a document to the collection */ - -int _mi_ft_add(MI_INFO *info, uint keynr, byte *keybuf, const byte *record, - my_off_t pos) -{ - int error= -1; - FT_WORD *wlist; - DBUG_ENTER("_mi_ft_add"); - - if ((wlist=_mi_ft_parserecord(info, keynr, record))) - { - error=_mi_ft_store(info,keynr,keybuf,wlist,pos); - my_free((char*) wlist,MYF(0)); - } - DBUG_RETURN(error); -} - - -/* removes a document from the collection */ - -int _mi_ft_del(MI_INFO *info, uint keynr, byte *keybuf, const byte *record, - my_off_t pos) -{ - int error= -1; - FT_WORD *wlist; - DBUG_ENTER("_mi_ft_del"); - DBUG_PRINT("enter",("keynr: %d",keynr)); - - if ((wlist=_mi_ft_parserecord(info, keynr, record))) - { - error=_mi_ft_erase(info,keynr,keybuf,wlist,pos); - my_free((char*) wlist,MYF(0)); - } - DBUG_PRINT("exit",("Return: %d",error)); - DBUG_RETURN(error); -} - -uint _ft_make_key(MI_INFO *info, uint keynr, byte *keybuf, FT_WORD *wptr, - my_off_t filepos) -{ - byte buf[HA_FT_MAXBYTELEN+16]; - DBUG_ENTER("_ft_make_key"); - -#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT - { - float weight=(float) ((filepos==HA_OFFSET_ERROR) ? 0 : wptr->weight); - mi_float4store(buf,weight); - } -#else -#error -#endif - - int2store(buf+HA_FT_WLEN,wptr->len); - memcpy(buf+HA_FT_WLEN+2,wptr->pos,wptr->len); - DBUG_RETURN(_mi_make_key(info,keynr,(uchar*) keybuf,buf,filepos)); -} - - -/* - convert key value to ft2 -*/ - -uint _mi_ft_convert_to_ft2(MI_INFO *info, uint keynr, uchar *key) -{ - my_off_t root; - DYNAMIC_ARRAY *da=info->ft1_to_ft2; - MI_KEYDEF *keyinfo=&info->s->ft2_keyinfo; - uchar *key_ptr= (uchar*) dynamic_array_ptr(da, 0), *end; - uint length, key_length; - DBUG_ENTER("_mi_ft_convert_to_ft2"); - - /* we'll generate one pageful at once, and insert the rest one-by-one */ - /* calculating the length of this page ...*/ - length=(keyinfo->block_length-2) / keyinfo->keylength; - set_if_smaller(length, da->elements); - length=length * keyinfo->keylength; - - get_key_full_length_rdonly(key_length, key); - while (_mi_ck_delete(info, keynr, key, key_length) == 0) - { - /* - nothing to do here. - _mi_ck_delete() will populate info->ft1_to_ft2 with deleted keys - */ - } - - /* creating pageful of keys */ - mi_putint(info->buff,length+2,0); - memcpy(info->buff+2, key_ptr, length); - info->buff_used=info->page_changed=1; /* info->buff is used */ - if ((root= _mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR || - _mi_write_keypage(info,keyinfo,root,DFLT_INIT_HITS,info->buff)) - DBUG_RETURN(-1); - - /* inserting the rest of key values */ - end= (uchar*) dynamic_array_ptr(da, da->elements); - for (key_ptr+=length; key_ptr < end; key_ptr+=keyinfo->keylength) - if(_mi_ck_real_write_btree(info, keyinfo, key_ptr, 0, &root, SEARCH_SAME)) - DBUG_RETURN(-1); - - /* now, writing the word key entry */ - ft_intXstore(key+key_length, - (int) da->elements); - _mi_dpointer(info, key+key_length+HA_FT_WLEN, root); - - DBUG_RETURN(_mi_ck_real_write_btree(info, - info->s->keyinfo+keynr, - key, 0, - &info->s->state.key_root[keynr], - SEARCH_SAME)); -} - diff --git a/myisam/ftbench/Ecompare.pl b/myisam/ftbench/Ecompare.pl deleted file mode 100755 index 265534e704d..00000000000 --- a/myisam/ftbench/Ecompare.pl +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/perl - -# compares out-files (as created by Ereport.pl) from dir1/*.out and dir2/*.out -# for each effectiveness column computes the probability of the hypothesis -# "Both files have the same effectiveness" - -# sign test is used to verify that test results are statistically -# significant to support the hypothesis. Function is computed on the fly. - -# basic formula is \sum_{r=0}^R C_N^r 2^{-N} -# As N can be big, we'll work with logarithms -$log2=log(2); -sub probab { - my $N=shift, $R=shift; - - my $r, $sum=0; - - for $r (0..$R) { - $sum+=exp(logfac($N)-logfac($r)-logfac($N-$r)-$N*$log2); - } - return $sum; -} - -# log(N!) -# for N<20 exact value from the table (below) is taken -# otherwise, Stirling approximation for N! is used -sub logfac { - my $n=shift; die "n=$n<0" if $n<0; - return $logfactab[$n] if $n<=$#logfactab; - return $n*log($n)-$n+log(2*3.14159265358*$n)/2; -} -@logfactab=( -0, 0, 0.693147180559945, 1.79175946922805, 3.17805383034795, -4.78749174278205, 6.57925121201010, 8.52516136106541, 10.6046029027453, -12.8018274800815, 15.1044125730755, 17.5023078458739, 19.9872144956619, -22.5521638531234, 25.1912211827387, 27.8992713838409, 30.6718601060807, -33.5050734501369, 36.3954452080331, 39.3398841871995, 42.3356164607535, -); - -############################# main () ############################### -#$p=shift; $m=shift; $p-=$m; -#if($p>$m) { -# print "1 > 2 [+$p-$m]: ", probab($p+$m, $m), "\n"; -#} elsif($p<$m) { -# print "1 < 2 [+$p-$m]: ", probab($p+$m, $p), "\n"; -#} else { -# print "1 = 2 [+$p-$m]: ", probab($p+$m, $m), "\n"; -#} -#exit; - -die "Use: $0 dir1 dir2\n" unless @ARGV==2 && - -d ($dir1=shift) && -d ($dir2=shift); -$_=`cd $dir1; echo *.out`; -s/\.out\b//g; -$total=""; - -for $file (split) { - open(OUT1,$out1="$dir1/$file.out") || die "Cannot open $out1: $!"; - open(OUT2,$out2="$dir2/$file.out") || die "Cannot open $out2: $!"; - - @p=@m=(); - while(!eof(OUT1) || !eof(OUT2)) { - $_=<OUT1>; @l1=split; shift @l1; - $_=<OUT2>; @l2=split; shift @l2; - - die "Number of columns differ in line $.\n" unless $#l1 == $#l2; - - for (0..$#l1) { - $p[$_]+= $l1[$_] > $l2[$_]; - $m[$_]+= $l1[$_] < $l2[$_]; - } - } - - for (0..$#l1) { - $pp[$_]+=$p[$_]; $mm[$_]+=$m[$_]; - $total[$_].=rep($file, ($#l1 ? $_ : undef), $p[$_], $m[$_]); - } - close OUT1; - close OUT2; -} - -for (0..$#l1) { - rep($total[$_], ($#l1 ? $_ : undef), $pp[$_], $mm[$_]); -} - -sub rep { - my ($test, $n, $p, $m, $c, $r)=@_; - - if ($p>$m) { $c=">"; $r="+"; } - elsif($p<$m) { $c="<"; $r="-"; } - else { $c="="; $r="="; } - $n=" $n: " if defined $n; - printf "%-8s $n $dir1 $c $dir2 [+%03d-%03d]: %16.15f\n", - $test, $p, $m, probab($p+$m, ($p>=$m ? $m : $p)); - $r; -} diff --git a/myisam/ftbench/Ecreate.pl b/myisam/ftbench/Ecreate.pl deleted file mode 100755 index d90a6f7a0ad..00000000000 --- a/myisam/ftbench/Ecreate.pl +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/perl - -$test=shift || die "Usage $0 testname [option]"; -$option=shift; - -open(D, "<data/$test.d") || die "Cannot open(<data/$test.d): $!"; -open(Q, "<data/$test.q") || die "Cannot open(<data/$test.q): $!"; - -$N=0; - -print <<__HEADER__; -DROP TABLE IF EXISTS $test; -CREATE TABLE $test ( - id int(10) unsigned NOT NULL, - text text NOT NULL, - FULLTEXT KEY text (text) -) TYPE=MyISAM CHARSET=latin1; - -ALTER TABLE $test DISABLE KEYS; -__HEADER__ - -while (<D>) { chomp; - s/'/\\'/g; ++$N; - print "INSERT $test VALUES ($N, '$_');\n"; -} - -print <<__PREP__; -ALTER TABLE $test ENABLE KEYS; -SELECT $N; -__PREP__ - -$N=0; - -while (<Q>) { chomp; - s/'/\\'/g; ++$N; - $_="MATCH text AGAINST ('$_' $option)"; - print "SELECT $N, id, $_ FROM $test WHERE $_;\n"; -} - -print <<__FOOTER__; -DROP TABLE $test; -__FOOTER__ - - diff --git a/myisam/ftbench/Ereport.pl b/myisam/ftbench/Ereport.pl deleted file mode 100755 index 5969304da09..00000000000 --- a/myisam/ftbench/Ereport.pl +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/perl - -die "Use: $0 eval_output qrels_file\n" unless @ARGV==2; - -open(EOUT,$eout=shift) || die "Cannot open $eout: $!"; -open(RELJ,$relj=shift) || die "Cannot open $relj: $!"; - -$_=<EOUT>; -die "$eout must start with a number!\n "unless /^[1-9][0-9]*\n/; -$ndocs=$_+0; - -$qid=0; -$relj_str=<RELJ>; -$eout_str=<EOUT>; - -while(!eof(RELJ) || !eof(EOUT)) { - ++$qid; - %dq=(); - $A=$B=$AB=0; - $Ravg=$Pavg=0; - - while($relj_str =~ /^0*$qid\s+(\d+)/) { - ++$A; - $dq{$1+0}=1; - last unless $relj_str=<RELJ>; - } - # Favg measure = 1/(a/Pavg+(1-a)/Ravg) -sub Favg { my $a=shift; $Pavg*$Ravg ? 1/($a/$Pavg+(1-$a)/$Ravg) : 0; } - # F0 : a=0 -- ignore precision - # F5 : a=0.5 - # F1 : a=1 -- ignore recall - while($eout_str =~ /^$qid\s+(\d+)\s+(\d+(?:\.\d+)?)/) { - $B++; - $AB++ if $dq{$1+0}; - $Ravg+=$AB; - $Pavg+=$AB/$B; - last unless $eout_str=<EOUT>; - } - next unless $A; - - $Ravg/=$B*$A if $B; - $Pavg/=$B if $B; - - printf "%5d %1.12f %1.12f %1.12f\n", $qid, Favg(0),Favg(0.5),Favg(1); -} - -exit 0; - - diff --git a/myisam/ftbench/README b/myisam/ftbench/README deleted file mode 100644 index b1f8b66b15f..00000000000 --- a/myisam/ftbench/README +++ /dev/null @@ -1,43 +0,0 @@ -1. should be run from myisam/ftbench/ -2. myisam/ftdefs.h should NOT be locked (bk get, not bk edit!) -3. there should be ./data/ subdir with test collections, files: - test1.d - test1.q - test1.r - test2.d - test2.q - test2.r - where test1, test2, etc - are arbitrary test names - - *.[dq] files contain documents/queries one item per line. - - *.r files have the structure: - 1 16 .....blablabla - 1 09 .....blablabla - 2 116 .....blablabla - ... - - that is /^\d+\s+\d+/ - and are sorted by the first number (not necessarily by the second) - -4. there should be ./t/ subdir with test directories - - ./t - ./t/BEST/ - ./t/testdir1/ - ./t/testdir2/ - ... - - there *must* be ./t/BEST/ subdir or a symlink to one of other dirs in ./t - all other names (besides BEST) can be arbitrary - - all test results are compared with BEST results. - - test directories may contain ftdefs.h, my.cnf, ft_mode - (the last one is used as in ... MATCH ... AGAINST ("..." $ft_mode) ...) - NOTE: all *.out files in test directories will NOT be overwritten! - delete them to re-test - -5. run ./ft-test-run.sh -6. go make some coffee - diff --git a/myisam/ftbench/ft-test-run.sh b/myisam/ftbench/ft-test-run.sh deleted file mode 100755 index ceba818fa5c..00000000000 --- a/myisam/ftbench/ft-test-run.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/sh - -if [ ! -x ./ft-test-run.sh ] ; then - echo "Usage: ./ft-test-run.sh" - exit 1 -fi - -BASE=`pwd` -DATA=$BASE/var -ROOT=`cd ../..; pwd` -MYSQLD=$ROOT/sql/mysqld -MYSQL=$ROOT/client/mysql -MYSQLADMIN=$ROOT/client/mysqladmin -SOCK=$DATA/mysql.sock -PID=$DATA/mysql.pid -H=../ftdefs.h -OPTS="--no-defaults --socket=$SOCK --character-sets-dir=$ROOT/sql/share/charsets" -DELAY=10 - -stop_myslqd() -{ - [ -S $SOCK ] && $MYSQLADMIN $OPTS shutdown - [ -f $PID ] && kill `cat $PID` && sleep 15 && [ -f $PID ] && kill -9 `cat $PID` -} - -if [ ! -d t/BEST ] ; then - echo "No ./t/BEST directory! Aborting..." - exit 1 -fi -rm -f t/BEST/report.txt -if [ -w $H ] ; then - echo "$H is writeable! Aborting..." - exit 1 -fi - -stop_myslqd -rm -rf var > /dev/null 2>&1 -mkdir var -mkdir var/test - -for batch in t/* ; do - [ ! -d $batch ] && continue - [ $batch -ef t/BEST -a $batch != t/BEST ] && continue - - rm -rf var/test/* > /dev/null 2>&1 - rm -f $H - if [ -f $BASE/$batch/ftdefs.h ] ; then - cat $BASE/$batch/ftdefs.h > $H - chmod a-wx $H - else - bk get -q $H - fi - OPTS="--defaults-file=$BASE/$batch/my.cnf --socket=$SOCK --character-sets-dir=$ROOT/sql/share/charsets" - stop_myslqd - rm -f $MYSQLD - echo "building $batch" - echo "============== $batch ===============" >> var/ft_test.log - (cd $ROOT; gmake) >> var/ft_test.log 2>&1 - - for prog in $MYSQLD $MYSQL $MYSQLADMIN ; do - if [ ! -x $prog ] ; then - echo "build failed: no $prog" - exit 1 - fi - done - - echo "=====================================" >> var/ft_test.log - $MYSQLD $OPTS --basedir=$BASE --skip-bdb --pid-file=$PID \ - --language=$ROOT/sql/share/english \ - --skip-grant-tables --skip-innodb \ - --skip-networking --tmpdir=$DATA >> var/ft_test.log 2>&1 & - - sleep $DELAY - $MYSQLADMIN $OPTS ping - if [ $? != 0 ] ; then - echo "$MYSQLD refused to start" - exit 1 - fi - for test in `cd data; echo *.r|sed "s/\.r//g"` ; do - if [ -f $batch/$test.out ] ; then - echo "skipping $batch/$test.out" - continue - fi - echo "testing $batch/$test" - FT_MODE=`cat $batch/ft_mode 2>/dev/null` - ./Ecreate.pl $test "$FT_MODE" | $MYSQL $OPTS --skip-column-names test >var/$test.eval - echo "reporting $batch/$test" - ./Ereport.pl var/$test.eval data/$test.r > $batch/$test.out || exit - done - stop_myslqd - rm -f $H - bk get -q $H - if [ ! $batch -ef t/BEST ] ; then - echo "comparing $batch" - ./Ecompare.pl t/BEST $batch >> t/BEST/report.txt - fi -done - diff --git a/myisam/ftdefs.h b/myisam/ftdefs.h deleted file mode 100644 index 91c679a1e58..00000000000 --- a/myisam/ftdefs.h +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ - -/* some definitions for full-text indices */ - -#include "fulltext.h" -#include <m_ctype.h> -#include <my_tree.h> -#include <queues.h> - -#define true_word_char(s,X) (my_isalnum(s,X) || (X)=='_') -#define misc_word_char(X) ((X)=='\'') -#define word_char(s,X) (true_word_char(s,X) || misc_word_char(X)) - -#define FT_MAX_WORD_LEN_FOR_SORT 31 - -#define COMPILE_STOPWORDS_IN - -/* Interested readers may consult SMART - (ftp://ftp.cs.cornell.edu/pub/smart/smart.11.0.tar.Z) - for an excellent implementation of vector space model we use. - It also demonstrate the usage of different weghting techniques. - This code, though, is completely original and is not based on the - SMART code but was in some cases inspired by it. - - NORM_PIVOT was taken from the article - A.Singhal, C.Buckley, M.Mitra, "Pivoted Document Length Normalization", - ACM SIGIR'96, 21-29, 1996 - */ - -#define LWS_FOR_QUERY LWS_TF -#define LWS_IN_USE LWS_LOG -#define PRENORM_IN_USE PRENORM_AVG -#define NORM_IN_USE NORM_PIVOT -#define GWS_IN_USE GWS_PROB -/*==============================================================*/ -#define LWS_TF (count) -#define LWS_BINARY (count>0) -#define LWS_SQUARE (count*count) -#define LWS_LOG (count?(log( (double) count)+1):0) -/*--------------------------------------------------------------*/ -#define PRENORM_NONE (p->weight) -#define PRENORM_MAX (p->weight/docstat.max) -#define PRENORM_AUG (0.4+0.6*p->weight/docstat.max) -#define PRENORM_AVG (p->weight/docstat.sum*docstat.uniq) -#define PRENORM_AVGLOG ((1+log(p->weight))/(1+log(docstat.sum/docstat.uniq))) -/*--------------------------------------------------------------*/ -#define NORM_NONE (1) -#define NORM_SUM (docstat.nsum) -#define NORM_COS (sqrt(docstat.nsum2)) - -#define PIVOT_VAL (0.0115) -#define NORM_PIVOT (1+PIVOT_VAL*docstat.uniq) -/*---------------------------------------------------------------*/ -#define GWS_NORM (1/sqrt(sum2)) -#define GWS_GFIDF (sum/doc_cnt) -/* Mysterious, but w/o (double) GWS_IDF performs better :-o */ -#define GWS_IDF log(aio->info->state->records/doc_cnt) -#define GWS_IDF1 log((double)aio->info->state->records/doc_cnt) -#define GWS_PROB ((aio->info->state->records > doc_cnt) ? log(((double)(aio->info->state->records-doc_cnt))/doc_cnt) : 0 ) -#define GWS_FREQ (1.0/doc_cnt) -#define GWS_SQUARED pow(log((double)aio->info->state->records/doc_cnt),2) -#define GWS_CUBIC pow(log((double)aio->info->state->records/doc_cnt),3) -#define GWS_ENTROPY (1-(suml/sum-log(sum))/log(aio->info->state->records)) -/*=================================================================*/ - -/* Boolean search operators */ -#define FTB_YES (ft_boolean_syntax[0]) -#define FTB_EGAL (ft_boolean_syntax[1]) -#define FTB_NO (ft_boolean_syntax[2]) -#define FTB_INC (ft_boolean_syntax[3]) -#define FTB_DEC (ft_boolean_syntax[4]) -#define FTB_LBR (ft_boolean_syntax[5]) -#define FTB_RBR (ft_boolean_syntax[6]) -#define FTB_NEG (ft_boolean_syntax[7]) -#define FTB_TRUNC (ft_boolean_syntax[8]) -#define FTB_LQUOT (ft_boolean_syntax[10]) -#define FTB_RQUOT (ft_boolean_syntax[11]) - -typedef struct st_ft_word { - byte * pos; - uint len; - double weight; -} FT_WORD; - -typedef struct st_ftb_param { - byte prev; - int yesno; - int plusminus; - bool pmsign; - bool trunc; - byte *quot; -} FTB_PARAM; - -int is_stopword(char *word, uint len); - -uint _ft_make_key(MI_INFO *, uint , byte *, FT_WORD *, my_off_t); - -byte ft_get_word(CHARSET_INFO *, byte **, byte *, FT_WORD *, FTB_PARAM *); -byte ft_simple_get_word(CHARSET_INFO *, byte **, const byte *, - FT_WORD *, my_bool); - -typedef struct _st_ft_seg_iterator { - uint num, len; - HA_KEYSEG *seg; - const byte *rec, *pos; -} FT_SEG_ITERATOR; - -void _mi_ft_segiterator_init(MI_INFO *, uint, const byte *, FT_SEG_ITERATOR *); -void _mi_ft_segiterator_dummy_init(const byte *, uint, FT_SEG_ITERATOR *); -uint _mi_ft_segiterator(FT_SEG_ITERATOR *); - -void ft_parse_init(TREE *, CHARSET_INFO *); -int ft_parse(TREE *, byte *, int, my_bool); -FT_WORD * ft_linearize(TREE *); -FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, const byte *); -uint _mi_ft_parse(TREE *, MI_INFO *, uint, const byte *, my_bool); - -FT_INFO *ft_init_nlq_search(MI_INFO *, uint, byte *, uint, uint, byte *); -FT_INFO *ft_init_boolean_search(MI_INFO *, uint, byte *, uint, CHARSET_INFO *); - -extern const struct _ft_vft _ft_vft_nlq; -int ft_nlq_read_next(FT_INFO *, char *); -float ft_nlq_find_relevance(FT_INFO *, byte *, uint); -void ft_nlq_close_search(FT_INFO *); -float ft_nlq_get_relevance(FT_INFO *); -my_off_t ft_nlq_get_docid(FT_INFO *); -void ft_nlq_reinit_search(FT_INFO *); - -extern const struct _ft_vft _ft_vft_boolean; -int ft_boolean_read_next(FT_INFO *, char *); -float ft_boolean_find_relevance(FT_INFO *, byte *, uint); -void ft_boolean_close_search(FT_INFO *); -float ft_boolean_get_relevance(FT_INFO *); -my_off_t ft_boolean_get_docid(FT_INFO *); -void ft_boolean_reinit_search(FT_INFO *); - diff --git a/myisam/fulltext.h b/myisam/fulltext.h deleted file mode 100644 index d8c74d4e94b..00000000000 --- a/myisam/fulltext.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code */ - -/* some definitions for full-text indices */ - -#include "myisamdef.h" -#include "ft_global.h" - -#define HA_FT_WTYPE HA_KEYTYPE_FLOAT -#define HA_FT_WLEN 4 -#define FT_SEGS 2 - -#define ft_sintXkorr(A) mi_sint4korr(A) -#define ft_intXstore(T,A) mi_int4store(T,A) - -extern const HA_KEYSEG ft_keysegs[FT_SEGS]; - -int _mi_ft_cmp(MI_INFO *, uint, const byte *, const byte *); -int _mi_ft_add(MI_INFO *, uint, byte *, const byte *, my_off_t); -int _mi_ft_del(MI_INFO *, uint, byte *, const byte *, my_off_t); - -uint _mi_ft_convert_to_ft2(MI_INFO *, uint, uchar *); - diff --git a/myisam/make-ccc b/myisam/make-ccc deleted file mode 100755 index 6d1303729db..00000000000 --- a/myisam/make-ccc +++ /dev/null @@ -1,5 +0,0 @@ -rm -f .deps/*.P -ccc -DMAP_TO_USE_RAID -I./../include -I../include -DDBUG_OFF -fast -O3 -c mi_cache.c mi_changed.c mi_checksum.c mi_close.c mi_create.c mi_dbug.c mi_delete.c mi_delete_all.c mi_delete_table.c mi_dynrec.c mi_extra.c mi_info.c mi_key.c mi_locking.c mi_log.c mi_open.c mi_packrec.c mi_page.c mi_panic.c mi_range.c mi_rename.c mi_rfirst.c mi_rkey.c mi_rlast.c mi_rnext.c mi_rnext_same.c mi_rprev.c mi_rrnd.c mi_rsame.c mi_rsamepos.c mi_scan.c mi_search.c mi_static.c mi_statrec.c mi_unique.c mi_update.c mi_write.c ft_update.c ft_search.o ft_stem.o ft_stopwords.c ft_parser.c -make sort.o mi_check.o -rm libmyisam.a -ar -cr libmyisam.a mi_cache.o sort.o mi_check.o diff --git a/myisam/mi_cache.c b/myisam/mi_cache.c deleted file mode 100644 index 8dee068c50e..00000000000 --- a/myisam/mi_cache.c +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Functions for read record cacheing with myisam - Used for reading dynamic/compressed records from datafile. - - Can fetch data directly from file (outside cache), - if reading a small chunk straight before the cached part (with possible - overlap). - - Can be explicitly asked not to use cache (by not setting READING_NEXT in - flag) - useful for occasional out-of-cache reads, when the next read is - expected to hit the cache again. - - Allows "partial read" errors in the record header (when READING_HEADER flag - is set) - unread part is bzero'ed - - Note: out-of-cache reads are enabled for shared IO_CACHE's too, - as these reads will be cached by OS cache (and my_pread is always atomic) -*/ - - -#include "myisamdef.h" - -int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length, - int flag) -{ - uint read_length,in_buff_length; - my_off_t offset; - char *in_buff_pos; - DBUG_ENTER("_mi_read_cache"); - - if (pos < info->pos_in_file) - { - read_length=length; - if ((my_off_t) read_length > (my_off_t) (info->pos_in_file-pos)) - read_length=(uint) (info->pos_in_file-pos); - info->seek_not_done=1; - if (my_pread(info->file,buff,read_length,pos,MYF(MY_NABP))) - DBUG_RETURN(1); - if (!(length-=read_length)) - DBUG_RETURN(0); - pos+=read_length; - buff+=read_length; - } - if (pos >= info->pos_in_file && - (offset= (my_off_t) (pos - info->pos_in_file)) < - (my_off_t) (info->read_end - info->request_pos)) - { - in_buff_pos=info->request_pos+(uint) offset; - in_buff_length= min(length,(uint) (info->read_end-in_buff_pos)); - memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length); - if (!(length-=in_buff_length)) - DBUG_RETURN(0); - pos+=in_buff_length; - buff+=in_buff_length; - } - else - in_buff_length=0; - if (flag & READING_NEXT) - { - if (pos != (info->pos_in_file + - (uint) (info->read_end - info->request_pos))) - { - info->pos_in_file=pos; /* Force start here */ - info->read_pos=info->read_end=info->request_pos; /* Everything used */ - info->seek_not_done=1; - } - else - info->read_pos=info->read_end; /* All block used */ - if (!(*info->read_function)(info,buff,length)) - DBUG_RETURN(0); - read_length=info->error; - } - else - { - info->seek_not_done=1; - if ((read_length=my_pread(info->file,buff,length,pos,MYF(0))) == length) - DBUG_RETURN(0); - } - if (!(flag & READING_HEADER) || (int) read_length == -1 || - read_length+in_buff_length < 3) - { - DBUG_PRINT("error", - ("Error %d reading next-multi-part block (Got %d bytes)", - my_errno, (int) read_length)); - if (!my_errno || my_errno == -1) - my_errno=HA_ERR_WRONG_IN_RECORD; - DBUG_RETURN(1); - } - bzero(buff+read_length,MI_BLOCK_INFO_HEADER_LENGTH - in_buff_length - - read_length); - DBUG_RETURN(0); -} /* _mi_read_cache */ diff --git a/myisam/mi_changed.c b/myisam/mi_changed.c deleted file mode 100644 index c2ab5568eba..00000000000 --- a/myisam/mi_changed.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Check if somebody has changed table since last check. */ - -#include "myisamdef.h" - - /* Return 0 if table isn't changed */ - -int mi_is_changed(MI_INFO *info) -{ - int result; - DBUG_ENTER("mi_is_changed"); - if (fast_mi_readinfo(info)) - DBUG_RETURN(-1); - VOID(_mi_writeinfo(info,0)); - result=(int) info->data_changed; - info->data_changed=0; - DBUG_PRINT("exit",("result: %d",result)); - DBUG_RETURN(result); -} diff --git a/myisam/mi_check.c b/myisam/mi_check.c deleted file mode 100644 index dd8cc736741..00000000000 --- a/myisam/mi_check.c +++ /dev/null @@ -1,4082 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Describe, check and repair of MyISAM tables */ - -#include "ftdefs.h" -#include <m_ctype.h> -#include <stdarg.h> -#include <my_getopt.h> -#ifdef HAVE_SYS_VADVISE_H -#include <sys/vadvise.h> -#endif -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif -#include "rt_index.h" - -#ifndef USE_RAID -#define my_raid_create(A,B,C,D,E,F,G) my_create(A,B,C,G) -#define my_raid_delete(A,B,C) my_delete(A,B) -#endif - - /* Functions defined in this file */ - -static int check_k_link(MI_CHECK *param, MI_INFO *info,uint nr); -static int chk_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo, - my_off_t page, uchar *buff, ha_rows *keys, - ha_checksum *key_checksum, uint level); -static uint isam_key_length(MI_INFO *info,MI_KEYDEF *keyinfo); -static ha_checksum calc_checksum(ha_rows count); -static int writekeys(MI_CHECK *param, MI_INFO *info,byte *buff, - my_off_t filepos); -static int sort_one_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo, - my_off_t pagepos, File new_file); -static int sort_key_read(MI_SORT_PARAM *sort_param,void *key); -static int sort_ft_key_read(MI_SORT_PARAM *sort_param,void *key); -static int sort_get_next_record(MI_SORT_PARAM *sort_param); -static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,const void *b); -static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a); -static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a); -static my_off_t get_record_for_key(MI_INFO *info,MI_KEYDEF *keyinfo, - uchar *key); -static int sort_insert_key(MI_SORT_PARAM *sort_param, - reg1 SORT_KEY_BLOCKS *key_block, - uchar *key, my_off_t prev_block); -static int sort_delete_record(MI_SORT_PARAM *sort_param); -/*static int flush_pending_blocks(MI_CHECK *param);*/ -static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks, - uint buffer_length); -static ha_checksum mi_byte_checksum(const byte *buf, uint length); -static void set_data_file_type(SORT_INFO *sort_info, MYISAM_SHARE *share); - -void myisamchk_init(MI_CHECK *param) -{ - bzero((gptr) param,sizeof(*param)); - param->opt_follow_links=1; - param->keys_in_use= ~(ulonglong) 0; - param->search_after_block=HA_OFFSET_ERROR; - param->auto_increment_value= 0; - param->use_buffers=USE_BUFFER_INIT; - param->read_buffer_length=READ_BUFFER_INIT; - param->write_buffer_length=READ_BUFFER_INIT; - param->sort_buffer_length=SORT_BUFFER_INIT; - param->sort_key_blocks=BUFFERS_WHEN_SORTING; - param->tmpfile_createflag=O_RDWR | O_TRUNC | O_EXCL; - param->myf_rw=MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL); - param->start_check_pos=0; - param->max_record_length= LONGLONG_MAX; - param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE; -} - - /* Check the status flags for the table */ - -int chk_status(MI_CHECK *param, register MI_INFO *info) -{ - MYISAM_SHARE *share=info->s; - - if (mi_is_crashed_on_repair(info)) - mi_check_print_warning(param, - "Table is marked as crashed and last repair failed"); - else if (mi_is_crashed(info)) - mi_check_print_warning(param, - "Table is marked as crashed"); - if (share->state.open_count != (uint) (info->s->global_changed ? 1 : 0)) - { - /* Don't count this as a real warning, as check can correct this ! */ - uint save=param->warning_printed; - mi_check_print_warning(param, - share->state.open_count==1 ? - "%d client is using or hasn't closed the table properly" : - "%d clients are using or haven't closed the table properly", - share->state.open_count); - /* If this will be fixed by the check, forget the warning */ - if (param->testflag & T_UPDATE_STATE) - param->warning_printed=save; - } - return 0; -} - - /* Check delete links */ - -int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag) -{ - reg2 ha_rows i; - uint delete_link_length; - my_off_t empty,next_link,old_link; - char buff[22],buff2[22]; - DBUG_ENTER("chk_del"); - - LINT_INIT(old_link); - param->record_checksum=0; - delete_link_length=((info->s->options & HA_OPTION_PACK_RECORD) ? 20 : - info->s->rec_reflength+1); - - if (!(test_flag & T_SILENT)) - puts("- check record delete-chain"); - - next_link=info->s->state.dellink; - if (info->state->del == 0) - { - if (test_flag & T_VERBOSE) - { - puts("No recordlinks"); - } - } - else - { - if (test_flag & T_VERBOSE) - printf("Recordlinks: "); - empty=0; - for (i= info->state->del ; i > 0L && next_link != HA_OFFSET_ERROR ; i--) - { - if (*killed_ptr(param)) - DBUG_RETURN(1); - if (test_flag & T_VERBOSE) - printf(" %9s",llstr(next_link,buff)); - if (next_link >= info->state->data_file_length) - goto wrong; - if (my_pread(info->dfile,(char*) buff,delete_link_length, - next_link,MYF(MY_NABP))) - { - if (test_flag & T_VERBOSE) puts(""); - mi_check_print_error(param,"Can't read delete-link at filepos: %s", - llstr(next_link,buff)); - DBUG_RETURN(1); - } - if (*buff != '\0') - { - if (test_flag & T_VERBOSE) puts(""); - mi_check_print_error(param,"Record at pos: %s is not remove-marked", - llstr(next_link,buff)); - goto wrong; - } - if (info->s->options & HA_OPTION_PACK_RECORD) - { - my_off_t prev_link=mi_sizekorr(buff+12); - if (empty && prev_link != old_link) - { - if (test_flag & T_VERBOSE) puts(""); - mi_check_print_error(param,"Deleted block at %s doesn't point back at previous delete link",llstr(next_link,buff2)); - goto wrong; - } - old_link=next_link; - next_link=mi_sizekorr(buff+4); - empty+=mi_uint3korr(buff+1); - } - else - { - param->record_checksum+=(ha_checksum) next_link; - next_link=_mi_rec_pos(info->s,(uchar*) buff+1); - empty+=info->s->base.pack_reclength; - } - } - if (test_flag & T_VERBOSE) - puts("\n"); - if (empty != info->state->empty) - { - mi_check_print_warning(param, - "Found %s deleted space in delete link chain. Should be %s", - llstr(empty,buff2), - llstr(info->state->empty,buff)); - } - if (next_link != HA_OFFSET_ERROR) - { - mi_check_print_error(param, - "Found more than the expected %s deleted rows in delete link chain", - llstr(info->state->del, buff)); - goto wrong; - } - if (i != 0) - { - mi_check_print_error(param, - "Found %s deleted rows in delete link chain. Should be %s", - llstr(info->state->del - i, buff2), - llstr(info->state->del, buff)); - goto wrong; - } - } - DBUG_RETURN(0); - -wrong: - param->testflag|=T_RETRY_WITHOUT_QUICK; - if (test_flag & T_VERBOSE) puts(""); - mi_check_print_error(param,"record delete-link-chain corrupted"); - DBUG_RETURN(1); -} /* chk_del */ - - - /* Check delete links in index file */ - -static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr) -{ - my_off_t next_link; - uint block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH; - ha_rows records; - char llbuff[21],*buff; - DBUG_ENTER("check_k_link"); - - if (param->testflag & T_VERBOSE) - printf("block_size %4d:",block_size); - - next_link=info->s->state.key_del[nr]; - records= (ha_rows) (info->state->key_file_length / block_size); - while (next_link != HA_OFFSET_ERROR && records > 0) - { - if (*killed_ptr(param)) - DBUG_RETURN(1); - if (param->testflag & T_VERBOSE) - printf("%16s",llstr(next_link,llbuff)); - if (next_link > info->state->key_file_length || - next_link & (info->s->blocksize-1)) - DBUG_RETURN(1); - if (!(buff=key_cache_read(info->s->key_cache, - info->s->kfile, next_link, DFLT_INIT_HITS, - (byte*) info->buff, - myisam_block_size, block_size, 1))) - DBUG_RETURN(1); - next_link=mi_sizekorr(buff); - records--; - param->key_file_blocks+=block_size; - } - if (param->testflag & T_VERBOSE) - { - if (next_link != HA_OFFSET_ERROR) - printf("%16s\n",llstr(next_link,llbuff)); - else - puts(""); - } - DBUG_RETURN (next_link != HA_OFFSET_ERROR); -} /* check_k_link */ - - - /* Check sizes of files */ - -int chk_size(MI_CHECK *param, register MI_INFO *info) -{ - int error=0; - register my_off_t skr,size; - char buff[22],buff2[22]; - DBUG_ENTER("chk_size"); - - if (!(param->testflag & T_SILENT)) puts("- check file-size"); - - /* The following is needed if called externally (not from myisamchk) */ - flush_key_blocks(info->s->key_cache, - info->s->kfile, FLUSH_FORCE_WRITE); - - size=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0)); - if ((skr=(my_off_t) info->state->key_file_length) != size) - { - /* Don't give error if file generated by myisampack */ - if (skr > size && info->s->state.key_map) - { - error=1; - mi_check_print_error(param, - "Size of indexfile is: %-8s Should be: %s", - llstr(size,buff), llstr(skr,buff2)); - } - else - mi_check_print_warning(param, - "Size of indexfile is: %-8s Should be: %s", - llstr(size,buff), llstr(skr,buff2)); - } - if (!(param->testflag & T_VERY_SILENT) && - ! (info->s->options & HA_OPTION_COMPRESS_RECORD) && - ulonglong2double(info->state->key_file_length) > - ulonglong2double(info->s->base.margin_key_file_length)*0.9) - mi_check_print_warning(param,"Keyfile is almost full, %10s of %10s used", - llstr(info->state->key_file_length,buff), - llstr(info->s->base.max_key_file_length-1,buff)); - - size=my_seek(info->dfile,0L,MY_SEEK_END,MYF(0)); - skr=(my_off_t) info->state->data_file_length; - if (info->s->options & HA_OPTION_COMPRESS_RECORD) - skr+= MEMMAP_EXTRA_MARGIN; -#ifdef USE_RELOC - if (info->data_file_type == STATIC_RECORD && - skr < (my_off_t) info->s->base.reloc*info->s->base.min_pack_length) - skr=(my_off_t) info->s->base.reloc*info->s->base.min_pack_length; -#endif - if (skr != size) - { - info->state->data_file_length=size; /* Skip other errors */ - if (skr > size && skr != size + MEMMAP_EXTRA_MARGIN) - { - error=1; - mi_check_print_error(param,"Size of datafile is: %-9s Should be: %s", - llstr(size,buff), llstr(skr,buff2)); - param->testflag|=T_RETRY_WITHOUT_QUICK; - } - else - { - mi_check_print_warning(param, - "Size of datafile is: %-9s Should be: %s", - llstr(size,buff), llstr(skr,buff2)); - } - } - if (!(param->testflag & T_VERY_SILENT) && - !(info->s->options & HA_OPTION_COMPRESS_RECORD) && - ulonglong2double(info->state->data_file_length) > - (ulonglong2double(info->s->base.max_data_file_length)*0.9)) - mi_check_print_warning(param, "Datafile is almost full, %10s of %10s used", - llstr(info->state->data_file_length,buff), - llstr(info->s->base.max_data_file_length-1,buff2)); - DBUG_RETURN(error); -} /* chk_size */ - - - /* Check keys */ - -int chk_key(MI_CHECK *param, register MI_INFO *info) -{ - uint key,found_keys=0,full_text_keys=0,result=0; - ha_rows keys; - ha_checksum old_record_checksum,init_checksum; - my_off_t all_keydata,all_totaldata,key_totlength,length; - ulong *rec_per_key_part; - MYISAM_SHARE *share=info->s; - MI_KEYDEF *keyinfo; - char buff[22],buff2[22]; - DBUG_ENTER("chk_key"); - - if (!(param->testflag & T_SILENT)) - puts("- check key delete-chain"); - - param->key_file_blocks=info->s->base.keystart; - for (key=0 ; key < info->s->state.header.max_block_size ; key++) - if (check_k_link(param,info,key)) - { - if (param->testflag & T_VERBOSE) puts(""); - mi_check_print_error(param,"key delete-link-chain corrupted"); - DBUG_RETURN(-1); - } - - if (!(param->testflag & T_SILENT)) puts("- check index reference"); - - all_keydata=all_totaldata=key_totlength=0; - old_record_checksum=0; - init_checksum=param->record_checksum; - if (!(share->options & - (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD))) - old_record_checksum=calc_checksum(info->state->records+info->state->del-1)* - share->base.pack_reclength; - rec_per_key_part= param->rec_per_key_part; - for (key= 0,keyinfo= &share->keyinfo[0]; key < share->base.keys ; - rec_per_key_part+=keyinfo->keysegs, key++, keyinfo++) - { - param->key_crc[key]=0; - if (!(((ulonglong) 1 << key) & share->state.key_map)) - { - /* Remember old statistics for key */ - memcpy((char*) rec_per_key_part, - (char*) (share->state.rec_per_key_part + - (uint) (rec_per_key_part - param->rec_per_key_part)), - keyinfo->keysegs*sizeof(*rec_per_key_part)); - continue; - } - found_keys++; - - param->record_checksum=init_checksum; - bzero((char*) ¶m->unique_count,sizeof(param->unique_count)); - if ((!(param->testflag & T_SILENT))) - printf ("- check data record references index: %d\n",key+1); - if (keyinfo->flag & HA_FULLTEXT) - full_text_keys++; - if (share->state.key_root[key] == HA_OFFSET_ERROR && - (info->state->records == 0 || keyinfo->flag & HA_FULLTEXT)) - continue; - if (!_mi_fetch_keypage(info,keyinfo,share->state.key_root[key], - DFLT_INIT_HITS,info->buff,0)) - { - mi_check_print_error(param,"Can't read indexpage from filepos: %s", - llstr(share->state.key_root[key],buff)); - if (!(param->testflag & T_INFO)) - DBUG_RETURN(-1); - result= -1; - continue; - } - param->key_file_blocks+=keyinfo->block_length; - keys=0; - param->keydata=param->totaldata=0; - param->key_blocks=0; - param->max_level=0; - if (chk_index(param,info,keyinfo,share->state.key_root[key],info->buff, - &keys, param->key_crc+key,1)) - DBUG_RETURN(-1); - if(!(keyinfo->flag & (HA_FULLTEXT | HA_SPATIAL))) - { - if (keys != info->state->records) - { - mi_check_print_error(param,"Found %s keys of %s",llstr(keys,buff), - llstr(info->state->records,buff2)); - if (!(param->testflag & T_INFO)) - DBUG_RETURN(-1); - result= -1; - continue; - } - if (found_keys - full_text_keys == 1 && - ((share->options & - (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) || - (param->testflag & T_DONT_CHECK_CHECKSUM))) - old_record_checksum=param->record_checksum; - else if (old_record_checksum != param->record_checksum) - { - if (key) - mi_check_print_error(param,"Key %u doesn't point at same records that key 1", - key+1); - else - mi_check_print_error(param,"Key 1 doesn't point at all records"); - if (!(param->testflag & T_INFO)) - DBUG_RETURN(-1); - result= -1; - continue; - } - } - if ((uint) share->base.auto_key -1 == key) - { - /* Check that auto_increment key is bigger than max key value */ - ulonglong save_auto_value=info->s->state.auto_increment; - info->s->state.auto_increment=0; - info->lastinx=key; - _mi_read_key_record(info, 0L, info->rec_buff); - update_auto_increment(info, info->rec_buff); - if (info->s->state.auto_increment > save_auto_value) - { - mi_check_print_warning(param, - "Auto-increment value: %s is smaller than max used value: %s", - llstr(save_auto_value,buff2), - llstr(info->s->state.auto_increment, buff)); - } - if (param->testflag & T_AUTO_INC) - { - set_if_bigger(info->s->state.auto_increment, - param->auto_increment_value); - } - else - info->s->state.auto_increment=save_auto_value; - - /* Check that there isn't a row with auto_increment = 0 in the table */ - mi_extra(info,HA_EXTRA_KEYREAD,0); - bzero(info->lastkey,keyinfo->seg->length); - if (!mi_rkey(info, info->rec_buff, key, (const byte*) info->lastkey, - keyinfo->seg->length, HA_READ_KEY_EXACT)) - { - /* Don't count this as a real warning, as myisamchk can't correct it */ - uint save=param->warning_printed; - mi_check_print_warning(param, - "Found row where the auto_increment column has the value 0"); - param->warning_printed=save; - } - mi_extra(info,HA_EXTRA_NO_KEYREAD,0); - } - - length=(my_off_t) isam_key_length(info,keyinfo)*keys + param->key_blocks*2; - if (param->testflag & T_INFO && param->totaldata != 0L && keys != 0L) - printf("Key: %2d: Keyblocks used: %3d%% Packed: %4d%% Max levels: %2d\n", - key+1, - (int) (my_off_t2double(param->keydata)*100.0/my_off_t2double(param->totaldata)), - (int) ((my_off_t2double(length) - my_off_t2double(param->keydata))*100.0/ - my_off_t2double(length)), - param->max_level); - all_keydata+=param->keydata; all_totaldata+=param->totaldata; key_totlength+=length; - - if (param->testflag & T_STATISTICS) - update_key_parts(keyinfo, rec_per_key_part, param->unique_count, - (ulonglong) info->state->records); - } - if (param->testflag & T_INFO) - { - if (all_totaldata != 0L && found_keys > 0) - printf("Total: Keyblocks used: %3d%% Packed: %4d%%\n\n", - (int) (my_off_t2double(all_keydata)*100.0/ - my_off_t2double(all_totaldata)), - (int) ((my_off_t2double(key_totlength) - - my_off_t2double(all_keydata))*100.0/ - my_off_t2double(key_totlength))); - else if (all_totaldata != 0L && share->state.key_map) - puts(""); - } - if (param->key_file_blocks != info->state->key_file_length && - param->keys_in_use != ~(ulonglong) 0) - mi_check_print_warning(param, "Some data are unreferenced in keyfile"); - if (found_keys != full_text_keys) - param->record_checksum=old_record_checksum-init_checksum; /* Remove delete links */ - else - param->record_checksum=0; - DBUG_RETURN(result); -} /* chk_key */ - - -static int chk_index_down(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, - my_off_t page, uchar *buff, ha_rows *keys, - ha_checksum *key_checksum, uint level) -{ - char llbuff[22],llbuff2[22]; - if (page > info->state->key_file_length || (page & (info->s->blocksize -1))) - { - my_off_t max_length=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0)); - mi_check_print_error(param,"Wrong pagepointer: %s at page: %s", - llstr(page,llbuff),llstr(page,llbuff2)); - - if (page+info->s->blocksize > max_length) - goto err; - info->state->key_file_length=(max_length & - ~ (my_off_t) (info->s->blocksize-1)); - } - if (!_mi_fetch_keypage(info,keyinfo,page, DFLT_INIT_HITS,buff,0)) - { - mi_check_print_error(param,"Can't read key from filepos: %s", - llstr(page,llbuff)); - goto err; - } - param->key_file_blocks+=keyinfo->block_length; - if (chk_index(param,info,keyinfo,page,buff,keys,key_checksum,level)) - goto err; - - return 0; -err: - return 1; -} - - /* Check if index is ok */ - -static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, - my_off_t page, uchar *buff, ha_rows *keys, - ha_checksum *key_checksum, uint level) -{ - int flag; - uint used_length,comp_flag,nod_flag,key_length=0,not_used; - uchar key[MI_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos; - my_off_t next_page,record; - char llbuff[22]; - DBUG_ENTER("chk_index"); - DBUG_DUMP("buff",(byte*) buff,mi_getint(buff)); - - /* TODO: implement appropriate check for RTree keys */ - if (keyinfo->flag & HA_SPATIAL) - DBUG_RETURN(0); - - if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length))) - { - mi_check_print_error(param,"Not enough memory for keyblock"); - DBUG_RETURN(-1); - } - - if (keyinfo->flag & HA_NOSAME) - comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* Not real duplicates */ - else - comp_flag=SEARCH_SAME; /* Keys in positionorder */ - nod_flag=mi_test_if_nod(buff); - used_length=mi_getint(buff); - keypos=buff+2+nod_flag; - endpos=buff+used_length; - - param->keydata+=used_length; param->totaldata+=keyinfo->block_length; /* INFO */ - param->key_blocks++; - if (level > param->max_level) - param->max_level=level; - - if (used_length > keyinfo->block_length) - { - mi_check_print_error(param,"Wrong pageinfo at page: %s", - llstr(page,llbuff)); - goto err; - } - for ( ;; ) - { - if (*killed_ptr(param)) - goto err; - memcpy((char*) info->lastkey,(char*) key,key_length); - info->lastkey_length=key_length; - if (nod_flag) - { - next_page=_mi_kpos(nod_flag,keypos); - if (chk_index_down(param,info,keyinfo,next_page, - temp_buff,keys,key_checksum,level+1)) - goto err; - } - old_keypos=keypos; - if (keypos >= endpos || - (key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,key)) == 0) - break; - if (keypos > endpos) - { - mi_check_print_error(param,"Wrong key block length at page: %s",llstr(page,llbuff)); - goto err; - } - if ((*keys)++ && - (flag=ha_key_cmp(keyinfo->seg,info->lastkey,key,key_length, - comp_flag, ¬_used)) >=0) - { - DBUG_DUMP("old",(byte*) info->lastkey, info->lastkey_length); - DBUG_DUMP("new",(byte*) key, key_length); - DBUG_DUMP("new_in_page",(char*) old_keypos,(uint) (keypos-old_keypos)); - - if (comp_flag & SEARCH_FIND && flag == 0) - mi_check_print_error(param,"Found duplicated key at page %s",llstr(page,llbuff)); - else - mi_check_print_error(param,"Key in wrong position at page %s",llstr(page,llbuff)); - goto err; - } - if (param->testflag & T_STATISTICS) - { - if (*keys != 1L) /* not first_key */ - { - uint diff; - ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY, - SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, - &diff); - param->unique_count[diff-1]++; - } - } - (*key_checksum)+= mi_byte_checksum((byte*) key, - key_length- info->s->rec_reflength); - record= _mi_dpos(info,0,key+key_length); - if (keyinfo->flag & HA_FULLTEXT) /* special handling for ft2 */ - { - uint off; - int subkeys; - get_key_full_length_rdonly(off, key); - subkeys=ft_sintXkorr(key+off); - if (subkeys < 0) - { - ha_rows tmp_keys=0; - if (chk_index_down(param,info,&info->s->ft2_keyinfo,record, - temp_buff,&tmp_keys,key_checksum,1)) - goto err; - if (tmp_keys + subkeys) - { - mi_check_print_error(param, - "Number of words in the 2nd level tree " - "does not match the number in the header. " - "Parent word in on the page %s, offset %u", - llstr(page,llbuff), (uint) (old_keypos-buff)); - goto err; - } - (*keys)+=tmp_keys-1; - continue; - } - /* fall through */ - } - if (record >= info->state->data_file_length) - { -#ifndef DBUG_OFF - char llbuff2[22], llbuff3[22]; -#endif - mi_check_print_error(param,"Found key at page %s that points to record outside datafile",llstr(page,llbuff)); - DBUG_PRINT("test",("page: %s record: %s filelength: %s", - llstr(page,llbuff),llstr(record,llbuff2), - llstr(info->state->data_file_length,llbuff3))); - DBUG_DUMP("key",(byte*) key,key_length); - DBUG_DUMP("new_in_page",(char*) old_keypos,(uint) (keypos-old_keypos)); - goto err; - } - param->record_checksum+=(ha_checksum) record; - } - if (keypos != endpos) - { - mi_check_print_error(param,"Keyblock size at page %s is not correct. Block length: %d key length: %d", - llstr(page,llbuff), used_length, (keypos - buff)); - goto err; - } - my_afree((byte*) temp_buff); - DBUG_RETURN(0); - err: - my_afree((byte*) temp_buff); - DBUG_RETURN(1); -} /* chk_index */ - - - /* Calculate a checksum of 1+2+3+4...N = N*(N+1)/2 without overflow */ - -static ha_checksum calc_checksum(ha_rows count) -{ - ulonglong sum,a,b; - DBUG_ENTER("calc_checksum"); - - sum=0; - a=count; b=count+1; - if (a & 1) - b>>=1; - else - a>>=1; - while (b) - { - if (b & 1) - sum+=a; - a<<=1; b>>=1; - } - DBUG_PRINT("exit",("sum: %lx",(ulong) sum)); - DBUG_RETURN((ha_checksum) sum); -} /* calc_checksum */ - - - /* Calc length of key in normal isam */ - -static uint isam_key_length(MI_INFO *info, register MI_KEYDEF *keyinfo) -{ - uint length; - HA_KEYSEG *keyseg; - DBUG_ENTER("isam_key_length"); - - length= info->s->rec_reflength; - for (keyseg=keyinfo->seg ; keyseg->type ; keyseg++) - length+= keyseg->length; - - DBUG_PRINT("exit",("length: %d",length)); - DBUG_RETURN(length); -} /* key_length */ - - - /* Check that record-link is ok */ - -int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) -{ - int error,got_error,flag; - uint key,left_length,b_type,field; - ha_rows records,del_blocks; - my_off_t used,empty,pos,splits,start_recpos, - del_length,link_used,start_block; - byte *record,*to; - char llbuff[22],llbuff2[22],llbuff3[22]; - ha_checksum intern_record_checksum; - ha_checksum key_checksum[MI_MAX_POSSIBLE_KEY]; - my_bool static_row_size; - MI_KEYDEF *keyinfo; - MI_BLOCK_INFO block_info; - DBUG_ENTER("chk_data_link"); - - if (!(param->testflag & T_SILENT)) - { - if (extend) - puts("- check records and index references"); - else - puts("- check record links"); - } - - if (!(record= (byte*) my_malloc(info->s->base.pack_reclength,MYF(0)))) - { - mi_check_print_error(param,"Not enough memory for record"); - DBUG_RETURN(-1); - } - records=del_blocks=0; - used=link_used=splits=del_length=0; - intern_record_checksum=param->glob_crc=0; - LINT_INIT(left_length); LINT_INIT(start_recpos); LINT_INIT(to); - got_error=error=0; - empty=info->s->pack.header_length; - - /* Check how to calculate checksum of rows */ - static_row_size=1; - if (info->s->data_file_type == COMPRESSED_RECORD) - { - for (field=0 ; field < info->s->base.fields ; field++) - { - if (info->s->rec[field].base_type == FIELD_BLOB || - info->s->rec[field].base_type == FIELD_VARCHAR) - { - static_row_size=0; - break; - } - } - } - - pos=my_b_tell(¶m->read_cache); - bzero((char*) key_checksum, info->s->base.keys * sizeof(key_checksum[0])); - while (pos < info->state->data_file_length) - { - if (*killed_ptr(param)) - goto err2; - switch (info->s->data_file_type) { - case STATIC_RECORD: - if (my_b_read(¶m->read_cache,(byte*) record, - info->s->base.pack_reclength)) - goto err; - start_recpos=pos; - pos+=info->s->base.pack_reclength; - splits++; - if (*record == '\0') - { - del_blocks++; - del_length+=info->s->base.pack_reclength; - continue; /* Record removed */ - } - param->glob_crc+= mi_static_checksum(info,record); - used+=info->s->base.pack_reclength; - break; - case DYNAMIC_RECORD: - flag=block_info.second_read=0; - block_info.next_filepos=pos; - do - { - if (_mi_read_cache(¶m->read_cache,(byte*) block_info.header, - (start_block=block_info.next_filepos), - sizeof(block_info.header), - (flag ? 0 : READING_NEXT) | READING_HEADER)) - goto err; - if (start_block & (MI_DYN_ALIGN_SIZE-1)) - { - mi_check_print_error(param,"Wrong aligned block at %s", - llstr(start_block,llbuff)); - goto err2; - } - b_type=_mi_get_block_info(&block_info,-1,start_block); - if (b_type & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR | - BLOCK_FATAL_ERROR)) - { - if (b_type & BLOCK_SYNC_ERROR) - { - if (flag) - { - mi_check_print_error(param,"Unexpected byte: %d at link: %s", - (int) block_info.header[0], - llstr(start_block,llbuff)); - goto err2; - } - pos=block_info.filepos+block_info.block_len; - goto next; - } - if (b_type & BLOCK_DELETED) - { - if (block_info.block_len < info->s->base.min_block_length) - { - mi_check_print_error(param, - "Deleted block with impossible length %lu at %s", - block_info.block_len,llstr(pos,llbuff)); - goto err2; - } - if ((block_info.next_filepos != HA_OFFSET_ERROR && - block_info.next_filepos >= info->state->data_file_length) || - (block_info.prev_filepos != HA_OFFSET_ERROR && - block_info.prev_filepos >= info->state->data_file_length)) - { - mi_check_print_error(param,"Delete link points outside datafile at %s", - llstr(pos,llbuff)); - goto err2; - } - del_blocks++; - del_length+=block_info.block_len; - pos=block_info.filepos+block_info.block_len; - splits++; - goto next; - } - mi_check_print_error(param,"Wrong bytesec: %d-%d-%d at linkstart: %s", - block_info.header[0],block_info.header[1], - block_info.header[2], - llstr(start_block,llbuff)); - goto err2; - } - if (info->state->data_file_length < block_info.filepos+ - block_info.block_len) - { - mi_check_print_error(param, - "Recordlink that points outside datafile at %s", - llstr(pos,llbuff)); - got_error=1; - break; - } - splits++; - if (!flag++) /* First block */ - { - start_recpos=pos; - pos=block_info.filepos+block_info.block_len; - if (block_info.rec_len > (uint) info->s->base.max_pack_length) - { - mi_check_print_error(param,"Found too long record (%lu) at %s", - (ulong) block_info.rec_len, - llstr(start_recpos,llbuff)); - got_error=1; - break; - } - if (info->s->base.blobs) - { - if (!(to= mi_alloc_rec_buff(info, block_info.rec_len, - &info->rec_buff))) - { - mi_check_print_error(param, - "Not enough memory (%lu) for blob at %s", - (ulong) block_info.rec_len, - llstr(start_recpos,llbuff)); - got_error=1; - break; - } - } - else - to= info->rec_buff; - left_length=block_info.rec_len; - } - if (left_length < block_info.data_len) - { - mi_check_print_error(param,"Found too long record (%lu) at %s", - (ulong) block_info.data_len, - llstr(start_recpos,llbuff)); - got_error=1; - break; - } - if (_mi_read_cache(¶m->read_cache,(byte*) to,block_info.filepos, - (uint) block_info.data_len, - flag == 1 ? READING_NEXT : 0)) - goto err; - to+=block_info.data_len; - link_used+= block_info.filepos-start_block; - used+= block_info.filepos - start_block + block_info.data_len; - empty+=block_info.block_len-block_info.data_len; - left_length-=block_info.data_len; - if (left_length) - { - if (b_type & BLOCK_LAST) - { - mi_check_print_error(param, - "Wrong record length %s of %s at %s", - llstr(block_info.rec_len-left_length,llbuff), - llstr(block_info.rec_len, llbuff2), - llstr(start_recpos,llbuff3)); - got_error=1; - break; - } - if (info->state->data_file_length < block_info.next_filepos) - { - mi_check_print_error(param, - "Found next-recordlink that points outside datafile at %s", - llstr(block_info.filepos,llbuff)); - got_error=1; - break; - } - } - } while (left_length); - if (! got_error) - { - if (_mi_rec_unpack(info,record,info->rec_buff,block_info.rec_len) == - MY_FILE_ERROR) - { - mi_check_print_error(param,"Found wrong record at %s", - llstr(start_recpos,llbuff)); - got_error=1; - } - else - { - info->checksum=mi_checksum(info,record); - if (param->testflag & (T_EXTEND | T_MEDIUM | T_VERBOSE)) - { - if (_mi_rec_check(info,record, info->rec_buff,block_info.rec_len)) - { - mi_check_print_error(param,"Found wrong packed record at %s", - llstr(start_recpos,llbuff)); - got_error=1; - } - } - if (!got_error) - param->glob_crc+= info->checksum; - } - } - else if (!flag) - pos=block_info.filepos+block_info.block_len; - break; - case COMPRESSED_RECORD: - if (_mi_read_cache(¶m->read_cache,(byte*) block_info.header, pos, - info->s->pack.ref_length, READING_NEXT)) - goto err; - start_recpos=pos; - splits++; - VOID(_mi_pack_get_block_info(info,&block_info, -1, start_recpos)); - pos=block_info.filepos+block_info.rec_len; - if (block_info.rec_len < (uint) info->s->min_pack_length || - block_info.rec_len > (uint) info->s->max_pack_length) - { - mi_check_print_error(param, - "Found block with wrong recordlength: %d at %s", - block_info.rec_len, llstr(start_recpos,llbuff)); - got_error=1; - break; - } - if (_mi_read_cache(¶m->read_cache,(byte*) info->rec_buff, - block_info.filepos, block_info.rec_len, READING_NEXT)) - goto err; - if (_mi_pack_rec_unpack(info,record,info->rec_buff,block_info.rec_len)) - { - mi_check_print_error(param,"Found wrong record at %s", - llstr(start_recpos,llbuff)); - got_error=1; - } - if (static_row_size) - param->glob_crc+= mi_static_checksum(info,record); - else - param->glob_crc+= mi_checksum(info,record); - link_used+= (block_info.filepos - start_recpos); - used+= (pos-start_recpos); - } /* switch */ - if (! got_error) - { - intern_record_checksum+=(ha_checksum) start_recpos; - records++; - if (param->testflag & T_WRITE_LOOP && records % WRITE_COUNT == 0) - { - printf("%s\r", llstr(records,llbuff)); VOID(fflush(stdout)); - } - - /* Check if keys match the record */ - - for (key=0,keyinfo= info->s->keyinfo; key < info->s->base.keys; - key++,keyinfo++) - { - if ((((ulonglong) 1 << key) & info->s->state.key_map)) - { - if(!(keyinfo->flag & HA_FULLTEXT)) - { - uint key_length=_mi_make_key(info,key,info->lastkey,record, - start_recpos); - if (extend) - { - /* We don't need to lock the key tree here as we don't allow - concurrent threads when running myisamchk - */ - if (_mi_search(info,keyinfo,info->lastkey,key_length, - SEARCH_SAME, info->s->state.key_root[key])) - { - mi_check_print_error(param,"Record at: %10s Can't find key for index: %2d", - llstr(start_recpos,llbuff),key+1); - if (error++ > MAXERR || !(param->testflag & T_VERBOSE)) - goto err2; - } - } - else - key_checksum[key]+=mi_byte_checksum((byte*) info->lastkey, - key_length); - } - } - } - } - else - { - got_error=0; - if (error++ > MAXERR || !(param->testflag & T_VERBOSE)) - goto err2; - } - next:; /* Next record */ - } - if (param->testflag & T_WRITE_LOOP) - { - VOID(fputs(" \r",stdout)); VOID(fflush(stdout)); - } - if (records != info->state->records) - { - mi_check_print_error(param,"Record-count is not ok; is %-10s Should be: %s", - llstr(records,llbuff), llstr(info->state->records,llbuff2)); - error=1; - } - else if (param->record_checksum && - param->record_checksum != intern_record_checksum) - { - mi_check_print_error(param, - "Keypointers and record positions doesn't match"); - error=1; - } - else if (param->glob_crc != info->s->state.checksum && - (info->s->options & - (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))) - { - mi_check_print_warning(param, - "Record checksum is not the same as checksum stored in the index file\n"); - error=1; - } - else if (!extend) - { - for (key=0 ; key < info->s->base.keys; key++) - { - if (key_checksum[key] != param->key_crc[key] && - !(info->s->keyinfo[key].flag & (HA_FULLTEXT | HA_SPATIAL))) - { - mi_check_print_error(param,"Checksum for key: %2d doesn't match checksum for records", - key+1); - error=1; - } - } - } - - if (del_length != info->state->empty) - { - mi_check_print_warning(param, - "Found %s deleted space. Should be %s", - llstr(del_length,llbuff2), - llstr(info->state->empty,llbuff)); - } - if (used+empty+del_length != info->state->data_file_length) - { - mi_check_print_warning(param, - "Found %s record-data and %s unused data and %s deleted-data", - llstr(used,llbuff),llstr(empty,llbuff2), - llstr(del_length,llbuff3)); - mi_check_print_warning(param, - "Total %s, Should be: %s", - llstr((used+empty+del_length),llbuff), - llstr(info->state->data_file_length,llbuff2)); - } - if (del_blocks != info->state->del) - { - mi_check_print_warning(param, - "Found %10s deleted blocks Should be: %s", - llstr(del_blocks,llbuff), - llstr(info->state->del,llbuff2)); - } - if (splits != info->s->state.split) - { - mi_check_print_warning(param, - "Found %10s parts Should be: %s parts", - llstr(splits,llbuff), - llstr(info->s->state.split,llbuff2)); - } - if (param->testflag & T_INFO) - { - if (param->warning_printed || param->error_printed) - puts(""); - if (used != 0 && ! param->error_printed) - { - printf("Records:%18s M.recordlength:%9lu Packed:%14.0f%%\n", - llstr(records,llbuff), (long)((used-link_used)/records), - (info->s->base.blobs ? 0.0 : - (ulonglong2double((ulonglong) info->s->base.reclength*records)- - my_off_t2double(used))/ - ulonglong2double((ulonglong) info->s->base.reclength*records)*100.0)); - printf("Recordspace used:%9.0f%% Empty space:%12d%% Blocks/Record: %6.2f\n", - (ulonglong2double(used-link_used)/ulonglong2double(used-link_used+empty)*100.0), - (!records ? 100 : (int) (ulonglong2double(del_length+empty)/ - my_off_t2double(used)*100.0)), - ulonglong2double(splits - del_blocks) / records); - } - printf("Record blocks:%12s Delete blocks:%10s\n", - llstr(splits-del_blocks,llbuff),llstr(del_blocks,llbuff2)); - printf("Record data: %12s Deleted data: %10s\n", - llstr(used-link_used,llbuff),llstr(del_length,llbuff2)); - printf("Lost space: %12s Linkdata: %10s\n", - llstr(empty,llbuff),llstr(link_used,llbuff2)); - } - my_free((gptr) record,MYF(0)); - DBUG_RETURN (error); - err: - mi_check_print_error(param,"got error: %d when reading datafile at record: %s",my_errno, llstr(records,llbuff)); - err2: - my_free((gptr) record,MYF(0)); - param->testflag|=T_RETRY_WITHOUT_QUICK; - DBUG_RETURN(1); -} /* chk_data_link */ - - - /* Recover old table by reading each record and writing all keys */ - /* Save new datafile-name in temp_filename */ - -int mi_repair(MI_CHECK *param, register MI_INFO *info, - my_string name, int rep_quick) -{ - int error,got_error; - uint i; - ha_rows start_records,new_header_length; - my_off_t del; - File new_file; - MYISAM_SHARE *share=info->s; - char llbuff[22],llbuff2[22]; - SORT_INFO sort_info; - MI_SORT_PARAM sort_param; - DBUG_ENTER("mi_repair"); - - bzero((char *)&sort_info, sizeof(sort_info)); - bzero((char *)&sort_param, sizeof(sort_param)); - start_records=info->state->records; - new_header_length=(param->testflag & T_UNPACK) ? 0L : - share->pack.header_length; - got_error=1; - new_file= -1; - sort_param.sort_info=&sort_info; - - if (!(param->testflag & T_SILENT)) - { - printf("- recovering (with keycache) MyISAM-table '%s'\n",name); - printf("Data records: %s\n", llstr(info->state->records,llbuff)); - } - param->testflag|=T_REP; /* for easy checking */ - - if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) - param->testflag|=T_CALC_CHECKSUM; - - if (!param->using_global_keycache) - VOID(init_key_cache(dflt_key_cache, param->key_cache_block_size, - param->use_buffers, 0, 0)); - - if (init_io_cache(¶m->read_cache,info->dfile, - (uint) param->read_buffer_length, - READ_CACHE,share->pack.header_length,1,MYF(MY_WME))) - { - bzero(&info->rec_cache,sizeof(info->rec_cache)); - goto err; - } - if (!rep_quick) - if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length, - WRITE_CACHE, new_header_length, 1, - MYF(MY_WME | MY_WAIT_IF_FULL))) - goto err; - info->opt_flag|=WRITE_CACHE_USED; - if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength, - MYF(0))) || - !mi_alloc_rec_buff(info, -1, &sort_param.rec_buff)) - { - mi_check_print_error(param, "Not enough memory for extra record"); - goto err; - } - - if (!rep_quick) - { - /* Get real path for data file */ - if ((new_file=my_raid_create(fn_format(param->temp_filename, - share->data_file_name, "", - DATA_TMP_EXT, 2+4), - 0,param->tmpfile_createflag, - share->base.raid_type, - share->base.raid_chunks, - share->base.raid_chunksize, - MYF(0))) < 0) - { - mi_check_print_error(param,"Can't create new tempfile: '%s'", - param->temp_filename); - goto err; - } - if (filecopy(param,new_file,info->dfile,0L,new_header_length, - "datafile-header")) - goto err; - info->s->state.dellink= HA_OFFSET_ERROR; - info->rec_cache.file=new_file; - if (param->testflag & T_UNPACK) - { - share->options&= ~HA_OPTION_COMPRESS_RECORD; - mi_int2store(share->state.header.options,share->options); - } - } - sort_info.info=info; - sort_info.param = param; - sort_param.read_cache=param->read_cache; - sort_param.pos=sort_param.max_pos=share->pack.header_length; - sort_param.filepos=new_header_length; - param->read_cache.end_of_file=sort_info.filelength= - my_seek(info->dfile,0L,MY_SEEK_END,MYF(0)); - sort_info.dupp=0; - sort_param.fix_datafile= (my_bool) (! rep_quick); - sort_param.master=1; - sort_info.max_records= ~(ha_rows) 0; - - set_data_file_type(&sort_info, share); - del=info->state->del; - info->state->records=info->state->del=share->state.split=0; - info->state->empty=0; - param->glob_crc=0; - if (param->testflag & T_CALC_CHECKSUM) - param->calc_checksum=1; - - info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - for (i=0 ; i < info->s->base.keys ; i++) - share->state.key_root[i]= HA_OFFSET_ERROR; - for (i=0 ; i < share->state.header.max_block_size ; i++) - share->state.key_del[i]= HA_OFFSET_ERROR; - - /* - I think mi_repair and mi_repair_by_sort should do the same - (according, e.g. to ha_myisam::repair), but as mi_repair doesn't - touch key_map it cannot be used to T_CREATE_MISSING_KEYS. - That is what the next line is for - */ - - if (param->testflag & T_CREATE_MISSING_KEYS) - share->state.key_map= ((((ulonglong) 1L << share->base.keys)-1) & - param->keys_in_use); - - info->state->key_file_length=share->base.keystart; - - lock_memory(param); /* Everything is alloced */ - while (!(error=sort_get_next_record(&sort_param))) - { - if (writekeys(param,info,(byte*)sort_param.record,sort_param.filepos)) - { - if (my_errno != HA_ERR_FOUND_DUPP_KEY) - goto err; - DBUG_DUMP("record",(byte*) sort_param.record,share->base.pack_reclength); - mi_check_print_info(param,"Duplicate key %2d for record at %10s against new record at %10s", - info->errkey+1, - llstr(sort_param.start_recpos,llbuff), - llstr(info->dupp_key_pos,llbuff2)); - if (param->testflag & T_VERBOSE) - { - VOID(_mi_make_key(info,(uint) info->errkey,info->lastkey, - sort_param.record,0L)); - _mi_print_key(stdout,share->keyinfo[info->errkey].seg,info->lastkey, - USE_WHOLE_KEY); - } - sort_info.dupp++; - if ((param->testflag & (T_FORCE_UNIQUENESS|T_QUICK)) == T_QUICK) - { - param->testflag|=T_RETRY_WITHOUT_QUICK; - param->error_printed=1; - goto err; - } - continue; - } - if (sort_write_record(&sort_param)) - goto err; - } - if (error > 0 || write_data_suffix(&sort_info, (my_bool)!rep_quick) || - flush_io_cache(&info->rec_cache) || param->read_cache.error < 0) - goto err; - - if (param->testflag & T_WRITE_LOOP) - { - VOID(fputs(" \r",stdout)); VOID(fflush(stdout)); - } - if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0))) - { - mi_check_print_warning(param, - "Can't change size of indexfile, error: %d", - my_errno); - goto err; - } - - if (rep_quick && del+sort_info.dupp != info->state->del) - { - mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records"); - mi_check_print_error(param,"Run recovery again without -q"); - got_error=1; - param->retry_repair=1; - param->testflag|=T_RETRY_WITHOUT_QUICK; - goto err; - } - if (param->testflag & T_SAFE_REPAIR) - { - /* Don't repair if we loosed more than one row */ - if (info->state->records+1 < start_records) - { - info->state->records=start_records; - got_error=1; - goto err; - } - } - - if (!rep_quick) - { - my_close(info->dfile,MYF(0)); - info->dfile=new_file; - info->state->data_file_length=sort_param.filepos; - share->state.version=(ulong) time((time_t*) 0); /* Force reopen */ - } - else - { - info->state->data_file_length=sort_param.max_pos; - } - if (param->testflag & T_CALC_CHECKSUM) - share->state.checksum=param->glob_crc; - - if (!(param->testflag & T_SILENT)) - { - if (start_records != info->state->records) - printf("Data records: %s\n", llstr(info->state->records,llbuff)); - if (sort_info.dupp) - mi_check_print_warning(param, - "%s records have been removed", - llstr(sort_info.dupp,llbuff)); - } - - got_error=0; - /* If invoked by external program that uses thr_lock */ - if (&share->state.state != info->state) - memcpy( &share->state.state, info->state, sizeof(*info->state)); - -err: - if (!got_error) - { - /* Replace the actual file with the temporary file */ - if (new_file >= 0) - { - my_close(new_file,MYF(0)); - info->dfile=new_file= -1; - if (change_to_newfile(share->data_file_name,MI_NAME_DEXT, - DATA_TMP_EXT, share->base.raid_chunks, - (param->testflag & T_BACKUP_DATA ? - MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || - mi_open_datafile(info,share,-1)) - got_error=1; - } - } - if (got_error) - { - if (! param->error_printed) - mi_check_print_error(param,"%d for record at pos %s",my_errno, - llstr(sort_param.start_recpos,llbuff)); - if (new_file >= 0) - { - VOID(my_close(new_file,MYF(0))); - VOID(my_raid_delete(param->temp_filename,info->s->base.raid_chunks, - MYF(MY_WME))); - info->rec_cache.file=-1; /* don't flush data to new_file, it's closed */ - } - mi_mark_crashed_on_repair(info); - } - my_free(mi_get_rec_buff_ptr(info, sort_param.rec_buff), - MYF(MY_ALLOW_ZERO_PTR)); - my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR)); - my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR)); - VOID(end_io_cache(¶m->read_cache)); - info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); - VOID(end_io_cache(&info->rec_cache)); - got_error|=flush_blocks(param, share->key_cache, share->kfile); - if (!got_error && param->testflag & T_UNPACK) - { - share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD; - share->pack.header_length=0; - share->data_file_type=sort_info.new_data_file_type; - } - share->state.changed|= (STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES | - STATE_NOT_ANALYZED); - DBUG_RETURN(got_error); -} - - -/* Uppate keyfile when doing repair */ - -static int writekeys(MI_CHECK *param, register MI_INFO *info, byte *buff, - my_off_t filepos) -{ - register uint i; - uchar *key; - DBUG_ENTER("writekeys"); - - key=info->lastkey+info->s->base.max_key_length; - for (i=0 ; i < info->s->base.keys ; i++) - { - if (((ulonglong) 1 << i) & info->s->state.key_map) - { - if (info->s->keyinfo[i].flag & HA_FULLTEXT ) - { - if (_mi_ft_add(info,i,(char*) key,buff,filepos)) - goto err; - } -#ifdef HAVE_SPATIAL - else if (info->s->keyinfo[i].flag & HA_SPATIAL) - { - uint key_length=_mi_make_key(info,i,key,buff,filepos); - if (rtree_insert(info, i, key, key_length)) - goto err; - } -#endif /*HAVE_SPATIAL*/ - else - { - uint key_length=_mi_make_key(info,i,key,buff,filepos); - if (_mi_ck_write(info,i,key,key_length)) - goto err; - } - } - } - DBUG_RETURN(0); - - err: - if (my_errno == HA_ERR_FOUND_DUPP_KEY) - { - info->errkey=(int) i; /* This key was found */ - while ( i-- > 0 ) - { - if (((ulonglong) 1 << i) & info->s->state.key_map) - { - if (info->s->keyinfo[i].flag & HA_FULLTEXT) - { - if (_mi_ft_del(info,i,(char*) key,buff,filepos)) - break; - } - else - { - uint key_length=_mi_make_key(info,i,key,buff,filepos); - if (_mi_ck_delete(info,i,key,key_length)) - break; - } - } - } - } - /* Remove checksum that was added to glob_crc in sort_get_next_record */ - if (param->calc_checksum) - param->glob_crc-= info->checksum; - DBUG_PRINT("error",("errno: %d",my_errno)); - DBUG_RETURN(-1); -} /* writekeys */ - - - /* Change all key-pointers that points to a records */ - -int movepoint(register MI_INFO *info, byte *record, my_off_t oldpos, - my_off_t newpos, uint prot_key) -{ - register uint i; - uchar *key; - uint key_length; - DBUG_ENTER("movepoint"); - - key=info->lastkey+info->s->base.max_key_length; - for (i=0 ; i < info->s->base.keys; i++) - { - if (i != prot_key && (((ulonglong) 1 << i) & info->s->state.key_map)) - { - key_length=_mi_make_key(info,i,key,record,oldpos); - if (info->s->keyinfo[i].flag & HA_NOSAME) - { /* Change pointer direct */ - uint nod_flag; - MI_KEYDEF *keyinfo; - keyinfo=info->s->keyinfo+i; - if (_mi_search(info,keyinfo,key,USE_WHOLE_KEY, - (uint) (SEARCH_SAME | SEARCH_SAVE_BUFF), - info->s->state.key_root[i])) - DBUG_RETURN(-1); - nod_flag=mi_test_if_nod(info->buff); - _mi_dpointer(info,info->int_keypos-nod_flag- - info->s->rec_reflength,newpos); - if (_mi_write_keypage(info,keyinfo,info->last_keypage, - DFLT_INIT_HITS,info->buff)) - DBUG_RETURN(-1); - } - else - { /* Change old key to new */ - if (_mi_ck_delete(info,i,key,key_length)) - DBUG_RETURN(-1); - key_length=_mi_make_key(info,i,key,record,newpos); - if (_mi_ck_write(info,i,key,key_length)) - DBUG_RETURN(-1); - } - } - } - DBUG_RETURN(0); -} /* movepoint */ - - - /* Tell system that we want all memory for our cache */ - -void lock_memory(MI_CHECK *param __attribute__((unused))) -{ -#ifdef SUN_OS /* Key-cacheing thrases on sun 4.1 */ - if (param->opt_lock_memory) - { - int success = mlockall(MCL_CURRENT); /* or plock(DATLOCK); */ - if (geteuid() == 0 && success != 0) - mi_check_print_warning(param, - "Failed to lock memory. errno %d",my_errno); - } -#endif -} /* lock_memory */ - - - /* Flush all changed blocks to disk */ - -int flush_blocks(MI_CHECK *param, KEY_CACHE *key_cache, File file) -{ - if (flush_key_blocks(key_cache, file, FLUSH_RELEASE)) - { - mi_check_print_error(param,"%d when trying to write bufferts",my_errno); - return(1); - } - if (!param->using_global_keycache) - end_key_cache(key_cache,1); - return 0; -} /* flush_blocks */ - - - /* Sort index for more efficent reads */ - -int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) -{ - reg2 uint key; - reg1 MI_KEYDEF *keyinfo; - File new_file; - my_off_t index_pos[MI_MAX_POSSIBLE_KEY]; - uint r_locks,w_locks; - int old_lock; - MYISAM_SHARE *share=info->s; - MI_STATE_INFO old_state; - DBUG_ENTER("mi_sort_index"); - - if (!(param->testflag & T_SILENT)) - printf("- Sorting index for MyISAM-table '%s'\n",name); - - /* Get real path for index file */ - fn_format(param->temp_filename,name,"", MI_NAME_IEXT,2+4+32); - if ((new_file=my_create(fn_format(param->temp_filename,param->temp_filename, - "", INDEX_TMP_EXT,2+4), - 0,param->tmpfile_createflag,MYF(0))) <= 0) - { - mi_check_print_error(param,"Can't create new tempfile: '%s'", - param->temp_filename); - DBUG_RETURN(-1); - } - if (filecopy(param, new_file,share->kfile,0L, - (ulong) share->base.keystart, "headerblock")) - goto err; - - param->new_file_pos=share->base.keystart; - for (key= 0,keyinfo= &share->keyinfo[0]; key < share->base.keys ; - key++,keyinfo++) - { - if (!(((ulonglong) 1 << key) & share->state.key_map)) - continue; - - if (share->state.key_root[key] != HA_OFFSET_ERROR) - { - index_pos[key]=param->new_file_pos; /* Write first block here */ - if (sort_one_index(param,info,keyinfo,share->state.key_root[key], - new_file)) - goto err; - } - else - index_pos[key]= HA_OFFSET_ERROR; /* No blocks */ - } - - /* Flush key cache for this file if we are calling this outside myisamchk */ - flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED); - - share->state.version=(ulong) time((time_t*) 0); - old_state= share->state; /* save state if not stored */ - r_locks= share->r_locks; - w_locks= share->w_locks; - old_lock= info->lock_type; - - /* Put same locks as old file */ - share->r_locks= share->w_locks= share->tot_locks= 0; - (void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE); - VOID(my_close(share->kfile,MYF(MY_WME))); - share->kfile = -1; - VOID(my_close(new_file,MYF(MY_WME))); - if (change_to_newfile(share->index_file_name,MI_NAME_IEXT,INDEX_TMP_EXT,0, - MYF(0)) || - mi_open_keyfile(share)) - goto err2; - info->lock_type= F_UNLCK; /* Force mi_readinfo to lock */ - _mi_readinfo(info,F_WRLCK,0); /* Will lock the table */ - info->lock_type= old_lock; - share->r_locks= r_locks; - share->w_locks= w_locks; - share->tot_locks= r_locks+w_locks; - share->state= old_state; /* Restore old state */ - - info->state->key_file_length=param->new_file_pos; - info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - for (key=0 ; key < info->s->base.keys ; key++) - info->s->state.key_root[key]=index_pos[key]; - for (key=0 ; key < info->s->state.header.max_block_size ; key++) - info->s->state.key_del[key]= HA_OFFSET_ERROR; - - info->s->state.changed&= ~STATE_NOT_SORTED_PAGES; - DBUG_RETURN(0); - -err: - VOID(my_close(new_file,MYF(MY_WME))); -err2: - VOID(my_delete(param->temp_filename,MYF(MY_WME))); - DBUG_RETURN(-1); -} /* mi_sort_index */ - - - /* Sort records recursive using one index */ - -static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, - my_off_t pagepos, File new_file) -{ - uint length,nod_flag,used_length, key_length; - uchar *buff,*keypos,*endpos; - uchar key[MI_MAX_POSSIBLE_KEY_BUFF]; - my_off_t new_page_pos,next_page; - char llbuff[22]; - DBUG_ENTER("sort_one_index"); - - new_page_pos=param->new_file_pos; - param->new_file_pos+=keyinfo->block_length; - - if (!(buff=(uchar*) my_alloca((uint) keyinfo->block_length))) - { - mi_check_print_error(param,"Not enough memory for key block"); - DBUG_RETURN(-1); - } - if (!_mi_fetch_keypage(info,keyinfo,pagepos,DFLT_INIT_HITS,buff,0)) - { - mi_check_print_error(param,"Can't read key block from filepos: %s", - llstr(pagepos,llbuff)); - goto err; - } - if ((nod_flag=mi_test_if_nod(buff)) || keyinfo->flag & HA_FULLTEXT) - { - used_length=mi_getint(buff); - keypos=buff+2+nod_flag; - endpos=buff+used_length; - for ( ;; ) - { - if (nod_flag) - { - next_page=_mi_kpos(nod_flag,keypos); - _mi_kpointer(info,keypos-nod_flag,param->new_file_pos); /* Save new pos */ - if (sort_one_index(param,info,keyinfo,next_page,new_file)) - { - DBUG_PRINT("error",("From page: %ld, keyoffset: %d used_length: %d", - (ulong) pagepos, (int) (keypos - buff), - (int) used_length)); - DBUG_DUMP("buff",(byte*) buff,used_length); - goto err; - } - } - if (keypos >= endpos || - (key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,key)) == 0) - break; - DBUG_ASSERT(keypos <= endpos); - if (keyinfo->flag & HA_FULLTEXT) - { - uint off; - int subkeys; - get_key_full_length_rdonly(off, key); - subkeys=ft_sintXkorr(key+off); - if (subkeys < 0) - { - next_page= _mi_dpos(info,0,key+key_length); - _mi_dpointer(info,keypos-nod_flag-info->s->rec_reflength, - param->new_file_pos); /* Save new pos */ - if (sort_one_index(param,info,&info->s->ft2_keyinfo, - next_page,new_file)) - goto err; - } - } - } - } - - /* Fill block with zero and write it to the new index file */ - length=mi_getint(buff); - bzero((byte*) buff+length,keyinfo->block_length-length); - if (my_pwrite(new_file,(byte*) buff,(uint) keyinfo->block_length, - new_page_pos,MYF(MY_NABP | MY_WAIT_IF_FULL))) - { - mi_check_print_error(param,"Can't write indexblock, error: %d",my_errno); - goto err; - } - my_afree((gptr) buff); - DBUG_RETURN(0); -err: - my_afree((gptr) buff); - DBUG_RETURN(1); -} /* sort_one_index */ - - - /* - Let temporary file replace old file. - This assumes that the new file was created in the same - directory as given by realpath(filename). - This will ensure that any symlinks that are used will still work. - Copy stats from old file to new file, deletes orignal and - changes new file name to old file name - */ - -int change_to_newfile(const char * filename, const char * old_ext, - const char * new_ext, - uint raid_chunks __attribute__((unused)), - myf MyFlags) -{ - char old_filename[FN_REFLEN],new_filename[FN_REFLEN]; -#ifdef USE_RAID - if (raid_chunks) - return my_raid_redel(fn_format(old_filename,filename,"",old_ext,2+4), - fn_format(new_filename,filename,"",new_ext,2+4), - raid_chunks, - MYF(MY_WME | MY_LINK_WARNING | MyFlags)); -#endif - /* Get real path to filename */ - (void) fn_format(old_filename,filename,"",old_ext,2+4+32); - return my_redel(old_filename, - fn_format(new_filename,old_filename,"",new_ext,2+4), - MYF(MY_WME | MY_LINK_WARNING | MyFlags)); -} /* change_to_newfile */ - - - /* Locks a whole file */ - /* Gives an error-message if file can't be locked */ - -int lock_file(MI_CHECK *param, File file, my_off_t start, int lock_type, - const char *filetype, const char *filename) -{ - if (my_lock(file,lock_type,start,F_TO_EOF, - param->testflag & T_WAIT_FOREVER ? MYF(MY_SEEK_NOT_DONE) : - MYF(MY_SEEK_NOT_DONE | MY_DONT_WAIT))) - { - mi_check_print_error(param," %d when locking %s '%s'",my_errno,filetype,filename); - param->error_printed=2; /* Don't give that data is crashed */ - return 1; - } - return 0; -} /* lock_file */ - - - /* Copy a block between two files */ - -int filecopy(MI_CHECK *param, File to,File from,my_off_t start, - my_off_t length, const char *type) -{ - char tmp_buff[IO_SIZE],*buff; - ulong buff_length; - DBUG_ENTER("filecopy"); - - buff_length=(ulong) min(param->write_buffer_length,length); - if (!(buff=my_malloc(buff_length,MYF(0)))) - { - buff=tmp_buff; buff_length=IO_SIZE; - } - - VOID(my_seek(from,start,MY_SEEK_SET,MYF(0))); - while (length > buff_length) - { - if (my_read(from,(byte*) buff,buff_length,MYF(MY_NABP)) || - my_write(to,(byte*) buff,buff_length,param->myf_rw)) - goto err; - length-= buff_length; - } - if (my_read(from,(byte*) buff,(uint) length,MYF(MY_NABP)) || - my_write(to,(byte*) buff,(uint) length,param->myf_rw)) - goto err; - if (buff != tmp_buff) - my_free(buff,MYF(0)); - DBUG_RETURN(0); -err: - if (buff != tmp_buff) - my_free(buff,MYF(0)); - mi_check_print_error(param,"Can't copy %s to tempfile, error %d", - type,my_errno); - DBUG_RETURN(1); -} - - -/* - Repair table or given index using sorting - - SYNOPSIS - mi_repair_by_sort() - param Repair parameters - info MyISAM handler to repair - name Name of table (for warnings) - rep_quick set to <> 0 if we should not change data file - - RESULT - 0 ok - <>0 Error -*/ - -int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, - const char * name, int rep_quick) -{ - int got_error; - uint i; - ulong length; - ha_rows start_records; - my_off_t new_header_length,del; - File new_file; - MI_SORT_PARAM sort_param; - MYISAM_SHARE *share=info->s; - HA_KEYSEG *keyseg; - ulong *rec_per_key_part; - char llbuff[22]; - SORT_INFO sort_info; - ulonglong key_map=share->state.key_map; - DBUG_ENTER("mi_repair_by_sort"); - - start_records=info->state->records; - got_error=1; - new_file= -1; - new_header_length=(param->testflag & T_UNPACK) ? 0 : - share->pack.header_length; - if (!(param->testflag & T_SILENT)) - { - printf("- recovering (with sort) MyISAM-table '%s'\n",name); - printf("Data records: %s\n", llstr(start_records,llbuff)); - } - param->testflag|=T_REP; /* for easy checking */ - - if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) - param->testflag|=T_CALC_CHECKSUM; - - bzero((char*)&sort_info,sizeof(sort_info)); - bzero((char *)&sort_param, sizeof(sort_param)); - if (!(sort_info.key_block= - alloc_key_blocks(param, - (uint) param->sort_key_blocks, - share->base.max_key_block_length)) - || init_io_cache(¶m->read_cache,info->dfile, - (uint) param->read_buffer_length, - READ_CACHE,share->pack.header_length,1,MYF(MY_WME)) || - (! rep_quick && - init_io_cache(&info->rec_cache,info->dfile, - (uint) param->write_buffer_length, - WRITE_CACHE,new_header_length,1, - MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw))) - goto err; - sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks; - info->opt_flag|=WRITE_CACHE_USED; - info->rec_cache.file=info->dfile; /* for sort_delete_record */ - - if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength, - MYF(0))) || - !mi_alloc_rec_buff(info, -1, &sort_param.rec_buff)) - { - mi_check_print_error(param, "Not enough memory for extra record"); - goto err; - } - if (!rep_quick) - { - /* Get real path for data file */ - if ((new_file=my_raid_create(fn_format(param->temp_filename, - share->data_file_name, "", - DATA_TMP_EXT, 2+4), - 0,param->tmpfile_createflag, - share->base.raid_type, - share->base.raid_chunks, - share->base.raid_chunksize, - MYF(0))) < 0) - { - mi_check_print_error(param,"Can't create new tempfile: '%s'", - param->temp_filename); - goto err; - } - if (filecopy(param, new_file,info->dfile,0L,new_header_length, - "datafile-header")) - goto err; - if (param->testflag & T_UNPACK) - { - share->options&= ~HA_OPTION_COMPRESS_RECORD; - mi_int2store(share->state.header.options,share->options); - } - share->state.dellink= HA_OFFSET_ERROR; - info->rec_cache.file=new_file; - } - - info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - if (!(param->testflag & T_CREATE_MISSING_KEYS)) - { - /* - Flush key cache for this file if we are calling this outside - myisamchk - */ - flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED); - /* Clear the pointers to the given rows */ - for (i=0 ; i < share->base.keys ; i++) - share->state.key_root[i]= HA_OFFSET_ERROR; - for (i=0 ; i < share->state.header.max_block_size ; i++) - share->state.key_del[i]= HA_OFFSET_ERROR; - info->state->key_file_length=share->base.keystart; - } - else - { - if (flush_key_blocks(share->key_cache,share->kfile, FLUSH_FORCE_WRITE)) - goto err; - key_map= ~key_map; /* Create the missing keys */ - } - - sort_info.info=info; - sort_info.param = param; - - set_data_file_type(&sort_info, share); - sort_param.filepos=new_header_length; - sort_info.dupp=0; - sort_info.buff=0; - param->read_cache.end_of_file=sort_info.filelength= - my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0)); - - sort_param.wordlist=NULL; - - if (share->data_file_type == DYNAMIC_RECORD) - length=max(share->base.min_pack_length+1,share->base.min_block_length); - else if (share->data_file_type == COMPRESSED_RECORD) - length=share->base.min_block_length; - else - length=share->base.pack_reclength; - sort_info.max_records= - ((param->testflag & T_CREATE_MISSING_KEYS) ? info->state->records : - (ha_rows) (sort_info.filelength/length+1)); - sort_param.key_cmp=sort_key_cmp; - sort_param.lock_in_memory=lock_memory; - sort_param.tmpdir=param->tmpdir; - sort_param.sort_info=&sort_info; - sort_param.fix_datafile= (my_bool) (! rep_quick); - sort_param.master =1; - - del=info->state->del; - param->glob_crc=0; - if (param->testflag & T_CALC_CHECKSUM) - param->calc_checksum=1; - - rec_per_key_part= param->rec_per_key_part; - for (sort_param.key=0 ; sort_param.key < share->base.keys ; - rec_per_key_part+=sort_param.keyinfo->keysegs, sort_param.key++) - { - sort_param.read_cache=param->read_cache; - sort_param.keyinfo=share->keyinfo+sort_param.key; - sort_param.seg=sort_param.keyinfo->seg; - if (!(((ulonglong) 1 << sort_param.key) & key_map)) - { - /* Remember old statistics for key */ - memcpy((char*) rec_per_key_part, - (char*) (share->state.rec_per_key_part + - (uint) (rec_per_key_part - param->rec_per_key_part)), - sort_param.keyinfo->keysegs*sizeof(*rec_per_key_part)); - continue; - } - - if ((!(param->testflag & T_SILENT))) - printf ("- Fixing index %d\n",sort_param.key+1); - sort_param.max_pos=sort_param.pos=share->pack.header_length; - keyseg=sort_param.seg; - bzero((char*) sort_param.unique,sizeof(sort_param.unique)); - sort_param.key_length=share->rec_reflength; - for (i=0 ; keyseg[i].type != HA_KEYTYPE_END; i++) - { - sort_param.key_length+=keyseg[i].length; - if (keyseg[i].flag & HA_SPACE_PACK) - sort_param.key_length+=get_pack_length(keyseg[i].length); - if (keyseg[i].flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART)) - sort_param.key_length+=2 + test(keyseg[i].length >= 127); - if (keyseg[i].flag & HA_NULL_PART) - sort_param.key_length++; - } - info->state->records=info->state->del=share->state.split=0; - info->state->empty=0; - - if (sort_param.keyinfo->flag & HA_FULLTEXT) - { - uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT* - sort_param.keyinfo->seg->charset->mbmaxlen; - sort_info.max_records= - (ha_rows) (sort_info.filelength/ft_min_word_len+1); - - sort_param.key_read=sort_ft_key_read; - sort_param.key_write=sort_ft_key_write; - sort_param.key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN; - } - else - { - sort_param.key_read=sort_key_read; - sort_param.key_write=sort_key_write; - } - - if (_create_index_by_sort(&sort_param, - (my_bool) (!(param->testflag & T_VERBOSE)), - (uint) param->sort_buffer_length)) - { - param->retry_repair=1; - goto err; - } - param->calc_checksum=0; /* No need to calc glob_crc */ - - /* Set for next loop */ - sort_info.max_records= (ha_rows) info->state->records; - - if (param->testflag & T_STATISTICS) - update_key_parts(sort_param.keyinfo, rec_per_key_part, sort_param.unique, - (ulonglong) info->state->records); - share->state.key_map|=(ulonglong) 1 << sort_param.key; - - if (sort_param.fix_datafile) - { - param->read_cache.end_of_file=sort_param.filepos; - if (write_data_suffix(&sort_info,1) || end_io_cache(&info->rec_cache)) - goto err; - if (param->testflag & T_SAFE_REPAIR) - { - /* Don't repair if we loosed more than one row */ - if (info->state->records+1 < start_records) - { - info->state->records=start_records; - goto err; - } - } - share->state.state.data_file_length = info->state->data_file_length= - sort_param.filepos; - /* Only whole records */ - share->state.version=(ulong) time((time_t*) 0); - my_close(info->dfile,MYF(0)); - info->dfile=new_file; - share->data_file_type=sort_info.new_data_file_type; - share->pack.header_length=(ulong) new_header_length; - sort_param.fix_datafile=0; - } - else - info->state->data_file_length=sort_param.max_pos; - - param->read_cache.file=info->dfile; /* re-init read cache */ - reinit_io_cache(¶m->read_cache,READ_CACHE,share->pack.header_length, - 1,1); - } - - if (param->testflag & T_WRITE_LOOP) - { - VOID(fputs(" \r",stdout)); VOID(fflush(stdout)); - } - - if (rep_quick && del+sort_info.dupp != info->state->del) - { - mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records"); - mi_check_print_error(param,"Run recovery again without -q"); - got_error=1; - param->retry_repair=1; - param->testflag|=T_RETRY_WITHOUT_QUICK; - goto err; - } - - if (rep_quick & T_FORCE_UNIQUENESS) - { - my_off_t skr=info->state->data_file_length+ - (share->options & HA_OPTION_COMPRESS_RECORD ? - MEMMAP_EXTRA_MARGIN : 0); -#ifdef USE_RELOC - if (share->data_file_type == STATIC_RECORD && - skr < share->base.reloc*share->base.min_pack_length) - skr=share->base.reloc*share->base.min_pack_length; -#endif - if (skr != sort_info.filelength && !info->s->base.raid_type) - if (my_chsize(info->dfile,skr,0,MYF(0))) - mi_check_print_warning(param, - "Can't change size of datafile, error: %d", - my_errno); - } - if (param->testflag & T_CALC_CHECKSUM) - share->state.checksum=param->glob_crc; - - if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0))) - mi_check_print_warning(param, - "Can't change size of indexfile, error: %d", - my_errno); - - if (!(param->testflag & T_SILENT)) - { - if (start_records != info->state->records) - printf("Data records: %s\n", llstr(info->state->records,llbuff)); - if (sort_info.dupp) - mi_check_print_warning(param, - "%s records have been removed", - llstr(sort_info.dupp,llbuff)); - } - got_error=0; - - if (&share->state.state != info->state) - memcpy( &share->state.state, info->state, sizeof(*info->state)); - -err: - got_error|= flush_blocks(param, share->key_cache, share->kfile); - VOID(end_io_cache(&info->rec_cache)); - if (!got_error) - { - /* Replace the actual file with the temporary file */ - if (new_file >= 0) - { - my_close(new_file,MYF(0)); - info->dfile=new_file= -1; - if (change_to_newfile(share->data_file_name,MI_NAME_DEXT, - DATA_TMP_EXT, share->base.raid_chunks, - (param->testflag & T_BACKUP_DATA ? - MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || - mi_open_datafile(info,share,-1)) - got_error=1; - } - } - if (got_error) - { - if (! param->error_printed) - mi_check_print_error(param,"%d when fixing table",my_errno); - if (new_file >= 0) - { - VOID(my_close(new_file,MYF(0))); - VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks, - MYF(MY_WME))); - if (info->dfile == new_file) - info->dfile= -1; - } - mi_mark_crashed_on_repair(info); - } - else if (key_map == share->state.key_map) - share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS; - share->state.changed|=STATE_NOT_SORTED_PAGES; - - my_free(mi_get_rec_buff_ptr(info, sort_param.rec_buff), - MYF(MY_ALLOW_ZERO_PTR)); - my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR)); - my_free((gptr) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR)); - my_free((gptr) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR)); - my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR)); - VOID(end_io_cache(¶m->read_cache)); - info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); - if (!got_error && (param->testflag & T_UNPACK)) - { - share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD; - share->pack.header_length=0; - } - DBUG_RETURN(got_error); -} - -/* - Threaded repair of table using sorting - - SYNOPSIS - mi_repair_parallel() - param Repair parameters - info MyISAM handler to repair - name Name of table (for warnings) - rep_quick set to <> 0 if we should not change data file - - DESCRIPTION - Same as mi_repair_by_sort but do it multithreaded - Each key is handled by a separate thread. - TODO: make a number of threads a parameter - - RESULT - 0 ok - <>0 Error -*/ - -int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, - const char * name, int rep_quick) -{ -#ifndef THREAD - return mi_repair_by_sort(param, info, name, rep_quick); -#else - int got_error; - uint i,key, total_key_length, istep; - ulong rec_length; - ha_rows start_records; - my_off_t new_header_length,del; - File new_file; - MI_SORT_PARAM *sort_param=0; - MYISAM_SHARE *share=info->s; - ulong *rec_per_key_part; - HA_KEYSEG *keyseg; - char llbuff[22]; - IO_CACHE_SHARE io_share; - SORT_INFO sort_info; - ulonglong key_map=share->state.key_map; - pthread_attr_t thr_attr; - DBUG_ENTER("mi_repair_parallel"); - - start_records=info->state->records; - got_error=1; - new_file= -1; - new_header_length=(param->testflag & T_UNPACK) ? 0 : - share->pack.header_length; - if (!(param->testflag & T_SILENT)) - { - printf("- parallel recovering (with sort) MyISAM-table '%s'\n",name); - printf("Data records: %s\n", llstr(start_records,llbuff)); - } - param->testflag|=T_REP; /* for easy checking */ - - if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) - param->testflag|=T_CALC_CHECKSUM; - - bzero((char*)&sort_info,sizeof(sort_info)); - if (!(sort_info.key_block= - alloc_key_blocks(param, - (uint) param->sort_key_blocks, - share->base.max_key_block_length)) - || init_io_cache(¶m->read_cache,info->dfile, - (uint) param->read_buffer_length, - READ_CACHE,share->pack.header_length,1,MYF(MY_WME)) || - (! rep_quick && - init_io_cache(&info->rec_cache,info->dfile, - (uint) param->write_buffer_length, - WRITE_CACHE,new_header_length,1, - MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw))) - goto err; - sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks; - info->opt_flag|=WRITE_CACHE_USED; - info->rec_cache.file=info->dfile; /* for sort_delete_record */ - - if (!rep_quick) - { - /* Get real path for data file */ - if ((new_file=my_raid_create(fn_format(param->temp_filename, - share->data_file_name, "", - DATA_TMP_EXT, - 2+4), - 0,param->tmpfile_createflag, - share->base.raid_type, - share->base.raid_chunks, - share->base.raid_chunksize, - MYF(0))) < 0) - { - mi_check_print_error(param,"Can't create new tempfile: '%s'", - param->temp_filename); - goto err; - } - if (filecopy(param, new_file,info->dfile,0L,new_header_length, - "datafile-header")) - goto err; - if (param->testflag & T_UNPACK) - { - share->options&= ~HA_OPTION_COMPRESS_RECORD; - mi_int2store(share->state.header.options,share->options); - } - share->state.dellink= HA_OFFSET_ERROR; - info->rec_cache.file=new_file; - } - - info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - if (!(param->testflag & T_CREATE_MISSING_KEYS)) - { - /* - Flush key cache for this file if we are calling this outside - myisamchk - */ - flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED); - /* Clear the pointers to the given rows */ - for (i=0 ; i < share->base.keys ; i++) - share->state.key_root[i]= HA_OFFSET_ERROR; - for (i=0 ; i < share->state.header.max_block_size ; i++) - share->state.key_del[i]= HA_OFFSET_ERROR; - info->state->key_file_length=share->base.keystart; - } - else - { - if (flush_key_blocks(share->key_cache,share->kfile, FLUSH_FORCE_WRITE)) - goto err; - key_map= ~key_map; /* Create the missing keys */ - } - - sort_info.info=info; - sort_info.param = param; - - set_data_file_type(&sort_info, share); - sort_info.dupp=0; - sort_info.buff=0; - param->read_cache.end_of_file=sort_info.filelength= - my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0)); - - if (share->data_file_type == DYNAMIC_RECORD) - rec_length=max(share->base.min_pack_length+1,share->base.min_block_length); - else if (share->data_file_type == COMPRESSED_RECORD) - rec_length=share->base.min_block_length; - else - rec_length=share->base.pack_reclength; - /* - +1 below is required hack for parallel repair mode. - The info->state->records value, that is compared later - to sort_info.max_records and cannot exceed it, is - increased in sort_key_write. In mi_repair_by_sort, sort_key_write - is called after sort_key_read, where the comparison is performed, - but in parallel mode master thread can call sort_key_write - before some other repair thread calls sort_key_read. - Furthermore I'm not even sure +1 would be enough. - May be sort_info.max_records shold be always set to max value in - parallel mode. - */ - sort_info.max_records= - ((param->testflag & T_CREATE_MISSING_KEYS) ? info->state->records + 1: - (ha_rows) (sort_info.filelength/rec_length+1)); - - del=info->state->del; - param->glob_crc=0; - if (param->testflag & T_CALC_CHECKSUM) - param->calc_checksum=1; - - if (!(sort_param=(MI_SORT_PARAM *) - my_malloc((uint) share->base.keys * - (sizeof(MI_SORT_PARAM) + share->base.pack_reclength), - MYF(MY_ZEROFILL)))) - { - mi_check_print_error(param,"Not enough memory for key!"); - goto err; - } - total_key_length=0; - rec_per_key_part= param->rec_per_key_part; - info->state->records=info->state->del=share->state.split=0; - info->state->empty=0; - - for (i=key=0, istep=1 ; key < share->base.keys ; - rec_per_key_part+=sort_param[i].keyinfo->keysegs, i+=istep, key++) - { - sort_param[i].key=key; - sort_param[i].keyinfo=share->keyinfo+key; - sort_param[i].seg=sort_param[i].keyinfo->seg; - if (!(((ulonglong) 1 << key) & key_map)) - { - /* Remember old statistics for key */ - memcpy((char*) rec_per_key_part, - (char*) (share->state.rec_per_key_part+ - (uint) (rec_per_key_part - param->rec_per_key_part)), - sort_param[i].keyinfo->keysegs*sizeof(*rec_per_key_part)); - istep=0; - continue; - } - istep=1; - if ((!(param->testflag & T_SILENT))) - printf ("- Fixing index %d\n",key+1); - if (sort_param[i].keyinfo->flag & HA_FULLTEXT) - { - sort_param[i].key_read=sort_ft_key_read; - sort_param[i].key_write=sort_ft_key_write; - } - else - { - sort_param[i].key_read=sort_key_read; - sort_param[i].key_write=sort_key_write; - } - sort_param[i].key_cmp=sort_key_cmp; - sort_param[i].lock_in_memory=lock_memory; - sort_param[i].tmpdir=param->tmpdir; - sort_param[i].sort_info=&sort_info; - sort_param[i].master=0; - sort_param[i].fix_datafile=0; - - sort_param[i].filepos=new_header_length; - sort_param[i].max_pos=sort_param[i].pos=share->pack.header_length; - - sort_param[i].record= (((char *)(sort_param+share->base.keys))+ - (share->base.pack_reclength * i)); - if (!mi_alloc_rec_buff(info, -1, &sort_param[i].rec_buff)) - { - mi_check_print_error(param,"Not enough memory!"); - goto err; - } - - sort_param[i].key_length=share->rec_reflength; - for (keyseg=sort_param[i].seg; keyseg->type != HA_KEYTYPE_END; - keyseg++) - { - sort_param[i].key_length+=keyseg->length; - if (keyseg->flag & HA_SPACE_PACK) - sort_param[i].key_length+=get_pack_length(keyseg->length); - if (keyseg->flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART)) - sort_param[i].key_length+=2 + test(keyseg->length >= 127); - if (keyseg->flag & HA_NULL_PART) - sort_param[i].key_length++; - } - total_key_length+=sort_param[i].key_length; - - if (sort_param[i].keyinfo->flag & HA_FULLTEXT) - { - uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT* - sort_param[i].keyinfo->seg->charset->mbmaxlen; - sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN; - } - } - sort_info.total_keys=i; - sort_param[0].master= 1; - sort_param[0].fix_datafile= (my_bool)(! rep_quick); - - sort_info.got_error=0; - pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST); - pthread_cond_init(&sort_info.cond, 0); - pthread_mutex_lock(&sort_info.mutex); - - init_io_cache_share(¶m->read_cache, &io_share, i); - (void) pthread_attr_init(&thr_attr); - (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); - - for (i=0 ; i < sort_info.total_keys ; i++) - { - sort_param[i].read_cache=param->read_cache; - /* - two approaches: the same amount of memory for each thread - or the memory for the same number of keys for each thread... - In the second one all the threads will fill their sort_buffers - (and call write_keys) at the same time, putting more stress on i/o. - */ - sort_param[i].sortbuff_size= -#ifndef USING_SECOND_APPROACH - param->sort_buffer_length/sort_info.total_keys; -#else - param->sort_buffer_length*sort_param[i].key_length/total_key_length; -#endif - if (pthread_create(&sort_param[i].thr, &thr_attr, - thr_find_all_keys, - (void *) (sort_param+i))) - { - mi_check_print_error(param,"Cannot start a repair thread"); - remove_io_thread(¶m->read_cache); - sort_info.got_error=1; - } - else - sort_info.threads_running++; - } - (void) pthread_attr_destroy(&thr_attr); - - /* waiting for all threads to finish */ - while (sort_info.threads_running) - pthread_cond_wait(&sort_info.cond, &sort_info.mutex); - pthread_mutex_unlock(&sort_info.mutex); - - if ((got_error= thr_write_keys(sort_param))) - { - param->retry_repair=1; - goto err; - } - got_error=1; /* Assume the following may go wrong */ - - if (sort_param[0].fix_datafile) - { - if (write_data_suffix(&sort_info,1) || end_io_cache(&info->rec_cache)) - goto err; - if (param->testflag & T_SAFE_REPAIR) - { - /* Don't repair if we loosed more than one row */ - if (info->state->records+1 < start_records) - { - info->state->records=start_records; - goto err; - } - } - share->state.state.data_file_length= info->state->data_file_length= - sort_param->filepos; - /* Only whole records */ - share->state.version=(ulong) time((time_t*) 0); - my_close(info->dfile,MYF(0)); - info->dfile=new_file; - share->data_file_type=sort_info.new_data_file_type; - share->pack.header_length=(ulong) new_header_length; - } - else - info->state->data_file_length=sort_param->max_pos; - - if (rep_quick && del+sort_info.dupp != info->state->del) - { - mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records"); - mi_check_print_error(param,"Run recovery again without -q"); - param->retry_repair=1; - param->testflag|=T_RETRY_WITHOUT_QUICK; - goto err; - } - - if (rep_quick & T_FORCE_UNIQUENESS) - { - my_off_t skr=info->state->data_file_length+ - (share->options & HA_OPTION_COMPRESS_RECORD ? - MEMMAP_EXTRA_MARGIN : 0); -#ifdef USE_RELOC - if (share->data_file_type == STATIC_RECORD && - skr < share->base.reloc*share->base.min_pack_length) - skr=share->base.reloc*share->base.min_pack_length; -#endif - if (skr != sort_info.filelength && !info->s->base.raid_type) - if (my_chsize(info->dfile,skr,0,MYF(0))) - mi_check_print_warning(param, - "Can't change size of datafile, error: %d", - my_errno); - } - if (param->testflag & T_CALC_CHECKSUM) - share->state.checksum=param->glob_crc; - - if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0))) - mi_check_print_warning(param, - "Can't change size of indexfile, error: %d", my_errno); - - if (!(param->testflag & T_SILENT)) - { - if (start_records != info->state->records) - printf("Data records: %s\n", llstr(info->state->records,llbuff)); - if (sort_info.dupp) - mi_check_print_warning(param, - "%s records have been removed", - llstr(sort_info.dupp,llbuff)); - } - got_error=0; - - if (&share->state.state != info->state) - memcpy(&share->state.state, info->state, sizeof(*info->state)); - -err: - got_error|= flush_blocks(param, share->key_cache, share->kfile); - VOID(end_io_cache(&info->rec_cache)); - if (!got_error) - { - /* Replace the actual file with the temporary file */ - if (new_file >= 0) - { - my_close(new_file,MYF(0)); - info->dfile=new_file= -1; - if (change_to_newfile(share->data_file_name,MI_NAME_DEXT, - DATA_TMP_EXT, share->base.raid_chunks, - (param->testflag & T_BACKUP_DATA ? - MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || - mi_open_datafile(info,share,-1)) - got_error=1; - } - } - if (got_error) - { - if (! param->error_printed) - mi_check_print_error(param,"%d when fixing table",my_errno); - if (new_file >= 0) - { - VOID(my_close(new_file,MYF(0))); - VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks, - MYF(MY_WME))); - if (info->dfile == new_file) - info->dfile= -1; - } - mi_mark_crashed_on_repair(info); - } - else if (key_map == share->state.key_map) - share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS; - share->state.changed|=STATE_NOT_SORTED_PAGES; - - pthread_cond_destroy (&sort_info.cond); - pthread_mutex_destroy(&sort_info.mutex); - - my_free((gptr) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR)); - my_free((gptr) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR)); - my_free((gptr) sort_param,MYF(MY_ALLOW_ZERO_PTR)); - my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR)); - VOID(end_io_cache(¶m->read_cache)); - info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); - if (!got_error && (param->testflag & T_UNPACK)) - { - share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD; - share->pack.header_length=0; - } - DBUG_RETURN(got_error); -#endif /* THREAD */ -} - - /* Read next record and return next key */ - -static int sort_key_read(MI_SORT_PARAM *sort_param, void *key) -{ - int error; - SORT_INFO *sort_info=sort_param->sort_info; - MI_INFO *info=sort_info->info; - DBUG_ENTER("sort_key_read"); - - if ((error=sort_get_next_record(sort_param))) - DBUG_RETURN(error); - if (info->state->records == sort_info->max_records) - { - mi_check_print_error(sort_info->param, - "Key %d - Found too many records; Can't continue", - sort_param->key+1); - DBUG_RETURN(1); - } - sort_param->real_key_length= - (info->s->rec_reflength+ - _mi_make_key(info, sort_param->key, (uchar*) key, - sort_param->record, sort_param->filepos)); -#ifdef HAVE_purify - bzero(key+sort_param->real_key_length, - (sort_param->key_length-sort_param->real_key_length)); -#endif - DBUG_RETURN(sort_write_record(sort_param)); -} /* sort_key_read */ - -static int sort_ft_key_read(MI_SORT_PARAM *sort_param, void *key) -{ - int error; - SORT_INFO *sort_info=sort_param->sort_info; - MI_INFO *info=sort_info->info; - FT_WORD *wptr=0; - DBUG_ENTER("sort_ft_key_read"); - - if (!sort_param->wordlist) - { - for (;;) - { - my_free((char*) wptr, MYF(MY_ALLOW_ZERO_PTR)); - if ((error=sort_get_next_record(sort_param))) - DBUG_RETURN(error); - if (!(wptr=_mi_ft_parserecord(info,sort_param->key,sort_param->record))) - DBUG_RETURN(1); - if (wptr->pos) - break; - error=sort_write_record(sort_param); - } - sort_param->wordptr=sort_param->wordlist=wptr; - } - else - { - error=0; - wptr=(FT_WORD*)(sort_param->wordptr); - } - - sort_param->real_key_length=(info->s->rec_reflength+ - _ft_make_key(info, sort_param->key, - key, wptr++, sort_param->filepos)); -#ifdef HAVE_purify - if (sort_param->key_length > sort_param->real_key_length) - bzero(key+sort_param->real_key_length, - (sort_param->key_length-sort_param->real_key_length)); -#endif - if (!wptr->pos) - { - my_free((char*) sort_param->wordlist, MYF(0)); - sort_param->wordlist=0; - error=sort_write_record(sort_param); - } - else - sort_param->wordptr=(void*)wptr; - - DBUG_RETURN(error); -} /* sort_ft_key_read */ - - - /* Read next record from file using parameters in sort_info */ - /* Return -1 if end of file, 0 if ok and > 0 if error */ - -static int sort_get_next_record(MI_SORT_PARAM *sort_param) -{ - int searching; - uint found_record,b_type,left_length; - my_off_t pos; - byte *to; - MI_BLOCK_INFO block_info; - SORT_INFO *sort_info=sort_param->sort_info; - MI_CHECK *param=sort_info->param; - MI_INFO *info=sort_info->info; - MYISAM_SHARE *share=info->s; - char llbuff[22],llbuff2[22]; - DBUG_ENTER("sort_get_next_record"); - - if (*killed_ptr(param)) - DBUG_RETURN(1); - - switch (share->data_file_type) { - case STATIC_RECORD: - for (;;) - { - if (my_b_read(&sort_param->read_cache,sort_param->record, - share->base.pack_reclength)) - { - if (sort_param->read_cache.error) - param->out_flag |= O_DATA_LOST; - param->retry_repair=1; - param->testflag|=T_RETRY_WITHOUT_QUICK; - DBUG_RETURN(-1); - } - sort_param->start_recpos=sort_param->pos; - if (!sort_param->fix_datafile) - { - sort_param->filepos=sort_param->pos; - if (sort_param->master) - share->state.split++; - } - sort_param->max_pos=(sort_param->pos+=share->base.pack_reclength); - if (*sort_param->record) - { - if (param->calc_checksum) - param->glob_crc+= (info->checksum= - mi_static_checksum(info,sort_param->record)); - DBUG_RETURN(0); - } - if (!sort_param->fix_datafile && sort_param->master) - { - info->state->del++; - info->state->empty+=share->base.pack_reclength; - } - } - case DYNAMIC_RECORD: - LINT_INIT(to); - pos=sort_param->pos; - searching=(sort_param->fix_datafile && (param->testflag & T_EXTEND)); - for (;;) - { - found_record=block_info.second_read= 0; - left_length=1; - if (searching) - { - pos=MY_ALIGN(pos,MI_DYN_ALIGN_SIZE); - param->testflag|=T_RETRY_WITHOUT_QUICK; - sort_param->start_recpos=pos; - } - do - { - if (pos > sort_param->max_pos) - sort_param->max_pos=pos; - if (pos & (MI_DYN_ALIGN_SIZE-1)) - { - if ((param->testflag & T_VERBOSE) || searching == 0) - mi_check_print_info(param,"Wrong aligned block at %s", - llstr(pos,llbuff)); - if (searching) - goto try_next; - } - if (found_record && pos == param->search_after_block) - mi_check_print_info(param,"Block: %s used by record at %s", - llstr(param->search_after_block,llbuff), - llstr(sort_param->start_recpos,llbuff2)); - if (_mi_read_cache(&sort_param->read_cache, - (byte*) block_info.header,pos, - MI_BLOCK_INFO_HEADER_LENGTH, - (! found_record ? READING_NEXT : 0) | - READING_HEADER)) - { - if (found_record) - { - mi_check_print_info(param, - "Can't read whole record at %s (errno: %d)", - llstr(sort_param->start_recpos,llbuff),errno); - goto try_next; - } - DBUG_RETURN(-1); - } - if (searching && ! sort_param->fix_datafile) - { - param->error_printed=1; - param->retry_repair=1; - param->testflag|=T_RETRY_WITHOUT_QUICK; - DBUG_RETURN(1); /* Something wrong with data */ - } - b_type=_mi_get_block_info(&block_info,-1,pos); - if ((b_type & (BLOCK_ERROR | BLOCK_FATAL_ERROR)) || - ((b_type & BLOCK_FIRST) && - (block_info.rec_len < (uint) share->base.min_pack_length || - block_info.rec_len > (uint) share->base.max_pack_length))) - { - uint i; - if (param->testflag & T_VERBOSE || searching == 0) - mi_check_print_info(param, - "Wrong bytesec: %3d-%3d-%3d at %10s; Skipped", - block_info.header[0],block_info.header[1], - block_info.header[2],llstr(pos,llbuff)); - if (found_record) - goto try_next; - block_info.second_read=0; - searching=1; - /* Search after block in read header string */ - for (i=MI_DYN_ALIGN_SIZE ; - i < MI_BLOCK_INFO_HEADER_LENGTH ; - i+= MI_DYN_ALIGN_SIZE) - if (block_info.header[i] >= 1 && - block_info.header[i] <= MI_MAX_DYN_HEADER_BYTE) - break; - pos+=(ulong) i; - sort_param->start_recpos=pos; - continue; - } - if (b_type & BLOCK_DELETED) - { - bool error=0; - if (block_info.block_len+ (uint) (block_info.filepos-pos) < - share->base.min_block_length) - { - if (!searching) - mi_check_print_info(param, - "Deleted block with impossible length %u at %s", - block_info.block_len,llstr(pos,llbuff)); - error=1; - } - else - { - if ((block_info.next_filepos != HA_OFFSET_ERROR && - block_info.next_filepos >= - info->state->data_file_length) || - (block_info.prev_filepos != HA_OFFSET_ERROR && - block_info.prev_filepos >= info->state->data_file_length)) - { - if (!searching) - mi_check_print_info(param, - "Delete link points outside datafile at %s", - llstr(pos,llbuff)); - error=1; - } - } - if (error) - { - if (found_record) - goto try_next; - searching=1; - pos+= MI_DYN_ALIGN_SIZE; - sort_param->start_recpos=pos; - block_info.second_read=0; - continue; - } - } - else - { - if (block_info.block_len+ (uint) (block_info.filepos-pos) < - share->base.min_block_length || - block_info.block_len > (uint) share->base.max_pack_length+ - MI_SPLIT_LENGTH) - { - if (!searching) - mi_check_print_info(param, - "Found block with impossible length %u at %s; Skipped", - block_info.block_len+ (uint) (block_info.filepos-pos), - llstr(pos,llbuff)); - if (found_record) - goto try_next; - searching=1; - pos+= MI_DYN_ALIGN_SIZE; - sort_param->start_recpos=pos; - block_info.second_read=0; - continue; - } - } - if (b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR)) - { - if (!sort_param->fix_datafile && sort_param->master && - (b_type & BLOCK_DELETED)) - { - info->state->empty+=block_info.block_len; - info->state->del++; - share->state.split++; - } - if (found_record) - goto try_next; - if (searching) - { - pos+=MI_DYN_ALIGN_SIZE; - sort_param->start_recpos=pos; - } - else - pos=block_info.filepos+block_info.block_len; - block_info.second_read=0; - continue; - } - - if (!sort_param->fix_datafile && sort_param->master) - share->state.split++; - if (! found_record++) - { - sort_param->find_length=left_length=block_info.rec_len; - sort_param->start_recpos=pos; - if (!sort_param->fix_datafile) - sort_param->filepos=sort_param->start_recpos; - if (sort_param->fix_datafile && (param->testflag & T_EXTEND)) - sort_param->pos=block_info.filepos+1; - else - sort_param->pos=block_info.filepos+block_info.block_len; - if (share->base.blobs) - { - if (!(to=mi_alloc_rec_buff(info,block_info.rec_len, - &(sort_param->rec_buff)))) - { - if (param->max_record_length >= block_info.rec_len) - { - mi_check_print_error(param,"Not enough memory for blob at %s (need %lu)", - llstr(sort_param->start_recpos,llbuff), - (ulong) block_info.rec_len); - DBUG_RETURN(1); - } - else - { - mi_check_print_info(param,"Not enough memory for blob at %s (need %lu); Row skipped", - llstr(sort_param->start_recpos,llbuff), - (ulong) block_info.rec_len); - goto try_next; - } - } - } - else - to= sort_param->rec_buff; - } - if (left_length < block_info.data_len || ! block_info.data_len) - { - mi_check_print_info(param, - "Found block with too small length at %s; Skipped", - llstr(sort_param->start_recpos,llbuff)); - goto try_next; - } - if (block_info.filepos + block_info.data_len > - sort_param->read_cache.end_of_file) - { - mi_check_print_info(param, - "Found block that points outside data file at %s", - llstr(sort_param->start_recpos,llbuff)); - goto try_next; - } - if (_mi_read_cache(&sort_param->read_cache,to,block_info.filepos, - block_info.data_len, - (found_record == 1 ? READING_NEXT : 0))) - { - mi_check_print_info(param, - "Read error for block at: %s (error: %d); Skipped", - llstr(block_info.filepos,llbuff),my_errno); - goto try_next; - } - left_length-=block_info.data_len; - to+=block_info.data_len; - pos=block_info.next_filepos; - if (pos == HA_OFFSET_ERROR && left_length) - { - mi_check_print_info(param,"Wrong block with wrong total length starting at %s", - llstr(sort_param->start_recpos,llbuff)); - goto try_next; - } - if (pos + MI_BLOCK_INFO_HEADER_LENGTH > sort_param->read_cache.end_of_file) - { - mi_check_print_info(param,"Found link that points at %s (outside data file) at %s", - llstr(pos,llbuff2), - llstr(sort_param->start_recpos,llbuff)); - goto try_next; - } - } while (left_length); - - if (_mi_rec_unpack(info,sort_param->record,sort_param->rec_buff, - sort_param->find_length) != MY_FILE_ERROR) - { - if (sort_param->read_cache.error < 0) - DBUG_RETURN(1); - if (info->s->calc_checksum) - info->checksum=mi_checksum(info,sort_param->record); - if ((param->testflag & (T_EXTEND | T_REP)) || searching) - { - if (_mi_rec_check(info, sort_param->record, sort_param->rec_buff, - sort_param->find_length)) - { - mi_check_print_info(param,"Found wrong packed record at %s", - llstr(sort_param->start_recpos,llbuff)); - goto try_next; - } - } - if (param->calc_checksum) - param->glob_crc+= info->checksum; - DBUG_RETURN(0); - } - if (!searching) - mi_check_print_info(param,"Key %d - Found wrong stored record at %s", - sort_param->key+1, - llstr(sort_param->start_recpos,llbuff)); - try_next: - pos=(sort_param->start_recpos+=MI_DYN_ALIGN_SIZE); - searching=1; - } - case COMPRESSED_RECORD: - for (searching=0 ;; searching=1, sort_param->pos++) - { - if (_mi_read_cache(&sort_param->read_cache,(byte*) block_info.header, - sort_param->pos, - share->pack.ref_length,READING_NEXT)) - DBUG_RETURN(-1); - if (searching && ! sort_param->fix_datafile) - { - param->error_printed=1; - param->retry_repair=1; - param->testflag|=T_RETRY_WITHOUT_QUICK; - DBUG_RETURN(1); /* Something wrong with data */ - } - sort_param->start_recpos=sort_param->pos; - if (_mi_pack_get_block_info(info,&block_info,-1,sort_param->pos)) - DBUG_RETURN(-1); - if (!block_info.rec_len && - sort_param->pos + MEMMAP_EXTRA_MARGIN == - sort_param->read_cache.end_of_file) - DBUG_RETURN(-1); - if (block_info.rec_len < (uint) share->min_pack_length || - block_info.rec_len > (uint) share->max_pack_length) - { - if (! searching) - mi_check_print_info(param,"Found block with wrong recordlength: %d at %s\n", - block_info.rec_len, - llstr(sort_param->pos,llbuff)); - continue; - } - if (_mi_read_cache(&sort_param->read_cache,(byte*) sort_param->rec_buff, - block_info.filepos, block_info.rec_len, - READING_NEXT)) - { - if (! searching) - mi_check_print_info(param,"Couldn't read whole record from %s", - llstr(sort_param->pos,llbuff)); - continue; - } - if (_mi_pack_rec_unpack(info,sort_param->record,sort_param->rec_buff, - block_info.rec_len)) - { - if (! searching) - mi_check_print_info(param,"Found wrong record at %s", - llstr(sort_param->pos,llbuff)); - continue; - } - info->checksum=mi_checksum(info,sort_param->record); - if (!sort_param->fix_datafile) - { - sort_param->filepos=sort_param->pos; - if (sort_param->master) - share->state.split++; - } - sort_param->max_pos=(sort_param->pos=block_info.filepos+ - block_info.rec_len); - info->packed_length=block_info.rec_len; - if (param->calc_checksum) - param->glob_crc+= info->checksum; - DBUG_RETURN(0); - } - } - DBUG_RETURN(1); /* Impossible */ -} - - - /* Write record to new file */ - -int sort_write_record(MI_SORT_PARAM *sort_param) -{ - int flag; - uint length; - ulong block_length,reclength; - byte *from; - byte block_buff[8]; - SORT_INFO *sort_info=sort_param->sort_info; - MI_CHECK *param=sort_info->param; - MI_INFO *info=sort_info->info; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("sort_write_record"); - - if (sort_param->fix_datafile) - { - switch (sort_info->new_data_file_type) { - case STATIC_RECORD: - if (my_b_write(&info->rec_cache,sort_param->record, - share->base.pack_reclength)) - { - mi_check_print_error(param,"%d when writing to datafile",my_errno); - DBUG_RETURN(1); - } - sort_param->filepos+=share->base.pack_reclength; - info->s->state.split++; - /* sort_info->param->glob_crc+=mi_static_checksum(info, sort_param->record); */ - break; - case DYNAMIC_RECORD: - if (! info->blobs) - from=sort_param->rec_buff; - else - { - /* must be sure that local buffer is big enough */ - reclength=info->s->base.pack_reclength+ - _my_calc_total_blob_length(info,sort_param->record)+ - ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+ - MI_DYN_DELETE_BLOCK_HEADER; - if (sort_info->buff_length < reclength) - { - if (!(sort_info->buff=my_realloc(sort_info->buff, (uint) reclength, - MYF(MY_FREE_ON_ERROR | - MY_ALLOW_ZERO_PTR)))) - DBUG_RETURN(1); - sort_info->buff_length=reclength; - } - from=sort_info->buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER); - } - info->checksum=mi_checksum(info,sort_param->record); - reclength=_mi_rec_pack(info,from,sort_param->record); - flag=0; - /* sort_info->param->glob_crc+=info->checksum; */ - - do - { - block_length=reclength+ 3 + test(reclength >= (65520-3)); - if (block_length < share->base.min_block_length) - block_length=share->base.min_block_length; - info->update|=HA_STATE_WRITE_AT_END; - block_length=MY_ALIGN(block_length,MI_DYN_ALIGN_SIZE); - if (block_length > MI_MAX_BLOCK_LENGTH) - block_length=MI_MAX_BLOCK_LENGTH; - if (_mi_write_part_record(info,0L,block_length, - sort_param->filepos+block_length, - &from,&reclength,&flag)) - { - mi_check_print_error(param,"%d when writing to datafile",my_errno); - DBUG_RETURN(1); - } - sort_param->filepos+=block_length; - info->s->state.split++; - } while (reclength); - /* sort_info->param->glob_crc+=info->checksum; */ - break; - case COMPRESSED_RECORD: - reclength=info->packed_length; - length=save_pack_length(block_buff,reclength); - if (info->s->base.blobs) - length+=save_pack_length(block_buff+length,info->blob_length); - if (my_b_write(&info->rec_cache,block_buff,length) || - my_b_write(&info->rec_cache,(byte*) sort_param->rec_buff,reclength)) - { - mi_check_print_error(param,"%d when writing to datafile",my_errno); - DBUG_RETURN(1); - } - /* sort_info->param->glob_crc+=info->checksum; */ - sort_param->filepos+=reclength+length; - info->s->state.split++; - break; - } - } - if (sort_param->master) - { - info->state->records++; - if ((param->testflag & T_WRITE_LOOP) && - (info->state->records % WRITE_COUNT) == 0) - { - char llbuff[22]; - printf("%s\r", llstr(info->state->records,llbuff)); - VOID(fflush(stdout)); - } - } - DBUG_RETURN(0); -} /* sort_write_record */ - - - /* Compare two keys from _create_index_by_sort */ - -static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a, - const void *b) -{ - uint not_used; - return (ha_key_cmp(sort_param->seg, *((uchar**) a), *((uchar**) b), - USE_WHOLE_KEY, SEARCH_SAME,¬_used)); -} /* sort_key_cmp */ - - -static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a) -{ - uint diff_pos; - char llbuff[22],llbuff2[22]; - SORT_INFO *sort_info=sort_param->sort_info; - MI_CHECK *param= sort_info->param; - int cmp; - - if (sort_info->key_block->inited) - { - cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey, - (uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE, - &diff_pos); - sort_param->unique[diff_pos-1]++; - } - else - { - cmp= -1; - } - if ((sort_param->keyinfo->flag & HA_NOSAME) && cmp == 0) - { - sort_info->dupp++; - sort_info->info->lastpos=get_record_for_key(sort_info->info, - sort_param->keyinfo, - (uchar*) a); - mi_check_print_warning(param, - "Duplicate key for record at %10s against record at %10s", - llstr(sort_info->info->lastpos,llbuff), - llstr(get_record_for_key(sort_info->info, - sort_param->keyinfo, - sort_info->key_block-> - lastkey), - llbuff2)); - param->testflag|=T_RETRY_WITHOUT_QUICK; - if (sort_info->param->testflag & T_VERBOSE) - _mi_print_key(stdout,sort_param->seg,(uchar*) a, USE_WHOLE_KEY); - return (sort_delete_record(sort_param)); - } -#ifndef DBUG_OFF - if (cmp > 0) - { - mi_check_print_error(param, - "Internal error: Keys are not in order from sort"); - return(1); - } -#endif - return (sort_insert_key(sort_param,sort_info->key_block, - (uchar*) a, HA_OFFSET_ERROR)); -} /* sort_key_write */ - -int sort_ft_buf_flush(MI_SORT_PARAM *sort_param) -{ - SORT_INFO *sort_info=sort_param->sort_info; - SORT_KEY_BLOCKS *key_block=sort_info->key_block; - MYISAM_SHARE *share=sort_info->info->s; - uint val_off, val_len; - int error; - SORT_FT_BUF *ft_buf=sort_info->ft_buf; - uchar *from, *to; - - val_len=share->ft2_keyinfo.keylength; - get_key_full_length_rdonly(val_off, ft_buf->lastkey); - to=ft_buf->lastkey+val_off; - - if (ft_buf->buf) - { - /* flushing first-level tree */ - error=sort_insert_key(sort_param,key_block,ft_buf->lastkey, - HA_OFFSET_ERROR); - for (from=to+val_len; - !error && from < ft_buf->buf; - from+= val_len) - { - memcpy(to, from, val_len); - error=sort_insert_key(sort_param,key_block,ft_buf->lastkey, - HA_OFFSET_ERROR); - } - return error; - } - /* flushing second-level tree keyblocks */ - error=flush_pending_blocks(sort_param); - /* updating lastkey with second-level tree info */ - ft_intXstore(ft_buf->lastkey+val_off, -ft_buf->count); - _mi_dpointer(sort_info->info, ft_buf->lastkey+val_off+HA_FT_WLEN, - share->state.key_root[sort_param->key]); - /* restoring first level tree data in sort_info/sort_param */ - sort_info->key_block=sort_info->key_block_end- sort_info->param->sort_key_blocks; - sort_param->keyinfo=share->keyinfo+sort_param->key; - share->state.key_root[sort_param->key]=HA_OFFSET_ERROR; - /* writing lastkey in first-level tree */ - return error ? error : - sort_insert_key(sort_param,sort_info->key_block, - ft_buf->lastkey,HA_OFFSET_ERROR); -} - -static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a) -{ - uint a_len, val_off, val_len, error; - uchar *p; - SORT_INFO *sort_info=sort_param->sort_info; - SORT_FT_BUF *ft_buf=sort_info->ft_buf; - SORT_KEY_BLOCKS *key_block=sort_info->key_block; - - val_len=HA_FT_WLEN+sort_info->info->s->base.rec_reflength; - get_key_full_length_rdonly(a_len, (uchar *)a); - - if (!ft_buf) - { - /* - use two-level tree only if key_reflength fits in rec_reflength place - and row format is NOT static - for _mi_dpointer not to garble offsets - */ - if ((sort_info->info->s->base.key_reflength <= - sort_info->info->s->base.rec_reflength) && - (sort_info->info->s->options & - (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD))) - ft_buf=(SORT_FT_BUF *)my_malloc(sort_param->keyinfo->block_length + - sizeof(SORT_FT_BUF), MYF(MY_WME)); - - if (!ft_buf) - { - sort_param->key_write=sort_key_write; - return sort_key_write(sort_param, a); - } - sort_info->ft_buf=ft_buf; - goto word_init_ft_buf; /* no need to duplicate the code */ - } - get_key_full_length_rdonly(val_off, ft_buf->lastkey); - - if (mi_compare_text(sort_param->seg->charset, - ((uchar *)a)+1,a_len-1, - ft_buf->lastkey+1,val_off-1, 0, 0)==0) - { - if (!ft_buf->buf) /* store in second-level tree */ - { - ft_buf->count++; - return sort_insert_key(sort_param,key_block, - ((uchar *)a)+a_len, HA_OFFSET_ERROR); - } - - /* storing the key in the buffer. */ - memcpy (ft_buf->buf, (char *)a+a_len, val_len); - ft_buf->buf+=val_len; - if (ft_buf->buf < ft_buf->end) - return 0; - - /* converting to two-level tree */ - p=ft_buf->lastkey+val_off; - - while (key_block->inited) - key_block++; - sort_info->key_block=key_block; - sort_param->keyinfo=& sort_info->info->s->ft2_keyinfo; - ft_buf->count=(ft_buf->buf - p)/val_len; - - /* flushing buffer to second-level tree */ - for (error=0; !error && p < ft_buf->buf; p+= val_len) - error=sort_insert_key(sort_param,key_block,p,HA_OFFSET_ERROR); - ft_buf->buf=0; - return error; - } - - /* flushing buffer */ - if ((error=sort_ft_buf_flush(sort_param))) - return error; - -word_init_ft_buf: - a_len+=val_len; - memcpy(ft_buf->lastkey, a, a_len); - ft_buf->buf=ft_buf->lastkey+a_len; - /* - 32 is just a safety margin here - (at least max(val_len, sizeof(nod_flag)) should be there). - May be better performance could be achieved if we'd put - (sort_info->keyinfo->block_length-32)/XXX - instead. - TODO: benchmark the best value for XXX. - */ - ft_buf->end=ft_buf->lastkey+ (sort_param->keyinfo->block_length-32); - return 0; -} /* sort_ft_key_write */ - - - /* get pointer to record from a key */ - -static my_off_t get_record_for_key(MI_INFO *info, MI_KEYDEF *keyinfo, - uchar *key) -{ - return _mi_dpos(info,0,key+_mi_keylength(keyinfo,key)); -} /* get_record_for_key */ - - - /* Insert a key in sort-key-blocks */ - -static int sort_insert_key(MI_SORT_PARAM *sort_param, - register SORT_KEY_BLOCKS *key_block, uchar *key, - my_off_t prev_block) -{ - uint a_length,t_length,nod_flag; - my_off_t filepos,key_file_length; - uchar *anc_buff,*lastkey; - MI_KEY_PARAM s_temp; - MI_INFO *info; - MI_KEYDEF *keyinfo=sort_param->keyinfo; - SORT_INFO *sort_info= sort_param->sort_info; - MI_CHECK *param=sort_info->param; - DBUG_ENTER("sort_insert_key"); - - anc_buff=key_block->buff; - info=sort_info->info; - lastkey=key_block->lastkey; - nod_flag= (key_block == sort_info->key_block ? 0 : - info->s->base.key_reflength); - - if (!key_block->inited) - { - key_block->inited=1; - if (key_block == sort_info->key_block_end) - { - mi_check_print_error(param,"To many key-block-levels; Try increasing sort_key_blocks"); - DBUG_RETURN(1); - } - a_length=2+nod_flag; - key_block->end_pos=anc_buff+2; - lastkey=0; /* No previous key in block */ - } - else - a_length=mi_getint(anc_buff); - - /* Save pointer to previous block */ - if (nod_flag) - _mi_kpointer(info,key_block->end_pos,prev_block); - - t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, - (uchar*) 0,lastkey,lastkey,key, - &s_temp); - (*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp); - a_length+=t_length; - mi_putint(anc_buff,a_length,nod_flag); - key_block->end_pos+=t_length; - if (a_length <= keyinfo->block_length) - { - VOID(_mi_move_key(keyinfo,key_block->lastkey,key)); - key_block->last_length=a_length-t_length; - DBUG_RETURN(0); - } - - /* Fill block with end-zero and write filled block */ - mi_putint(anc_buff,key_block->last_length,nod_flag); - bzero((byte*) anc_buff+key_block->last_length, - keyinfo->block_length- key_block->last_length); - key_file_length=info->state->key_file_length; - if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR) - DBUG_RETURN(1); - - /* If we read the page from the key cache, we have to write it back to it */ - if (key_file_length == info->state->key_file_length) - { - if (_mi_write_keypage(info, keyinfo, filepos, DFLT_INIT_HITS, anc_buff)) - DBUG_RETURN(1); - } - else if (my_pwrite(info->s->kfile,(byte*) anc_buff, - (uint) keyinfo->block_length,filepos, param->myf_rw)) - DBUG_RETURN(1); - DBUG_DUMP("buff",(byte*) anc_buff,mi_getint(anc_buff)); - - /* Write separator-key to block in next level */ - if (sort_insert_key(sort_param,key_block+1,key_block->lastkey,filepos)) - DBUG_RETURN(1); - - /* clear old block and write new key in it */ - key_block->inited=0; - DBUG_RETURN(sort_insert_key(sort_param, key_block,key,prev_block)); -} /* sort_insert_key */ - - - /* Delete record when we found a duplicated key */ - -static int sort_delete_record(MI_SORT_PARAM *sort_param) -{ - uint i; - int old_file,error; - uchar *key; - SORT_INFO *sort_info=sort_param->sort_info; - MI_CHECK *param=sort_info->param; - MI_INFO *info=sort_info->info; - DBUG_ENTER("sort_delete_record"); - - if ((param->testflag & (T_FORCE_UNIQUENESS|T_QUICK)) == T_QUICK) - { - mi_check_print_error(param, - "Quick-recover aborted; Run recovery without switch -q or with switch -qq"); - DBUG_RETURN(1); - } - if (info->s->options & HA_OPTION_COMPRESS_RECORD) - { - mi_check_print_error(param, - "Recover aborted; Can't run standard recovery on compressed tables with errors in data-file. Use switch 'myisamchk --safe-recover' to fix it\n",stderr);; - DBUG_RETURN(1); - } - - old_file=info->dfile; - info->dfile=info->rec_cache.file; - if (sort_info->current_key) - { - key=info->lastkey+info->s->base.max_key_length; - if ((error=(*info->s->read_rnd)(info,sort_param->record,info->lastpos,0)) && - error != HA_ERR_RECORD_DELETED) - { - mi_check_print_error(param,"Can't read record to be removed"); - info->dfile=old_file; - DBUG_RETURN(1); - } - - for (i=0 ; i < sort_info->current_key ; i++) - { - uint key_length=_mi_make_key(info,i,key,sort_param->record,info->lastpos); - if (_mi_ck_delete(info,i,key,key_length)) - { - mi_check_print_error(param,"Can't delete key %d from record to be removed",i+1); - info->dfile=old_file; - DBUG_RETURN(1); - } - } - if (param->calc_checksum) - param->glob_crc-=(*info->s->calc_checksum)(info, sort_param->record); - } - error=flush_io_cache(&info->rec_cache) || (*info->s->delete_record)(info); - info->dfile=old_file; /* restore actual value */ - info->state->records--; - DBUG_RETURN(error); -} /* sort_delete_record */ - - /* Fix all pending blocks and flush everything to disk */ - -int flush_pending_blocks(MI_SORT_PARAM *sort_param) -{ - uint nod_flag,length; - my_off_t filepos,key_file_length; - SORT_KEY_BLOCKS *key_block; - SORT_INFO *sort_info= sort_param->sort_info; - myf myf_rw=sort_info->param->myf_rw; - MI_INFO *info=sort_info->info; - MI_KEYDEF *keyinfo=sort_param->keyinfo; - DBUG_ENTER("flush_pending_blocks"); - - filepos= HA_OFFSET_ERROR; /* if empty file */ - nod_flag=0; - for (key_block=sort_info->key_block ; key_block->inited ; key_block++) - { - key_block->inited=0; - length=mi_getint(key_block->buff); - if (nod_flag) - _mi_kpointer(info,key_block->end_pos,filepos); - key_file_length=info->state->key_file_length; - bzero((byte*) key_block->buff+length, keyinfo->block_length-length); - if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR) - DBUG_RETURN(1); - - /* If we read the page from the key cache, we have to write it back */ - if (key_file_length == info->state->key_file_length) - { - if (_mi_write_keypage(info, keyinfo, filepos, - DFLT_INIT_HITS, key_block->buff)) - DBUG_RETURN(1); - } - else if (my_pwrite(info->s->kfile,(byte*) key_block->buff, - (uint) keyinfo->block_length,filepos, myf_rw)) - DBUG_RETURN(1); - DBUG_DUMP("buff",(byte*) key_block->buff,length); - nod_flag=1; - } - info->s->state.key_root[sort_param->key]=filepos; /* Last is root for tree */ - DBUG_RETURN(0); -} /* flush_pending_blocks */ - - /* alloc space and pointers for key_blocks */ - -static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks, - uint buffer_length) -{ - reg1 uint i; - SORT_KEY_BLOCKS *block; - DBUG_ENTER("alloc_key_blocks"); - - if (!(block=(SORT_KEY_BLOCKS*) my_malloc((sizeof(SORT_KEY_BLOCKS)+ - buffer_length+IO_SIZE)*blocks, - MYF(0)))) - { - mi_check_print_error(param,"Not enough memory for sort-key-blocks"); - return(0); - } - for (i=0 ; i < blocks ; i++) - { - block[i].inited=0; - block[i].buff=(uchar*) (block+blocks)+(buffer_length+IO_SIZE)*i; - } - DBUG_RETURN(block); -} /* alloc_key_blocks */ - - - /* Check if file is almost full */ - -int test_if_almost_full(MI_INFO *info) -{ - if (info->s->options & HA_OPTION_COMPRESS_RECORD) - return 0; - return (my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0))/10*9 > - (my_off_t) (info->s->base.max_key_file_length) || - my_seek(info->dfile,0L,MY_SEEK_END,MYF(0))/10*9 > - (my_off_t) info->s->base.max_data_file_length); -} - - /* Recreate table with bigger more alloced record-data */ - -int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) -{ - int error; - MI_INFO info; - MYISAM_SHARE share; - MI_KEYDEF *keyinfo,*key,*key_end; - HA_KEYSEG *keysegs,*keyseg; - MI_COLUMNDEF *recdef,*rec,*end; - MI_UNIQUEDEF *uniquedef,*u_ptr,*u_end; - MI_STATUS_INFO status_info; - uint unpack,key_parts; - ha_rows max_records; - ulonglong file_length,tmp_length; - MI_CREATE_INFO create_info; - - error=1; /* Default error */ - info= **org_info; - status_info= (*org_info)->state[0]; - info.state= &status_info; - share= *(*org_info)->s; - unpack= (share.options & HA_OPTION_COMPRESS_RECORD) && - (param->testflag & T_UNPACK); - if (!(keyinfo=(MI_KEYDEF*) my_alloca(sizeof(MI_KEYDEF)*share.base.keys))) - return 0; - memcpy((byte*) keyinfo,(byte*) share.keyinfo, - (size_t) (sizeof(MI_KEYDEF)*share.base.keys)); - - key_parts= share.base.all_key_parts; - if (!(keysegs=(HA_KEYSEG*) my_alloca(sizeof(HA_KEYSEG)* - (key_parts+share.base.keys)))) - { - my_afree((gptr) keyinfo); - return 1; - } - if (!(recdef=(MI_COLUMNDEF*) - my_alloca(sizeof(MI_COLUMNDEF)*(share.base.fields+1)))) - { - my_afree((gptr) keyinfo); - my_afree((gptr) keysegs); - return 1; - } - if (!(uniquedef=(MI_UNIQUEDEF*) - my_alloca(sizeof(MI_UNIQUEDEF)*(share.state.header.uniques+1)))) - { - my_afree((gptr) recdef); - my_afree((gptr) keyinfo); - my_afree((gptr) keysegs); - return 1; - } - - /* Copy the column definitions */ - memcpy((byte*) recdef,(byte*) share.rec, - (size_t) (sizeof(MI_COLUMNDEF)*(share.base.fields+1))); - for (rec=recdef,end=recdef+share.base.fields; rec != end ; rec++) - { - if (unpack && !(share.options & HA_OPTION_PACK_RECORD) && - rec->type != FIELD_BLOB && - rec->type != FIELD_VARCHAR && - rec->type != FIELD_CHECK) - rec->type=(int) FIELD_NORMAL; - } - - /* Change the new key to point at the saved key segments */ - memcpy((byte*) keysegs,(byte*) share.keyparts, - (size_t) (sizeof(HA_KEYSEG)*(key_parts+share.base.keys+ - share.state.header.uniques))); - keyseg=keysegs; - for (key=keyinfo,key_end=keyinfo+share.base.keys; key != key_end ; key++) - { - key->seg=keyseg; - for (; keyseg->type ; keyseg++) - { - if (param->language) - keyseg->language=param->language; /* change language */ - } - keyseg++; /* Skip end pointer */ - } - - /* Copy the unique definitions and change them to point at the new key - segments*/ - memcpy((byte*) uniquedef,(byte*) share.uniqueinfo, - (size_t) (sizeof(MI_UNIQUEDEF)*(share.state.header.uniques))); - for (u_ptr=uniquedef,u_end=uniquedef+share.state.header.uniques; - u_ptr != u_end ; u_ptr++) - { - u_ptr->seg=keyseg; - keyseg+=u_ptr->keysegs+1; - } - if (share.options & HA_OPTION_COMPRESS_RECORD) - share.base.records=max_records=info.state->records; - else if (share.base.min_pack_length) - max_records=(ha_rows) (my_seek(info.dfile,0L,MY_SEEK_END,MYF(0)) / - (ulong) share.base.min_pack_length); - else - max_records=0; - unpack= (share.options & HA_OPTION_COMPRESS_RECORD) && - (param->testflag & T_UNPACK); - share.options&= ~HA_OPTION_TEMP_COMPRESS_RECORD; - - file_length=(ulonglong) my_seek(info.dfile,0L,MY_SEEK_END,MYF(0)); - tmp_length= file_length+file_length/10; - set_if_bigger(file_length,param->max_data_file_length); - set_if_bigger(file_length,tmp_length); - set_if_bigger(file_length,(ulonglong) share.base.max_data_file_length); - - VOID(mi_close(*org_info)); - bzero((char*) &create_info,sizeof(create_info)); - create_info.max_rows=max(max_records,share.base.records); - create_info.reloc_rows=share.base.reloc; - create_info.old_options=(share.options | - (unpack ? HA_OPTION_TEMP_COMPRESS_RECORD : 0)); - - create_info.data_file_length=file_length; - create_info.auto_increment=share.state.auto_increment; - create_info.raid_type= share.base.raid_type; - create_info.raid_chunks= share.base.raid_chunks; - create_info.raid_chunksize= share.base.raid_chunksize; - create_info.language = (param->language ? param->language : - share.state.header.language); - create_info.key_file_length= status_info.key_file_length; - /* We don't have to handle symlinks here because we are using - HA_DONT_TOUCH_DATA */ - if (mi_create(filename, - share.base.keys - share.state.header.uniques, - keyinfo, share.base.fields, recdef, - share.state.header.uniques, uniquedef, - &create_info, - HA_DONT_TOUCH_DATA)) - { - mi_check_print_error(param,"Got error %d when trying to recreate indexfile",my_errno); - goto end; - } - *org_info=mi_open(filename,O_RDWR, - (param->testflag & T_WAIT_FOREVER) ? HA_OPEN_WAIT_IF_LOCKED : - (param->testflag & T_DESCRIPT) ? HA_OPEN_IGNORE_IF_LOCKED : - HA_OPEN_ABORT_IF_LOCKED); - if (!*org_info) - { - mi_check_print_error(param,"Got error %d when trying to open re-created indexfile", - my_errno); - goto end; - } - /* We are modifing */ - (*org_info)->s->options&= ~HA_OPTION_READ_ONLY_DATA; - VOID(_mi_readinfo(*org_info,F_WRLCK,0)); - (*org_info)->state->records=info.state->records; - if (share.state.create_time) - (*org_info)->s->state.create_time=share.state.create_time; - (*org_info)->s->state.unique=(*org_info)->this_unique= - share.state.unique; - (*org_info)->s->state.checksum=share.state.checksum; - (*org_info)->state->del=info.state->del; - (*org_info)->s->state.dellink=share.state.dellink; - (*org_info)->state->empty=info.state->empty; - (*org_info)->state->data_file_length=info.state->data_file_length; - if (update_state_info(param,*org_info,UPDATE_TIME | UPDATE_STAT | - UPDATE_OPEN_COUNT)) - goto end; - error=0; -end: - my_afree((gptr) uniquedef); - my_afree((gptr) keyinfo); - my_afree((gptr) recdef); - my_afree((gptr) keysegs); - return error; -} - - - /* write suffix to data file if neaded */ - -int write_data_suffix(SORT_INFO *sort_info, my_bool fix_datafile) -{ - MI_INFO *info=sort_info->info; - - if (info->s->options & HA_OPTION_COMPRESS_RECORD && fix_datafile) - { - char buff[MEMMAP_EXTRA_MARGIN]; - bzero(buff,sizeof(buff)); - if (my_b_write(&info->rec_cache,buff,sizeof(buff))) - { - mi_check_print_error(sort_info->param, - "%d when writing to datafile",my_errno); - return 1; - } - sort_info->param->read_cache.end_of_file+=sizeof(buff); - } - return 0; -} - - /* Update state and myisamchk_time of indexfile */ - -int update_state_info(MI_CHECK *param, MI_INFO *info,uint update) -{ - MYISAM_SHARE *share=info->s; - - if (update & UPDATE_OPEN_COUNT) - { - share->state.open_count=0; - share->global_changed=0; - } - if (update & UPDATE_STAT) - { - uint i, key_parts= mi_uint2korr(share->state.header.key_parts); - share->state.rec_per_key_rows=info->state->records; - share->state.changed&= ~STATE_NOT_ANALYZED; - if (info->state->records) - { - for (i=0; i<key_parts; i++) - { - if (!(share->state.rec_per_key_part[i]=param->rec_per_key_part[i])) - share->state.changed|= STATE_NOT_ANALYZED; - } - } - } - if (update & (UPDATE_STAT | UPDATE_SORT | UPDATE_TIME | UPDATE_AUTO_INC)) - { - if (update & UPDATE_TIME) - { - share->state.check_time= (long) time((time_t*) 0); - if (!share->state.create_time) - share->state.create_time=share->state.check_time; - } - if (mi_state_info_write(share->kfile,&share->state,1+2)) - goto err; - share->changed=0; - } - { /* Force update of status */ - int error; - uint r_locks=share->r_locks,w_locks=share->w_locks; - share->r_locks= share->w_locks= share->tot_locks= 0; - error=_mi_writeinfo(info,WRITEINFO_NO_UNLOCK); - share->r_locks=r_locks; - share->w_locks=w_locks; - share->tot_locks=r_locks+w_locks; - if (!error) - return 0; - } -err: - mi_check_print_error(param,"%d when updating keyfile",my_errno); - return 1; -} - - /* - Update auto increment value for a table - When setting the 'repair_only' flag we only want to change the - old auto_increment value if its wrong (smaller than some given key). - The reason is that we shouldn't change the auto_increment value - for a table without good reason when only doing a repair; If the - user have inserted and deleted rows, the auto_increment value - may be bigger than the biggest current row and this is ok. - - If repair_only is not set, we will update the flag to the value in - param->auto_increment is bigger than the biggest key. - */ - -void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, - my_bool repair_only) -{ - byte *record; - if (!info->s->base.auto_key || - !(((ulonglong) 1 << (info->s->base.auto_key-1) - & info->s->state.key_map))) - { - if (!(param->testflag & T_VERY_SILENT)) - mi_check_print_info(param, - "Table: %s doesn't have an auto increment key\n", - param->isam_file_name); - return; - } - if (!(param->testflag & T_SILENT) && - !(param->testflag & T_REP)) - printf("Updating MyISAM file: %s\n", param->isam_file_name); - /* - We have to use an allocated buffer instead of info->rec_buff as - _mi_put_key_in_record() may use info->rec_buff - */ - if (!(record= (byte*) my_malloc((uint) info->s->base.pack_reclength, - MYF(0)))) - { - mi_check_print_error(param,"Not enough memory for extra record"); - return; - } - - mi_extra(info,HA_EXTRA_KEYREAD,0); - if (mi_rlast(info, record, info->s->base.auto_key-1)) - { - if (my_errno != HA_ERR_END_OF_FILE) - { - mi_extra(info,HA_EXTRA_NO_KEYREAD,0); - my_free((char*) record, MYF(0)); - mi_check_print_error(param,"%d when reading last record",my_errno); - return; - } - if (!repair_only) - info->s->state.auto_increment=param->auto_increment_value; - } - else - { - ulonglong auto_increment= (repair_only ? info->s->state.auto_increment : - param->auto_increment_value); - info->s->state.auto_increment=0; - update_auto_increment(info, record); - set_if_bigger(info->s->state.auto_increment,auto_increment); - } - mi_extra(info,HA_EXTRA_NO_KEYREAD,0); - my_free((char*) record, MYF(0)); - update_state_info(param, info, UPDATE_AUTO_INC); - return; -} - - /* calculate unique keys for each part key */ - -void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part, - ulonglong *unique, ulonglong records) -{ - ulonglong count=0,tmp; - uint parts; - for (parts=0 ; parts < keyinfo->keysegs ; parts++) - { - count+=unique[parts]; - if (count == 0) - tmp=records; - else - tmp= (records + (count+1)/2) / (count+1); - /* for some weird keys (e.g. FULLTEXT) tmp can be <1 here. - let's ensure it is not */ - set_if_bigger(tmp,1); - if (tmp >= (ulonglong) ~(ulong) 0) - tmp=(ulonglong) ~(ulong) 0; - *rec_per_key_part=(ulong) tmp; - rec_per_key_part++; - } -} - - -static ha_checksum mi_byte_checksum(const byte *buf, uint length) -{ - ha_checksum crc; - const byte *end=buf+length; - for (crc=0; buf != end; buf++) - crc=((crc << 1) + *((uchar*) buf)) + - test(crc & (((ha_checksum) 1) << (8*sizeof(ha_checksum)-1))); - return crc; -} - -static my_bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows) -{ - uint key_maxlength=key->maxlength; - if (key->flag & HA_FULLTEXT) - { - uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT* - key->seg->charset->mbmaxlen; - key_maxlength+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN; - } - return (key->flag & HA_SPATIAL) || - (key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY | HA_FULLTEXT) && - ((ulonglong) rows * key_maxlength > - (ulonglong) myisam_max_temp_length)); -} - -/* - Deactivate all not unique index that can be recreated fast - These include packed keys on which sorting will use more temporary - space than the max allowed file length or for which the unpacked keys - will take much more space than packed keys. - Note that 'rows' may be zero for the case when we don't know how many - rows we will put into the file. - */ - -void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows) -{ - MYISAM_SHARE *share=info->s; - MI_KEYDEF *key=share->keyinfo; - uint i; - - DBUG_ASSERT(info->state->records == 0 && - (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES)); - for (i=0 ; i < share->base.keys ; i++,key++) - { - if (!(key->flag & (HA_NOSAME | HA_SPATIAL | HA_AUTO_KEY)) && - ! mi_too_big_key_for_sort(key,rows) && info->s->base.auto_key != i+1) - { - share->state.key_map&= ~ ((ulonglong) 1 << i); - info->update|= HA_STATE_CHANGED; - } - } -} - - -/* - Return TRUE if we can use repair by sorting - One can set the force argument to force to use sorting - even if the temporary file would be quite big! -*/ - -my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, - ulonglong key_map, my_bool force) -{ - MYISAM_SHARE *share=info->s; - MI_KEYDEF *key=share->keyinfo; - uint i; - - /* - mi_repair_by_sort only works if we have at least one key. If we don't - have any keys, we should use the normal repair. - */ - if (!key_map) - return FALSE; /* Can't use sort */ - for (i=0 ; i < share->base.keys ; i++,key++) - { - if (!force && mi_too_big_key_for_sort(key,rows)) - return FALSE; - } - return TRUE; -} - - -static void -set_data_file_type(SORT_INFO *sort_info, MYISAM_SHARE *share) -{ - if ((sort_info->new_data_file_type=share->data_file_type) == - COMPRESSED_RECORD && sort_info->param->testflag & T_UNPACK) - { - MYISAM_SHARE tmp; - - if (share->options & HA_OPTION_PACK_RECORD) - sort_info->new_data_file_type = DYNAMIC_RECORD; - else - sort_info->new_data_file_type = STATIC_RECORD; - - /* Set delete_function for sort_delete_record() */ - memcpy((char*) &tmp, share, sizeof(*share)); - tmp.options= ~HA_OPTION_COMPRESS_RECORD; - mi_setup_functions(&tmp); - share->delete_record=tmp.delete_record; - } -} diff --git a/myisam/mi_checksum.c b/myisam/mi_checksum.c deleted file mode 100644 index 33a51068fb0..00000000000 --- a/myisam/mi_checksum.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Calculate a checksum for a row */ - -#include "myisamdef.h" - -ha_checksum mi_checksum(MI_INFO *info, const byte *buf) -{ - uint i; - ha_checksum crc=0; - MI_COLUMNDEF *rec=info->s->rec; - - for (i=info->s->base.fields ; i-- ; buf+=(rec++)->length) - { - const byte *pos; - ulong length; - switch (rec->type) { - case FIELD_BLOB: - { - length=_mi_calc_blob_length(rec->length- - mi_portable_sizeof_char_ptr, - buf); - memcpy((char*) &pos, buf+rec->length- mi_portable_sizeof_char_ptr, - sizeof(char*)); - break; - } - case FIELD_VARCHAR: - { - uint pack_length= HA_VARCHAR_PACKLENGTH(rec->length-1); - if (pack_length == 1) - length= (ulong) *(uchar*) buf; - else - length= uint2korr(buf); - pos= buf+pack_length; - break; - } - default: - length=rec->length; - pos=buf; - break; - } - crc=my_checksum(crc, pos ? pos : "", length); - } - return crc; -} - - -ha_checksum mi_static_checksum(MI_INFO *info, const byte *pos) -{ - return my_checksum(0, pos, info->s->base.reclength); -} diff --git a/myisam/mi_close.c b/myisam/mi_close.c deleted file mode 100644 index 62f5617de1a..00000000000 --- a/myisam/mi_close.c +++ /dev/null @@ -1,118 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* close a isam-database */ -/* - TODO: - We need to have a separate mutex on the closed file to allow other threads - to open other files during the time we flush the cache and close this file -*/ - -#include "myisamdef.h" - -int mi_close(register MI_INFO *info) -{ - int error=0,flag; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("mi_close"); - DBUG_PRINT("enter",("base: %lx reopen: %u locks: %u", - info,(uint) share->reopen, (uint) share->tot_locks)); - - pthread_mutex_lock(&THR_LOCK_myisam); - if (info->lock_type == F_EXTRA_LCK) - info->lock_type=F_UNLCK; /* HA_EXTRA_NO_USER_CHANGE */ - - if (share->reopen == 1 && share->kfile >= 0) - _mi_decrement_open_count(info); - - if (info->lock_type != F_UNLCK) - { - if (mi_lock_database(info,F_UNLCK)) - error=my_errno; - } - pthread_mutex_lock(&share->intern_lock); - - if (share->options & HA_OPTION_READ_ONLY_DATA) - { - share->r_locks--; - share->tot_locks--; - } - if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED)) - { - if (end_io_cache(&info->rec_cache)) - error=my_errno; - info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); - } - flag= !--share->reopen; - myisam_open_list=list_delete(myisam_open_list,&info->open_list); - pthread_mutex_unlock(&share->intern_lock); - - my_free(mi_get_rec_buff_ptr(info, info->rec_buff), MYF(MY_ALLOW_ZERO_PTR)); - if (flag) - { - if (share->kfile >= 0 && - flush_key_blocks(share->key_cache, share->kfile, - share->temporary ? FLUSH_IGNORE_CHANGED : - FLUSH_RELEASE)) - error=my_errno; - if (share->kfile >= 0) - { - /* - If we are crashed, we can safely flush the current state as it will - not change the crashed state. - We can NOT write the state in other cases as other threads - may be using the file at this point - */ - if (share->mode != O_RDONLY && mi_is_crashed(info)) - mi_state_info_write(share->kfile, &share->state, 1); - if (my_close(share->kfile,MYF(0))) - error = my_errno; - } -#ifdef HAVE_MMAP - if (share->file_map) - _mi_unmap_file(info); -#endif - if (share->decode_trees) - { - my_free((gptr) share->decode_trees,MYF(0)); - my_free((gptr) share->decode_tables,MYF(0)); - } -#ifdef THREAD - thr_lock_delete(&share->lock); - VOID(pthread_mutex_destroy(&share->intern_lock)); - { - int i,keys; - keys = share->state.header.keys; - for(i=0; i<keys; i++) { - VOID(rwlock_destroy(&share->key_root_lock[i])); - } - } -#endif - my_free((gptr) info->s,MYF(0)); - } - pthread_mutex_unlock(&THR_LOCK_myisam); - if (info->dfile >= 0 && my_close(info->dfile,MYF(0))) - error = my_errno; - - myisam_log_command(MI_LOG_CLOSE,info,NULL,0,error); - my_free((gptr) info,MYF(0)); - - if (error) - { - DBUG_RETURN(my_errno=error); - } - DBUG_RETURN(0); -} /* mi_close */ diff --git a/myisam/mi_create.c b/myisam/mi_create.c deleted file mode 100644 index 8635d6bcf36..00000000000 --- a/myisam/mi_create.c +++ /dev/null @@ -1,792 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Create a MyISAM table */ - -#include "ftdefs.h" -#include "sp_defs.h" - -#if defined(MSDOS) || defined(__WIN__) -#ifdef __WIN__ -#include <fcntl.h> -#else -#include <process.h> /* Prototype for getpid */ -#endif -#endif -#include <m_ctype.h> - - /* - ** Old options is used when recreating database, from isamchk - */ - -int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, - uint columns, MI_COLUMNDEF *recinfo, - uint uniques, MI_UNIQUEDEF *uniquedefs, - MI_CREATE_INFO *ci,uint flags) -{ - register uint i,j; - File dfile,file; - int errpos,save_errno, create_mode= O_RDWR | O_TRUNC; - myf create_flag; - uint fields,length,max_key_length,packed,pointer,real_length_diff, - key_length,info_length,key_segs,options,min_key_length_skip, - base_pos,long_varchar_count,varchar_length, - max_key_block_length,unique_key_parts,fulltext_keys,offset; - ulong reclength, real_reclength,min_pack_length; - char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr; - ulong pack_reclength; - ulonglong tot_length,max_rows, tmp; - enum en_fieldtype type; - MYISAM_SHARE share; - MI_KEYDEF *keydef,tmp_keydef; - MI_UNIQUEDEF *uniquedef; - HA_KEYSEG *keyseg,tmp_keyseg; - MI_COLUMNDEF *rec; - ulong *rec_per_key_part; - my_off_t key_root[MI_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE]; - MI_CREATE_INFO tmp_create_info; - DBUG_ENTER("mi_create"); - - if (!ci) - { - bzero((char*) &tmp_create_info,sizeof(tmp_create_info)); - ci=&tmp_create_info; - } - - if (keys + uniques > MI_MAX_KEY || columns == 0) - { - DBUG_RETURN(my_errno=HA_WRONG_CREATE_OPTION); - } - LINT_INIT(dfile); - LINT_INIT(file); - pthread_mutex_lock(&THR_LOCK_myisam); - errpos=0; - options=0; - bzero((byte*) &share,sizeof(share)); - - if (flags & HA_DONT_TOUCH_DATA) - { - if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD)) - options=ci->old_options & - (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD | - HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM | - HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE); - else - options=ci->old_options & - (HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE); - } - - if (ci->reloc_rows > ci->max_rows) - ci->reloc_rows=ci->max_rows; /* Check if wrong parameter */ - - if (!(rec_per_key_part= - (ulong*) my_malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long), - MYF(MY_WME | MY_ZEROFILL)))) - DBUG_RETURN(my_errno); - - /* Start by checking fields and field-types used */ - - reclength=varchar_length=long_varchar_count=packed= - min_pack_length=pack_reclength=0; - for (rec=recinfo, fields=0 ; - fields != columns ; - rec++,fields++) - { - reclength+=rec->length; - if ((type=(enum en_fieldtype) rec->type) != FIELD_NORMAL && - type != FIELD_CHECK) - { - packed++; - if (type == FIELD_BLOB) - { - share.base.blobs++; - if (pack_reclength != INT_MAX32) - { - if (rec->length == 4+mi_portable_sizeof_char_ptr) - pack_reclength= INT_MAX32; - else - pack_reclength+=(1 << ((rec->length-mi_portable_sizeof_char_ptr)*8)); /* Max blob length */ - } - } - else if (type == FIELD_SKIP_PRESPACE || - type == FIELD_SKIP_ENDSPACE) - { - if (pack_reclength != INT_MAX32) - pack_reclength+= rec->length > 255 ? 2 : 1; - min_pack_length++; - } - else if (type == FIELD_VARCHAR) - { - varchar_length+= rec->length-1; /* Used for min_pack_length */ - packed--; - pack_reclength++; - min_pack_length++; - /* We must test for 257 as length includes pack-length */ - if (test(rec->length >= 257)) - { - long_varchar_count++; - pack_reclength+= 2; /* May be packed on 3 bytes */ - } - } - else if (type != FIELD_SKIP_ZERO) - { - min_pack_length+=rec->length; - packed--; /* Not a pack record type */ - } - } - else /* FIELD_NORMAL */ - min_pack_length+=rec->length; - } - if ((packed & 7) == 1) - { /* Bad packing, try to remove a zero-field */ - while (rec != recinfo) - { - rec--; - if (rec->type == (int) FIELD_SKIP_ZERO && rec->length == 1) - { - rec->type=(int) FIELD_NORMAL; - packed--; - min_pack_length++; - break; - } - } - } - - if (packed || (flags & HA_PACK_RECORD)) - options|=HA_OPTION_PACK_RECORD; /* Must use packed records */ - /* We can't use checksum with static length rows */ - if (!(options & HA_OPTION_PACK_RECORD)) - options&= ~HA_OPTION_CHECKSUM; - if (!(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD))) - min_pack_length+= varchar_length; - if (flags & HA_CREATE_TMP_TABLE) - { - options|= HA_OPTION_TMP_TABLE; - create_mode|= O_EXCL | O_NOFOLLOW; - } - if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM)) - { - options|= HA_OPTION_CHECKSUM; - min_pack_length++; - } - if (flags & HA_CREATE_DELAY_KEY_WRITE) - options|= HA_OPTION_DELAY_KEY_WRITE; - - packed=(packed+7)/8; - if (pack_reclength != INT_MAX32) - pack_reclength+= reclength+packed + - test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_PACK_RECORD)); - min_pack_length+=packed; - - if (!ci->data_file_length) - { - if (ci->max_rows == 0 || pack_reclength == INT_MAX32) - ci->data_file_length= INT_MAX32-1; /* Should be enough */ - else if ((~(ulonglong) 0)/ci->max_rows < (ulonglong) pack_reclength) - ci->data_file_length= ~(ulonglong) 0; - else - ci->data_file_length=(ulonglong) ci->max_rows*pack_reclength; - } - else if (!ci->max_rows) - ci->max_rows=(ha_rows) (ci->data_file_length/(min_pack_length + - ((options & HA_OPTION_PACK_RECORD) ? - 3 : 0))); - - if (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD)) - pointer=mi_get_pointer_length(ci->data_file_length,myisam_data_pointer_size); - else - pointer=mi_get_pointer_length(ci->max_rows,myisam_data_pointer_size); - if (!(max_rows=(ulonglong) ci->max_rows)) - max_rows= ((((ulonglong) 1 << (pointer*8)) -1) / min_pack_length); - - - real_reclength=reclength; - if (!(options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD))) - { - if (reclength <= pointer) - reclength=pointer+1; /* reserve place for delete link */ - } - else - reclength+= long_varchar_count; /* We need space for varchar! */ - - max_key_length=0; tot_length=0 ; key_segs=0; - fulltext_keys=0; - max_key_block_length=0; - share.state.rec_per_key_part=rec_per_key_part; - share.state.key_root=key_root; - share.state.key_del=key_del; - if (uniques) - { - max_key_block_length= myisam_block_size; - max_key_length= MI_UNIQUE_HASH_LENGTH + pointer; - } - - for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++) - { - - share.state.key_root[i]= HA_OFFSET_ERROR; - min_key_length_skip=length=real_length_diff=0; - key_length=pointer; - if (keydef->flag & HA_SPATIAL) - { -#ifdef HAVE_SPATIAL - /* BAR TODO to support 3D and more dimensions in the future */ - uint sp_segs=SPDIMS*2; - keydef->flag=HA_SPATIAL; - - if (flags & HA_DONT_TOUCH_DATA) - { - /* - called by myisamchk - i.e. table structure was taken from - MYI file and SPATIAL key *does have* additional sp_segs keysegs. - We'd better delete them now - */ - keydef->keysegs-=sp_segs; - } - - for (j=0, keyseg=keydef->seg ; (int) j < keydef->keysegs ; - j++, keyseg++) - { - if (keyseg->type != HA_KEYTYPE_BINARY && - keyseg->type != HA_KEYTYPE_VARBINARY1 && - keyseg->type != HA_KEYTYPE_VARBINARY2) - { - my_errno=HA_WRONG_CREATE_OPTION; - goto err; - } - } - keydef->keysegs+=sp_segs; - key_length+=SPLEN*sp_segs; - length++; /* At least one length byte */ - min_key_length_skip+=SPLEN*2*SPDIMS; -#else - my_errno= HA_ERR_UNSUPPORTED; - goto err; -#endif /*HAVE_SPATIAL*/ - } - else if (keydef->flag & HA_FULLTEXT) - { - keydef->flag=HA_FULLTEXT | HA_PACK_KEY | HA_VAR_LENGTH_KEY; - options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ - - for (j=0, keyseg=keydef->seg ; (int) j < keydef->keysegs ; - j++, keyseg++) - { - if (keyseg->type != HA_KEYTYPE_TEXT && - keyseg->type != HA_KEYTYPE_VARTEXT1 && - keyseg->type != HA_KEYTYPE_VARTEXT2) - { - my_errno=HA_WRONG_CREATE_OPTION; - goto err; - } - if (!(keyseg->flag & HA_BLOB_PART) && - (keyseg->type == HA_KEYTYPE_VARTEXT1 || - keyseg->type == HA_KEYTYPE_VARTEXT2)) - { - /* Make a flag that this is a VARCHAR */ - keyseg->flag|= HA_VAR_LENGTH_PART; - /* Store in bit_start number of bytes used to pack the length */ - keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1)? - 1 : 2); - } - } - - fulltext_keys++; - key_length+= HA_FT_MAXBYTELEN+HA_FT_WLEN; - length++; /* At least one length byte */ - min_key_length_skip+=HA_FT_MAXBYTELEN; - real_length_diff=HA_FT_MAXBYTELEN-FT_MAX_WORD_LEN_FOR_SORT; - } - else - { - /* Test if prefix compression */ - if (keydef->flag & HA_PACK_KEY) - { - /* Can't use space_compression on number keys */ - if ((keydef->seg[0].flag & HA_SPACE_PACK) && - keydef->seg[0].type == (int) HA_KEYTYPE_NUM) - keydef->seg[0].flag&= ~HA_SPACE_PACK; - - /* Only use HA_PACK_KEY when first segment is a variable length key */ - if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART | - HA_VAR_LENGTH_PART))) - { - /* pack relative to previous key */ - keydef->flag&= ~HA_PACK_KEY; - keydef->flag|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY; - } - else - { - keydef->seg[0].flag|=HA_PACK_KEY; /* for easyer intern test */ - keydef->flag|=HA_VAR_LENGTH_KEY; - options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ - } - } - if (keydef->flag & HA_BINARY_PACK_KEY) - options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ - - if (keydef->flag & HA_AUTO_KEY && ci->with_auto_increment) - share.base.auto_key=i+1; - for (j=0, keyseg=keydef->seg ; j < keydef->keysegs ; j++, keyseg++) - { - /* numbers are stored with high by first to make compression easier */ - switch (keyseg->type) { - case HA_KEYTYPE_SHORT_INT: - case HA_KEYTYPE_LONG_INT: - case HA_KEYTYPE_FLOAT: - case HA_KEYTYPE_DOUBLE: - case HA_KEYTYPE_USHORT_INT: - case HA_KEYTYPE_ULONG_INT: - case HA_KEYTYPE_LONGLONG: - case HA_KEYTYPE_ULONGLONG: - case HA_KEYTYPE_INT24: - case HA_KEYTYPE_UINT24: - case HA_KEYTYPE_INT8: - keyseg->flag|= HA_SWAP_KEY; - break; - case HA_KEYTYPE_VARTEXT1: - case HA_KEYTYPE_VARTEXT2: - case HA_KEYTYPE_VARBINARY1: - case HA_KEYTYPE_VARBINARY2: - if (!(keyseg->flag & HA_BLOB_PART)) - { - /* Make a flag that this is a VARCHAR */ - keyseg->flag|= HA_VAR_LENGTH_PART; - /* Store in bit_start number of bytes used to pack the length */ - keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1 || - keyseg->type == HA_KEYTYPE_VARBINARY1) ? - 1 : 2); - } - break; - default: - break; - } - if (keyseg->flag & HA_SPACE_PACK) - { - DBUG_ASSERT(!(keyseg->flag & HA_VAR_LENGTH_PART)); - keydef->flag |= HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY; - options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ - length++; /* At least one length byte */ - min_key_length_skip+=keyseg->length; - if (keyseg->length >= 255) - { /* prefix may be 3 bytes */ - min_key_length_skip+=2; - length+=2; - } - } - if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART)) - { - DBUG_ASSERT(!test_all_bits(keyseg->flag, - (HA_VAR_LENGTH_PART | HA_BLOB_PART))); - keydef->flag|=HA_VAR_LENGTH_KEY; - length++; /* At least one length byte */ - options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ - min_key_length_skip+=keyseg->length; - if (keyseg->length >= 255) - { /* prefix may be 3 bytes */ - min_key_length_skip+=2; - length+=2; - } - } - key_length+= keyseg->length; - if (keyseg->null_bit) - { - key_length++; - options|=HA_OPTION_PACK_KEYS; - keyseg->flag|=HA_NULL_PART; - keydef->flag|=HA_VAR_LENGTH_KEY | HA_NULL_PART_KEY; - } - } - } /* if HA_FULLTEXT */ - key_segs+=keydef->keysegs; - if (keydef->keysegs > MI_MAX_KEY_SEG) - { - my_errno=HA_WRONG_CREATE_OPTION; - goto err; - } - /* - key_segs may be 0 in the case when we only want to be able to - add on row into the table. This can happen with some DISTINCT queries - in MySQL - */ - if ((keydef->flag & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME && - key_segs) - share.state.rec_per_key_part[key_segs-1]=1L; - length+=key_length; - keydef->block_length= MI_BLOCK_SIZE(length-real_length_diff, - pointer,MI_MAX_KEYPTR_SIZE); - if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH || - length >= MI_MAX_KEY_BUFF) - { - my_errno=HA_WRONG_CREATE_OPTION; - goto err; - } - set_if_bigger(max_key_block_length,keydef->block_length); - keydef->keylength= (uint16) key_length; - keydef->minlength= (uint16) (length-min_key_length_skip); - keydef->maxlength= (uint16) length; - - if (length > max_key_length) - max_key_length= length; - tot_length+= (max_rows/(ulong) (((uint) keydef->block_length-5)/ - (length*2)))* - (ulong) keydef->block_length; - } - for (i=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; ) - key_del[i]=HA_OFFSET_ERROR; - - unique_key_parts=0; - offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH; - for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++) - { - uniquedef->key=keys+i; - unique_key_parts+=uniquedef->keysegs; - share.state.key_root[keys+i]= HA_OFFSET_ERROR; - tot_length+= (max_rows/(ulong) (((uint) myisam_block_size-5)/ - ((MI_UNIQUE_HASH_LENGTH + pointer)*2)))* - (ulong) myisam_block_size; - } - keys+=uniques; /* Each unique has 1 key */ - key_segs+=uniques; /* Each unique has 1 key seg */ - - base_pos=(MI_STATE_INFO_SIZE + keys * MI_STATE_KEY_SIZE + - max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH* - MI_STATE_KEYBLOCK_SIZE+ - key_segs*MI_STATE_KEYSEG_SIZE); - info_length=base_pos+(uint) (MI_BASE_INFO_SIZE+ - keys * MI_KEYDEF_SIZE+ - uniques * MI_UNIQUEDEF_SIZE + - (key_segs + unique_key_parts)*HA_KEYSEG_SIZE+ - columns*MI_COLUMNDEF_SIZE); - - bmove(share.state.header.file_version,(byte*) myisam_file_magic,4); - ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ? - HA_OPTION_COMPRESS_RECORD | - HA_OPTION_TEMP_COMPRESS_RECORD: 0); - mi_int2store(share.state.header.options,ci->old_options); - mi_int2store(share.state.header.header_length,info_length); - mi_int2store(share.state.header.state_info_length,MI_STATE_INFO_SIZE); - mi_int2store(share.state.header.base_info_length,MI_BASE_INFO_SIZE); - mi_int2store(share.state.header.base_pos,base_pos); - share.state.header.language= (ci->language ? - ci->language : default_charset_info->number); - share.state.header.max_block_size=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH; - - share.state.dellink = HA_OFFSET_ERROR; - share.state.process= (ulong) getpid(); - share.state.unique= (ulong) 0; - share.state.update_count=(ulong) 0; - share.state.version= (ulong) time((time_t*) 0); - share.state.sortkey= (ushort) ~0; - share.state.auto_increment=ci->auto_increment; - share.options=options; - share.base.rec_reflength=pointer; - /* Get estimate for index file length (this may be wrong for FT keys) */ - tmp= (tot_length + max_key_block_length * keys * - MI_INDEX_BLOCK_MARGIN) / MI_MIN_KEY_BLOCK_LENGTH; - /* - use maximum of key_file_length we calculated and key_file_length value we - got from MYI file header (see also myisampack.c:save_state) - */ - share.base.key_reflength= - mi_get_pointer_length(max(ci->key_file_length,tmp),3); - share.base.keys= share.state.header.keys= keys; - share.state.header.uniques= uniques; - share.state.header.fulltext_keys= fulltext_keys; - mi_int2store(share.state.header.key_parts,key_segs); - mi_int2store(share.state.header.unique_key_parts,unique_key_parts); - - share.state.key_map = ((ulonglong) 1 << keys)-1; - share.base.keystart = share.state.state.key_file_length= - MY_ALIGN(info_length, myisam_block_size); - share.base.max_key_block_length=max_key_block_length; - share.base.max_key_length=ALIGN_SIZE(max_key_length+4); - share.base.records=ci->max_rows; - share.base.reloc= ci->reloc_rows; - share.base.reclength=real_reclength; - share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM); - share.base.max_pack_length=pack_reclength; - share.base.min_pack_length=min_pack_length; - share.base.pack_bits=packed; - share.base.fields=fields; - share.base.pack_fields=packed; -#ifdef USE_RAID - share.base.raid_type=ci->raid_type; - share.base.raid_chunks=ci->raid_chunks; - share.base.raid_chunksize=ci->raid_chunksize; -#endif - - /* max_data_file_length and max_key_file_length are recalculated on open */ - if (options & HA_OPTION_TMP_TABLE) - share.base.max_data_file_length=(my_off_t) ci->data_file_length; - - share.base.min_block_length= - (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH && - ! share.base.blobs) ? - max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) : - MI_EXTEND_BLOCK_LENGTH; - if (! (flags & HA_DONT_TOUCH_DATA)) - share.state.create_time= (long) time((time_t*) 0); - - if (ci->index_file_name) - { - fn_format(filename, ci->index_file_name,"",MI_NAME_IEXT,4); - fn_format(linkname,name, "",MI_NAME_IEXT,4); - linkname_ptr=linkname; - /* - Don't create the table if the link or file exists to ensure that one - doesn't accidently destroy another table. - */ - create_flag=0; - } - else - { - fn_format(filename,name,"",MI_NAME_IEXT,(4+ (flags & HA_DONT_TOUCH_DATA) ? - 32 : 0)); - linkname_ptr=0; - /* Replace the current file */ - create_flag=MY_DELETE_OLD; - } - - /* - If a MRG_MyISAM table is in use, the mapped MyISAM tables are open, - but no entry is made in the table cache for them. - A TRUNCATE command checks for the table in the cache only and could - be fooled to believe, the table is not open. - Pull the emergency brake in this situation. (Bug #8306) - */ - if (test_if_reopen(filename)) - { - my_printf_error(0, "MyISAM table '%s' is in use " - "(most likely by a MERGE table). Try FLUSH TABLES.", - MYF(0), name + dirname_length(name)); - goto err; - } - - if ((file= my_create_with_symlink(linkname_ptr, filename, 0, create_mode, - MYF(MY_WME | create_flag))) < 0) - goto err; - errpos=1; - - if (!(flags & HA_DONT_TOUCH_DATA)) - { -#ifdef USE_RAID - if (share.base.raid_type) - { - (void) fn_format(filename,name,"",MI_NAME_DEXT,2+4); - if ((dfile=my_raid_create(filename, 0, create_mode, - share.base.raid_type, - share.base.raid_chunks, - share.base.raid_chunksize, - MYF(MY_WME | MY_RAID))) < 0) - goto err; - } - else -#endif - { - if (ci->data_file_name) - { - fn_format(filename, ci->data_file_name,"",MI_NAME_DEXT,4); - fn_format(linkname, name, "",MI_NAME_DEXT,4); - linkname_ptr=linkname; - create_flag=0; - } - else - { - fn_format(filename,name,"",MI_NAME_DEXT,4); - linkname_ptr=0; - create_flag=MY_DELETE_OLD; - } - if ((dfile= - my_create_with_symlink(linkname_ptr, filename, 0, create_mode, - MYF(MY_WME | create_flag))) < 0) - goto err; - } - errpos=3; - } - - if (mi_state_info_write(file, &share.state, 2) || - mi_base_info_write(file, &share.base)) - goto err; -#ifndef DBUG_OFF - if ((uint) my_tell(file,MYF(0)) != base_pos+ MI_BASE_INFO_SIZE) - { - uint pos=(uint) my_tell(file,MYF(0)); - DBUG_PRINT("warning",("base_length: %d != used_length: %d", - base_pos+ MI_BASE_INFO_SIZE, pos)); - } -#endif - - /* Write key and keyseg definitions */ - for (i=0 ; i < share.base.keys - uniques; i++) - { - uint sp_segs=(keydefs[i].flag & HA_SPATIAL) ? 2*SPDIMS : 0; - - if (mi_keydef_write(file, &keydefs[i])) - goto err; - for (j=0 ; j < keydefs[i].keysegs-sp_segs ; j++) - if (mi_keyseg_write(file, &keydefs[i].seg[j])) - goto err; -#ifdef HAVE_SPATIAL - for (j=0 ; j < sp_segs ; j++) - { - HA_KEYSEG sseg; - sseg.type=SPTYPE; - sseg.language= 7; /* Binary */ - sseg.null_bit=0; - sseg.bit_start=0; - sseg.bit_end=0; - sseg.bit_length= 0; - sseg.bit_pos= 0; - sseg.length=SPLEN; - sseg.null_pos=0; - sseg.start=j*SPLEN; - sseg.flag= HA_SWAP_KEY; - if (mi_keyseg_write(file, &sseg)) - goto err; - } -#endif - } - /* Create extra keys for unique definitions */ - offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH; - bzero((char*) &tmp_keydef,sizeof(tmp_keydef)); - bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg)); - for (i=0; i < uniques ; i++) - { - tmp_keydef.keysegs=1; - tmp_keydef.flag= HA_UNIQUE_CHECK; - tmp_keydef.block_length= myisam_block_size; - tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer; - tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength; - tmp_keyseg.type= MI_UNIQUE_HASH_TYPE; - tmp_keyseg.length= MI_UNIQUE_HASH_LENGTH; - tmp_keyseg.start= offset; - offset+= MI_UNIQUE_HASH_LENGTH; - if (mi_keydef_write(file,&tmp_keydef) || - mi_keyseg_write(file,(&tmp_keyseg))) - goto err; - } - - /* Save unique definition */ - for (i=0 ; i < share.state.header.uniques ; i++) - { - HA_KEYSEG *keyseg_end; - keyseg= uniquedefs[i].seg; - if (mi_uniquedef_write(file, &uniquedefs[i])) - goto err; - for (keyseg= uniquedefs[i].seg, keyseg_end= keyseg+ uniquedefs[i].keysegs; - keyseg < keyseg_end; - keyseg++) - { - switch (keyseg->type) { - case HA_KEYTYPE_VARTEXT1: - case HA_KEYTYPE_VARTEXT2: - case HA_KEYTYPE_VARBINARY1: - case HA_KEYTYPE_VARBINARY2: - if (!(keyseg->flag & HA_BLOB_PART)) - { - keyseg->flag|= HA_VAR_LENGTH_PART; - keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1 || - keyseg->type == HA_KEYTYPE_VARBINARY1) ? - 1 : 2); - } - break; - default: - break; - } - if (mi_keyseg_write(file, keyseg)) - goto err; - } - } - for (i=0 ; i < share.base.fields ; i++) - if (mi_recinfo_write(file, &recinfo[i])) - goto err; - -#ifndef DBUG_OFF - if ((uint) my_tell(file,MYF(0)) != info_length) - { - uint pos= (uint) my_tell(file,MYF(0)); - DBUG_PRINT("warning",("info_length: %d != used_length: %d", - info_length, pos)); - } -#endif - - /* Enlarge files */ - if (my_chsize(file,(ulong) share.base.keystart,0,MYF(0))) - goto err; - - if (! (flags & HA_DONT_TOUCH_DATA)) - { -#ifdef USE_RELOC - if (my_chsize(dfile,share.base.min_pack_length*ci->reloc_rows,0,MYF(0))) - goto err; -#endif - errpos=2; - if (my_close(dfile,MYF(0))) - goto err; - } - errpos=0; - pthread_mutex_unlock(&THR_LOCK_myisam); - if (my_close(file,MYF(0))) - goto err; - my_free((char*) rec_per_key_part,MYF(0)); - DBUG_RETURN(0); - -err: - pthread_mutex_unlock(&THR_LOCK_myisam); - save_errno=my_errno; - switch (errpos) { - case 3: - VOID(my_close(dfile,MYF(0))); - /* fall through */ - case 2: - /* QQ: Tõnu should add a call to my_raid_delete() here */ - if (! (flags & HA_DONT_TOUCH_DATA)) - my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_DEXT,2+4), - MYF(0)); - /* fall through */ - case 1: - VOID(my_close(file,MYF(0))); - if (! (flags & HA_DONT_TOUCH_DATA)) - my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,2+4), - MYF(0)); - } - my_free((char*) rec_per_key_part, MYF(0)); - DBUG_RETURN(my_errno=save_errno); /* return the fatal errno */ -} - - -uint mi_get_pointer_length(ulonglong file_length, uint def) -{ - if (file_length) /* If not default */ - { - if (file_length >= (longlong) 1 << 56) - def=8; - if (file_length >= (longlong) 1 << 48) - def=7; - if (file_length >= (longlong) 1 << 40) - def=6; - else if (file_length >= (longlong) 1 << 32) - def=5; - else if (file_length >= (1L << 24)) - def=4; - else if (file_length >= (1L << 16)) - def=3; - else - def=2; - } - return def; -} diff --git a/myisam/mi_dbug.c b/myisam/mi_dbug.c deleted file mode 100644 index e782d21afe7..00000000000 --- a/myisam/mi_dbug.c +++ /dev/null @@ -1,193 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Support rutiner with are using with dbug */ - -#include "myisamdef.h" - - /* Print a key in user understandable format */ - -void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg, - const uchar *key, uint length) -{ - int flag; - short int s_1; - long int l_1; - float f_1; - double d_1; - const uchar *end; - const uchar *key_end=key+length; - - VOID(fputs("Key: \"",stream)); - flag=0; - for (; keyseg->type && key < key_end ;keyseg++) - { - if (flag++) - VOID(putc('-',stream)); - end= key+ keyseg->length; - if (keyseg->flag & HA_NULL_PART) - { - if (!*key) - { - fprintf(stream,"NULL"); - continue; - } - key++; - } - - switch (keyseg->type) { - case HA_KEYTYPE_BINARY: - if (!(keyseg->flag & HA_SPACE_PACK) && keyseg->length == 1) - { /* packed binary digit */ - VOID(fprintf(stream,"%d",(uint) *key++)); - break; - } - /* fall through */ - case HA_KEYTYPE_TEXT: - case HA_KEYTYPE_NUM: - if (keyseg->flag & HA_SPACE_PACK) - { - VOID(fprintf(stream,"%.*s",(int) *key,key+1)); - key+= (int) *key+1; - } - else - { - VOID(fprintf(stream,"%.*s",(int) keyseg->length,key)); - key=end; - } - break; - case HA_KEYTYPE_INT8: - VOID(fprintf(stream,"%d",(int) *((signed char*) key))); - key=end; - break; - case HA_KEYTYPE_SHORT_INT: - s_1= mi_sint2korr(key); - VOID(fprintf(stream,"%d",(int) s_1)); - key=end; - break; - case HA_KEYTYPE_USHORT_INT: - { - ushort u_1; - u_1= mi_uint2korr(key); - VOID(fprintf(stream,"%u",(uint) u_1)); - key=end; - break; - } - case HA_KEYTYPE_LONG_INT: - l_1=mi_sint4korr(key); - VOID(fprintf(stream,"%ld",l_1)); - key=end; - break; - case HA_KEYTYPE_ULONG_INT: - l_1=mi_sint4korr(key); - VOID(fprintf(stream,"%lu",(ulong) l_1)); - key=end; - break; - case HA_KEYTYPE_INT24: - VOID(fprintf(stream,"%ld",(long) mi_sint3korr(key))); - key=end; - break; - case HA_KEYTYPE_UINT24: - VOID(fprintf(stream,"%lu",(ulong) mi_uint3korr(key))); - key=end; - break; - case HA_KEYTYPE_FLOAT: - mi_float4get(f_1,key); - VOID(fprintf(stream,"%g",(double) f_1)); - key=end; - break; - case HA_KEYTYPE_DOUBLE: - mi_float8get(d_1,key); - VOID(fprintf(stream,"%g",d_1)); - key=end; - break; -#ifdef HAVE_LONG_LONG - case HA_KEYTYPE_LONGLONG: - { - char buff[21]; - longlong2str(mi_sint8korr(key),buff,-10); - VOID(fprintf(stream,"%s",buff)); - key=end; - break; - } - case HA_KEYTYPE_ULONGLONG: - { - char buff[21]; - longlong2str(mi_sint8korr(key),buff,10); - VOID(fprintf(stream,"%s",buff)); - key=end; - break; - } - case HA_KEYTYPE_BIT: - { - uint i; - fputs("0x",stream); - for (i=0 ; i < keyseg->length ; i++) - fprintf(stream, "%02x", (uint) *key++); - key= end; - break; - } - -#endif - case HA_KEYTYPE_VARTEXT1: /* VARCHAR and TEXT */ - case HA_KEYTYPE_VARTEXT2: /* VARCHAR and TEXT */ - case HA_KEYTYPE_VARBINARY1: /* VARBINARY and BLOB */ - case HA_KEYTYPE_VARBINARY2: /* VARBINARY and BLOB */ - { - uint tmp_length; - get_key_length(tmp_length,key); - /* - The following command sometimes gives a warning from valgrind. - Not yet sure if the bug is in valgrind, glibc or mysqld - */ - VOID(fprintf(stream,"%.*s",(int) tmp_length,key)); - key+=tmp_length; - break; - } - default: break; /* This never happens */ - } - } - VOID(fputs("\"\n",stream)); - return; -} /* print_key */ - - -#ifdef EXTRA_DEBUG - -my_bool check_table_is_closed(const char *name, const char *where) -{ - char filename[FN_REFLEN]; - LIST *pos; - DBUG_ENTER("check_table_is_closed"); - - (void) fn_format(filename,name,"",MI_NAME_IEXT,4+16+32); - for (pos=myisam_open_list ; pos ; pos=pos->next) - { - MI_INFO *info=(MI_INFO*) pos->data; - MYISAM_SHARE *share=info->s; - if (!strcmp(share->unique_file_name,filename)) - { - if (share->last_version) - { - fprintf(stderr,"Warning: Table: %s is open on %s\n", name,where); - DBUG_PRINT("warning",("Table: %s is open on %s", name,where)); - DBUG_RETURN(1); - } - } - } - DBUG_RETURN(0); -} -#endif /* EXTRA_DEBUG */ diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c deleted file mode 100644 index cc4a17182f7..00000000000 --- a/myisam/mi_delete.c +++ /dev/null @@ -1,887 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Remove a row from a MyISAM table */ - -#include "fulltext.h" -#include "rt_index.h" - -static int d_search(MI_INFO *info,MI_KEYDEF *keyinfo,uint comp_flag, - uchar *key,uint key_length,my_off_t page,uchar *anc_buff); -static int del(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,uchar *anc_buff, - my_off_t leaf_page,uchar *leaf_buff,uchar *keypos, - my_off_t next_block,uchar *ret_key); -static int underflow(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *anc_buff, - my_off_t leaf_page,uchar *leaf_buff,uchar *keypos); -static uint remove_key(MI_KEYDEF *keyinfo,uint nod_flag,uchar *keypos, - uchar *lastkey,uchar *page_end, - my_off_t *next_block); -static int _mi_ck_real_delete(register MI_INFO *info,MI_KEYDEF *keyinfo, - uchar *key, uint key_length, my_off_t *root); - - -int mi_delete(MI_INFO *info,const byte *record) -{ - uint i; - uchar *old_key; - int save_errno; - char lastpos[8]; - - MYISAM_SHARE *share=info->s; - DBUG_ENTER("mi_delete"); - - /* Test if record is in datafile */ - - DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_usage", - mi_print_error(info->s, HA_ERR_CRASHED); - DBUG_RETURN(my_errno= HA_ERR_CRASHED);); - DBUG_EXECUTE_IF("my_error_test_undefined_error", - mi_print_error(info->s, INT_MAX); - DBUG_RETURN(my_errno= INT_MAX);); - if (!(info->update & HA_STATE_AKTIV)) - { - DBUG_RETURN(my_errno=HA_ERR_KEY_NOT_FOUND); /* No database read */ - } - if (share->options & HA_OPTION_READ_ONLY_DATA) - { - DBUG_RETURN(my_errno=EACCES); - } - if (_mi_readinfo(info,F_WRLCK,1)) - DBUG_RETURN(my_errno); - if (info->s->calc_checksum) - info->checksum=(*info->s->calc_checksum)(info,record); - if ((*share->compare_record)(info,record)) - goto err; /* Error on read-check */ - - if (_mi_mark_file_changed(info)) - goto err; - - /* Remove all keys from the .ISAM file */ - - old_key=info->lastkey2; - for (i=0 ; i < share->base.keys ; i++ ) - { - if (((ulonglong) 1 << i) & info->s->state.key_map) - { - info->s->keyinfo[i].version++; - if (info->s->keyinfo[i].flag & HA_FULLTEXT ) - { - if (_mi_ft_del(info,i,(char*) old_key,record,info->lastpos)) - goto err; - } - else - { - if (info->s->keyinfo[i].ck_delete(info,i,old_key, - _mi_make_key(info,i,old_key,record,info->lastpos))) - goto err; - } - } - } - - if ((*share->delete_record)(info)) - goto err; /* Remove record from database */ - info->s->state.checksum-=info->checksum; - - info->update= HA_STATE_CHANGED+HA_STATE_DELETED+HA_STATE_ROW_CHANGED; - info->state->records--; - - mi_sizestore(lastpos,info->lastpos); - myisam_log_command(MI_LOG_DELETE,info,(byte*) lastpos,sizeof(lastpos),0); - VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); - allow_break(); /* Allow SIGHUP & SIGINT */ - if (info->invalidator != 0) - { - DBUG_PRINT("info", ("invalidator... '%s' (delete)", info->filename)); - (*info->invalidator)(info->filename); - info->invalidator=0; - } - DBUG_RETURN(0); - -err: - save_errno=my_errno; - mi_sizestore(lastpos,info->lastpos); - myisam_log_command(MI_LOG_DELETE,info,(byte*) lastpos, sizeof(lastpos),0); - if (save_errno != HA_ERR_RECORD_CHANGED) - { - mi_print_error(info->s, HA_ERR_CRASHED); - mi_mark_crashed(info); /* mark table crashed */ - } - VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); - info->update|=HA_STATE_WRITTEN; /* Buffer changed */ - allow_break(); /* Allow SIGHUP & SIGINT */ - my_errno=save_errno; - if (save_errno == HA_ERR_KEY_NOT_FOUND) - { - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - } - - DBUG_RETURN(my_errno); -} /* mi_delete */ - - - /* Remove a key from the btree index */ - -int _mi_ck_delete(register MI_INFO *info, uint keynr, uchar *key, - uint key_length) -{ - return _mi_ck_real_delete(info, info->s->keyinfo+keynr, key, key_length, - &info->s->state.key_root[keynr]); -} /* _mi_ck_delete */ - - -static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo, - uchar *key, uint key_length, my_off_t *root) -{ - int error; - uint nod_flag; - my_off_t old_root; - uchar *root_buff; - DBUG_ENTER("_mi_ck_real_delete"); - - if ((old_root=*root) == HA_OFFSET_ERROR) - { - mi_print_error(info->s, HA_ERR_CRASHED); - DBUG_RETURN(my_errno=HA_ERR_CRASHED); - } - if (!(root_buff= (uchar*) my_alloca((uint) keyinfo->block_length+ - MI_MAX_KEY_BUFF*2))) - { - DBUG_PRINT("error",("Couldn't allocate memory")); - DBUG_RETURN(my_errno=ENOMEM); - } - DBUG_PRINT("info",("root_page: %ld",old_root)); - if (!_mi_fetch_keypage(info,keyinfo,old_root,DFLT_INIT_HITS,root_buff,0)) - { - error= -1; - goto err; - } - if ((error=d_search(info,keyinfo, - (keyinfo->flag & HA_FULLTEXT ? SEARCH_FIND - : SEARCH_SAME), - key,key_length,old_root,root_buff)) >0) - { - if (error == 2) - { - DBUG_PRINT("test",("Enlarging of root when deleting")); - error=_mi_enlarge_root(info,keyinfo,key,root); - } - else /* error == 1 */ - { - if (mi_getint(root_buff) <= (nod_flag=mi_test_if_nod(root_buff))+3) - { - error=0; - if (nod_flag) - *root=_mi_kpos(nod_flag,root_buff+2+nod_flag); - else - *root=HA_OFFSET_ERROR; - if (_mi_dispose(info,keyinfo,old_root,DFLT_INIT_HITS)) - error= -1; - } - else - error=_mi_write_keypage(info,keyinfo,old_root, - DFLT_INIT_HITS,root_buff); - } - } -err: - my_afree((gptr) root_buff); - DBUG_PRINT("exit",("Return: %d",error)); - DBUG_RETURN(error); -} /* _mi_ck_real_delete */ - - - /* - ** Remove key below key root - ** Return values: - ** 1 if there are less buffers; In this case anc_buff is not saved - ** 2 if there are more buffers - ** -1 on errors - */ - -static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, - uint comp_flag, uchar *key, uint key_length, - my_off_t page, uchar *anc_buff) -{ - int flag,ret_value,save_flag; - uint length,nod_flag,search_key_length; - my_bool last_key; - uchar *leaf_buff,*keypos; - my_off_t leaf_page,next_block; - uchar lastkey[MI_MAX_KEY_BUFF]; - DBUG_ENTER("d_search"); - DBUG_DUMP("page",(byte*) anc_buff,mi_getint(anc_buff)); - - search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY; - flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key, search_key_length, - comp_flag, &keypos, lastkey, &last_key); - if (flag == MI_FOUND_WRONG_KEY) - { - DBUG_PRINT("error",("Found wrong key")); - DBUG_RETURN(-1); - } - nod_flag=mi_test_if_nod(anc_buff); - - if (!flag && keyinfo->flag & HA_FULLTEXT) - { - uint off; - int subkeys; - - get_key_full_length_rdonly(off, lastkey); - subkeys=ft_sintXkorr(lastkey+off); - DBUG_ASSERT(info->ft1_to_ft2==0 || subkeys >=0); - comp_flag=SEARCH_SAME; - if (subkeys >= 0) - { - /* normal word, one-level tree structure */ - if (info->ft1_to_ft2) - { - /* we're in ft1->ft2 conversion mode. Saving key data */ - insert_dynamic(info->ft1_to_ft2, (char*) (lastkey+off)); - } - else - { - /* we need exact match only if not in ft1->ft2 conversion mode */ - flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key,USE_WHOLE_KEY, - comp_flag, &keypos, lastkey, &last_key); - } - /* fall through to normal delete */ - } - else - { - /* popular word. two-level tree. going down */ - uint tmp_key_length; - my_off_t root; - uchar *kpos=keypos; - - if (!(tmp_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&kpos,lastkey))) - { - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno= HA_ERR_CRASHED; - DBUG_RETURN(-1); - } - root=_mi_dpos(info,nod_flag,kpos); - if (subkeys == -1) - { - /* the last entry in sub-tree */ - _mi_dispose(info, keyinfo, root,DFLT_INIT_HITS); - /* fall through to normal delete */ - } - else - { - keyinfo=&info->s->ft2_keyinfo; - kpos-=keyinfo->keylength+nod_flag; /* we'll modify key entry 'in vivo' */ - get_key_full_length_rdonly(off, key); - key+=off; - ret_value=_mi_ck_real_delete(info, &info->s->ft2_keyinfo, - key, HA_FT_WLEN, &root); - _mi_dpointer(info, kpos+HA_FT_WLEN, root); - subkeys++; - ft_intXstore(kpos, subkeys); - if (!ret_value) - ret_value=_mi_write_keypage(info,keyinfo,page, - DFLT_INIT_HITS,anc_buff); - DBUG_PRINT("exit",("Return: %d",ret_value)); - DBUG_RETURN(ret_value); - } - } - } - leaf_buff=0; - LINT_INIT(leaf_page); - if (nod_flag) - { - leaf_page=_mi_kpos(nod_flag,keypos); - if (!(leaf_buff= (uchar*) my_alloca((uint) keyinfo->block_length+ - MI_MAX_KEY_BUFF*2))) - { - DBUG_PRINT("error",("Couldn't allocate memory")); - my_errno=ENOMEM; - DBUG_PRINT("exit",("Return: %d",-1)); - DBUG_RETURN(-1); - } - if (!_mi_fetch_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff,0)) - goto err; - } - - if (flag != 0) - { - if (!nod_flag) - { - DBUG_PRINT("error",("Didn't find key")); - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; /* This should newer happend */ - goto err; - } - save_flag=0; - ret_value=d_search(info,keyinfo,comp_flag,key,key_length, - leaf_page,leaf_buff); - } - else - { /* Found key */ - uint tmp; - length=mi_getint(anc_buff); - if (!(tmp= remove_key(keyinfo,nod_flag,keypos,lastkey,anc_buff+length, - &next_block))) - goto err; - - length-= tmp; - - mi_putint(anc_buff,length,nod_flag); - if (!nod_flag) - { /* On leaf page */ - if (_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff)) - { - DBUG_PRINT("exit",("Return: %d",-1)); - DBUG_RETURN(-1); - } - /* Page will be update later if we return 1 */ - DBUG_RETURN(test(length <= (info->quick_mode ? MI_MIN_KEYBLOCK_LENGTH : - (uint) keyinfo->underflow_block_length))); - } - save_flag=1; - ret_value=del(info,keyinfo,key,anc_buff,leaf_page,leaf_buff,keypos, - next_block,lastkey); - } - if (ret_value >0) - { - save_flag=1; - if (ret_value == 1) - ret_value= underflow(info,keyinfo,anc_buff,leaf_page,leaf_buff,keypos); - else - { /* This happens only with packed keys */ - DBUG_PRINT("test",("Enlarging of key when deleting")); - if (!_mi_get_last_key(info,keyinfo,anc_buff,lastkey,keypos,&length)) - { - goto err; - } - ret_value=_mi_insert(info,keyinfo,key,anc_buff,keypos,lastkey, - (uchar*) 0,(uchar*) 0,(my_off_t) 0,(my_bool) 0); - } - } - if (ret_value == 0 && mi_getint(anc_buff) > keyinfo->block_length) - { - save_flag=1; - ret_value=_mi_split_page(info,keyinfo,key,anc_buff,lastkey,0) | 2; - } - if (save_flag && ret_value != 1) - ret_value|=_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff); - else - { - DBUG_DUMP("page",(byte*) anc_buff,mi_getint(anc_buff)); - } - my_afree((byte*) leaf_buff); - DBUG_PRINT("exit",("Return: %d",ret_value)); - DBUG_RETURN(ret_value); - -err: - my_afree((byte*) leaf_buff); - DBUG_PRINT("exit",("Error: %d",my_errno)); - DBUG_RETURN (-1); -} /* d_search */ - - - /* Remove a key that has a page-reference */ - -static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key, - uchar *anc_buff, my_off_t leaf_page, uchar *leaf_buff, - uchar *keypos, /* Pos to where deleted key was */ - my_off_t next_block, - uchar *ret_key) /* key before keypos in anc_buff */ -{ - int ret_value,length; - uint a_length,nod_flag,tmp; - my_off_t next_page; - uchar keybuff[MI_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key; - MYISAM_SHARE *share=info->s; - MI_KEY_PARAM s_temp; - DBUG_ENTER("del"); - DBUG_PRINT("enter",("leaf_page: %ld keypos: %lx",leaf_page,keypos)); - DBUG_DUMP("leaf_buff",(byte*) leaf_buff,mi_getint(leaf_buff)); - - endpos=leaf_buff+mi_getint(leaf_buff); - if (!(key_start=_mi_get_last_key(info,keyinfo,leaf_buff,keybuff,endpos, - &tmp))) - DBUG_RETURN(-1); - - if ((nod_flag=mi_test_if_nod(leaf_buff))) - { - next_page= _mi_kpos(nod_flag,endpos); - if (!(next_buff= (uchar*) my_alloca((uint) keyinfo->block_length+ - MI_MAX_KEY_BUFF*2))) - DBUG_RETURN(-1); - if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,next_buff,0)) - ret_value= -1; - else - { - DBUG_DUMP("next_page",(byte*) next_buff,mi_getint(next_buff)); - if ((ret_value=del(info,keyinfo,key,anc_buff,next_page,next_buff, - keypos,next_block,ret_key)) >0) - { - endpos=leaf_buff+mi_getint(leaf_buff); - if (ret_value == 1) - { - ret_value=underflow(info,keyinfo,leaf_buff,next_page, - next_buff,endpos); - if (ret_value == 0 && mi_getint(leaf_buff) > keyinfo->block_length) - { - ret_value=_mi_split_page(info,keyinfo,key,leaf_buff,ret_key,0) | 2; - } - } - else - { - DBUG_PRINT("test",("Inserting of key when deleting")); - if (_mi_get_last_key(info,keyinfo,leaf_buff,keybuff,endpos, - &tmp)) - goto err; - ret_value=_mi_insert(info,keyinfo,key,leaf_buff,endpos,keybuff, - (uchar*) 0,(uchar*) 0,(my_off_t) 0,0); - } - } - if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff)) - goto err; - } - my_afree((byte*) next_buff); - DBUG_RETURN(ret_value); - } - - /* Remove last key from leaf page */ - - mi_putint(leaf_buff,key_start-leaf_buff,nod_flag); - if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff)) - goto err; - - /* Place last key in ancestor page on deleted key position */ - - a_length=mi_getint(anc_buff); - endpos=anc_buff+a_length; - if (keypos != anc_buff+2+share->base.key_reflength && - !_mi_get_last_key(info,keyinfo,anc_buff,ret_key,keypos,&tmp)) - goto err; - prev_key=(keypos == anc_buff+2+share->base.key_reflength ? - 0 : ret_key); - length=(*keyinfo->pack_key)(keyinfo,share->base.key_reflength, - keypos == endpos ? (uchar*) 0 : keypos, - prev_key, prev_key, - keybuff,&s_temp); - if (length > 0) - bmove_upp((byte*) endpos+length,(byte*) endpos,(uint) (endpos-keypos)); - else - bmove(keypos,keypos-length, (int) (endpos-keypos)+length); - (*keyinfo->store_key)(keyinfo,keypos,&s_temp); - /* Save pointer to next leaf */ - if (!(*keyinfo->get_key)(keyinfo,share->base.key_reflength,&keypos,ret_key)) - goto err; - _mi_kpointer(info,keypos - share->base.key_reflength,next_block); - mi_putint(anc_buff,a_length+length,share->base.key_reflength); - - DBUG_RETURN( mi_getint(leaf_buff) <= - (info->quick_mode ? MI_MIN_KEYBLOCK_LENGTH : - (uint) keyinfo->underflow_block_length)); -err: - DBUG_RETURN(-1); -} /* del */ - - - /* Balances adjacent pages if underflow occours */ - -static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo, - uchar *anc_buff, - my_off_t leaf_page,/* Ancestor page and underflow page */ - uchar *leaf_buff, - uchar *keypos) /* Position to pos after key */ -{ - int t_length; - uint length,anc_length,buff_length,leaf_length,p_length,s_length,nod_flag, - key_reflength,key_length; - my_off_t next_page; - uchar anc_key[MI_MAX_KEY_BUFF],leaf_key[MI_MAX_KEY_BUFF], - *buff,*endpos,*next_keypos,*anc_pos,*half_pos,*temp_pos,*prev_key, - *after_key; - MI_KEY_PARAM s_temp; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("underflow"); - DBUG_PRINT("enter",("leaf_page: %ld keypos: %lx",(long) leaf_page,keypos)); - DBUG_DUMP("anc_buff",(byte*) anc_buff,mi_getint(anc_buff)); - DBUG_DUMP("leaf_buff",(byte*) leaf_buff,mi_getint(leaf_buff)); - - buff=info->buff; - info->buff_used=1; - next_keypos=keypos; - nod_flag=mi_test_if_nod(leaf_buff); - p_length=nod_flag+2; - anc_length=mi_getint(anc_buff); - leaf_length=mi_getint(leaf_buff); - key_reflength=share->base.key_reflength; - if (info->s->keyinfo+info->lastinx == keyinfo) - info->page_changed=1; - - if ((keypos < anc_buff+anc_length && (info->state->records & 1)) || - keypos == anc_buff+2+key_reflength) - { /* Use page right of anc-page */ - DBUG_PRINT("test",("use right page")); - - if (keyinfo->flag & HA_BINARY_PACK_KEY) - { - if (!(next_keypos=_mi_get_key(info, keyinfo, - anc_buff, buff, keypos, &length))) - goto err; - } - else - { - /* Got to end of found key */ - buff[0]=buff[1]=0; /* Avoid length error check if packed key */ - if (!(*keyinfo->get_key)(keyinfo,key_reflength,&next_keypos, - buff)) - goto err; - } - next_page= _mi_kpos(key_reflength,next_keypos); - if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0)) - goto err; - buff_length=mi_getint(buff); - DBUG_DUMP("next",(byte*) buff,buff_length); - - /* find keys to make a big key-page */ - bmove((byte*) next_keypos-key_reflength,(byte*) buff+2, - key_reflength); - if (!_mi_get_last_key(info,keyinfo,anc_buff,anc_key,next_keypos,&length) - || !_mi_get_last_key(info,keyinfo,leaf_buff,leaf_key, - leaf_buff+leaf_length,&length)) - goto err; - - /* merge pages and put parting key from anc_buff between */ - prev_key=(leaf_length == p_length ? (uchar*) 0 : leaf_key); - t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,buff+p_length, - prev_key, prev_key, - anc_key, &s_temp); - length=buff_length-p_length; - endpos=buff+length+leaf_length+t_length; - /* buff will always be larger than before !*/ - bmove_upp((byte*) endpos, (byte*) buff+buff_length,length); - memcpy((byte*) buff, (byte*) leaf_buff,(size_t) leaf_length); - (*keyinfo->store_key)(keyinfo,buff+leaf_length,&s_temp); - buff_length=(uint) (endpos-buff); - mi_putint(buff,buff_length,nod_flag); - - /* remove key from anc_buff */ - - if (!(s_length=remove_key(keyinfo,key_reflength,keypos,anc_key, - anc_buff+anc_length,(my_off_t *) 0))) - goto err; - - anc_length-=s_length; - mi_putint(anc_buff,anc_length,key_reflength); - - if (buff_length <= keyinfo->block_length) - { /* Keys in one page */ - memcpy((byte*) leaf_buff,(byte*) buff,(size_t) buff_length); - if (_mi_dispose(info,keyinfo,next_page,DFLT_INIT_HITS)) - goto err; - } - else - { /* Page is full */ - endpos=anc_buff+anc_length; - DBUG_PRINT("test",("anc_buff: %lx endpos: %lx",anc_buff,endpos)); - if (keypos != anc_buff+2+key_reflength && - !_mi_get_last_key(info,keyinfo,anc_buff,anc_key,keypos,&length)) - goto err; - if (!(half_pos=_mi_find_half_pos(nod_flag, keyinfo, buff, leaf_key, - &key_length, &after_key))) - goto err; - length=(uint) (half_pos-buff); - memcpy((byte*) leaf_buff,(byte*) buff,(size_t) length); - mi_putint(leaf_buff,length,nod_flag); - - /* Correct new keypointer to leaf_page */ - half_pos=after_key; - _mi_kpointer(info,leaf_key+key_length,next_page); - /* Save key in anc_buff */ - prev_key=(keypos == anc_buff+2+key_reflength ? (uchar*) 0 : anc_key), - t_length=(*keyinfo->pack_key)(keyinfo,key_reflength, - (keypos == endpos ? (uchar*) 0 : - keypos), - prev_key, prev_key, - leaf_key, &s_temp); - if (t_length >= 0) - bmove_upp((byte*) endpos+t_length,(byte*) endpos, - (uint) (endpos-keypos)); - else - bmove(keypos,keypos-t_length,(uint) (endpos-keypos)+t_length); - (*keyinfo->store_key)(keyinfo,keypos,&s_temp); - mi_putint(anc_buff,(anc_length+=t_length),key_reflength); - - /* Store key first in new page */ - if (nod_flag) - bmove((byte*) buff+2,(byte*) half_pos-nod_flag,(size_t) nod_flag); - if (!(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key)) - goto err; - t_length=(int) (*keyinfo->pack_key)(keyinfo, nod_flag, (uchar*) 0, - (uchar*) 0, (uchar *) 0, - leaf_key, &s_temp); - /* t_length will always be > 0 for a new page !*/ - length=(uint) ((buff+mi_getint(buff))-half_pos); - bmove((byte*) buff+p_length+t_length,(byte*) half_pos,(size_t) length); - (*keyinfo->store_key)(keyinfo,buff+p_length,&s_temp); - mi_putint(buff,length+t_length+p_length,nod_flag); - - if (_mi_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff)) - goto err; - } - if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff)) - goto err; - DBUG_RETURN(anc_length <= ((info->quick_mode ? MI_MIN_BLOCK_LENGTH : - (uint) keyinfo->underflow_block_length))); - } - - DBUG_PRINT("test",("use left page")); - - keypos=_mi_get_last_key(info,keyinfo,anc_buff,anc_key,keypos,&length); - if (!keypos) - goto err; - next_page= _mi_kpos(key_reflength,keypos); - if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0)) - goto err; - buff_length=mi_getint(buff); - endpos=buff+buff_length; - DBUG_DUMP("prev",(byte*) buff,buff_length); - - /* find keys to make a big key-page */ - bmove((byte*) next_keypos - key_reflength,(byte*) leaf_buff+2, - key_reflength); - next_keypos=keypos; - if (!(*keyinfo->get_key)(keyinfo,key_reflength,&next_keypos, - anc_key)) - goto err; - if (!_mi_get_last_key(info,keyinfo,buff,leaf_key,endpos,&length)) - goto err; - - /* merge pages and put parting key from anc_buff between */ - prev_key=(leaf_length == p_length ? (uchar*) 0 : leaf_key); - t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, - (leaf_length == p_length ? - (uchar*) 0 : leaf_buff+p_length), - prev_key, prev_key, - anc_key, &s_temp); - if (t_length >= 0) - bmove((byte*) endpos+t_length,(byte*) leaf_buff+p_length, - (size_t) (leaf_length-p_length)); - else /* We gained space */ - bmove((byte*) endpos,(byte*) leaf_buff+((int) p_length-t_length), - (size_t) (leaf_length-p_length+t_length)); - - (*keyinfo->store_key)(keyinfo,endpos,&s_temp); - buff_length=buff_length+leaf_length-p_length+t_length; - mi_putint(buff,buff_length,nod_flag); - - /* remove key from anc_buff */ - if (!(s_length= remove_key(keyinfo,key_reflength,keypos,anc_key, - anc_buff+anc_length,(my_off_t *) 0))) - goto err; - - anc_length-=s_length; - mi_putint(anc_buff,anc_length,key_reflength); - - if (buff_length <= keyinfo->block_length) - { /* Keys in one page */ - if (_mi_dispose(info,keyinfo,leaf_page,DFLT_INIT_HITS)) - goto err; - } - else - { /* Page is full */ - if (keypos == anc_buff+2+key_reflength) - anc_pos=0; /* First key */ - else if (!_mi_get_last_key(info,keyinfo,anc_buff,anc_pos=anc_key,keypos, - &length)) - goto err; - endpos=_mi_find_half_pos(nod_flag,keyinfo,buff,leaf_key, - &key_length, &half_pos); - if (!endpos) - goto err; - _mi_kpointer(info,leaf_key+key_length,leaf_page); - /* Save key in anc_buff */ - DBUG_DUMP("anc_buff",(byte*) anc_buff,anc_length); - DBUG_DUMP("key_to_anc",(byte*) leaf_key,key_length); - - temp_pos=anc_buff+anc_length; - t_length=(*keyinfo->pack_key)(keyinfo,key_reflength, - keypos == temp_pos ? (uchar*) 0 - : keypos, - anc_pos, anc_pos, - leaf_key,&s_temp); - if (t_length > 0) - bmove_upp((byte*) temp_pos+t_length,(byte*) temp_pos, - (uint) (temp_pos-keypos)); - else - bmove(keypos,keypos-t_length,(uint) (temp_pos-keypos)+t_length); - (*keyinfo->store_key)(keyinfo,keypos,&s_temp); - mi_putint(anc_buff,(anc_length+=t_length),key_reflength); - - /* Store first key on new page */ - if (nod_flag) - bmove((byte*) leaf_buff+2,(byte*) half_pos-nod_flag,(size_t) nod_flag); - if (!(length=(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key))) - goto err; - DBUG_DUMP("key_to_leaf",(byte*) leaf_key,length); - t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, (uchar*) 0, - (uchar*) 0, (uchar*) 0, leaf_key, &s_temp); - length=(uint) ((buff+buff_length)-half_pos); - DBUG_PRINT("info",("t_length: %d length: %d",t_length,(int) length)); - bmove((byte*) leaf_buff+p_length+t_length,(byte*) half_pos, - (size_t) length); - (*keyinfo->store_key)(keyinfo,leaf_buff+p_length,&s_temp); - mi_putint(leaf_buff,length+t_length+p_length,nod_flag); - if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff)) - goto err; - mi_putint(buff,endpos-buff,nod_flag); - } - if (_mi_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff)) - goto err; - DBUG_RETURN(anc_length <= (uint) keyinfo->block_length/2); - -err: - DBUG_RETURN(-1); -} /* underflow */ - - - /* - remove a key from packed buffert - The current code doesn't handle the case that the next key may be - packed better against the previous key if there is a case difference - returns how many chars was removed or 0 on error - */ - -static uint remove_key(MI_KEYDEF *keyinfo, uint nod_flag, - uchar *keypos, /* Where key starts */ - uchar *lastkey, /* key to be removed */ - uchar *page_end, /* End of page */ - my_off_t *next_block) /* ptr to next block */ -{ - int s_length; - uchar *start; - DBUG_ENTER("remove_key"); - DBUG_PRINT("enter",("keypos: %lx page_end: %lx",keypos,page_end)); - - start=keypos; - if (!(keyinfo->flag & - (HA_PACK_KEY | HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY | - HA_BINARY_PACK_KEY))) - { - s_length=(int) (keyinfo->keylength+nod_flag); - if (next_block && nod_flag) - *next_block= _mi_kpos(nod_flag,keypos+s_length); - } - else - { /* Let keypos point at next key */ - /* Calculate length of key */ - if (!(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,lastkey)) - DBUG_RETURN(0); /* Error */ - - if (next_block && nod_flag) - *next_block= _mi_kpos(nod_flag,keypos); - s_length=(int) (keypos-start); - if (keypos != page_end) - { - if (keyinfo->flag & HA_BINARY_PACK_KEY) - { - uchar *old_key=start; - uint next_length,prev_length,prev_pack_length; - get_key_length(next_length,keypos); - get_key_pack_length(prev_length,prev_pack_length,old_key); - if (next_length > prev_length) - { - /* We have to copy data from the current key to the next key */ - bmove_upp((char*) keypos,(char*) (lastkey+next_length), - (next_length-prev_length)); - keypos-=(next_length-prev_length)+prev_pack_length; - store_key_length(keypos,prev_length); - s_length=(int) (keypos-start); - } - } - else - { - /* Check if a variable length first key part */ - if ((keyinfo->seg->flag & HA_PACK_KEY) && *keypos & 128) - { - /* Next key is packed against the current one */ - uint next_length,prev_length,prev_pack_length,lastkey_length, - rest_length; - if (keyinfo->seg[0].length >= 127) - { - if (!(prev_length=mi_uint2korr(start) & 32767)) - goto end; - next_length=mi_uint2korr(keypos) & 32767; - keypos+=2; - prev_pack_length=2; - } - else - { - if (!(prev_length= *start & 127)) - goto end; /* Same key as previous*/ - next_length= *keypos & 127; - keypos++; - prev_pack_length=1; - } - if (!(*start & 128)) - prev_length=0; /* prev key not packed */ - if (keyinfo->seg[0].flag & HA_NULL_PART) - lastkey++; /* Skip null marker */ - get_key_length(lastkey_length,lastkey); - if (!next_length) /* Same key after */ - { - next_length=lastkey_length; - rest_length=0; - } - else - get_key_length(rest_length,keypos); - - if (next_length >= prev_length) - { /* Key after is based on deleted key */ - uint pack_length,tmp; - bmove_upp((char*) keypos,(char*) (lastkey+next_length), - tmp=(next_length-prev_length)); - rest_length+=tmp; - pack_length= prev_length ? get_pack_length(rest_length): 0; - keypos-=tmp+pack_length+prev_pack_length; - s_length=(int) (keypos-start); - if (prev_length) /* Pack against prev key */ - { - *keypos++= start[0]; - if (prev_pack_length == 2) - *keypos++= start[1]; - store_key_length(keypos,rest_length); - } - else - { - /* Next key is not packed anymore */ - if (keyinfo->seg[0].flag & HA_NULL_PART) - { - rest_length++; /* Mark not null */ - } - if (prev_pack_length == 2) - { - mi_int2store(keypos,rest_length); - } - else - *keypos= rest_length; - } - } - } - } - } - } - end: - bmove((byte*) start,(byte*) start+s_length, - (uint) (page_end-start-s_length)); - DBUG_RETURN((uint) s_length); -} /* remove_key */ diff --git a/myisam/mi_delete_all.c b/myisam/mi_delete_all.c deleted file mode 100644 index 3033249886f..00000000000 --- a/myisam/mi_delete_all.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Remove all rows from a MyISAM table */ -/* This clears the status information and truncates files */ - -#include "myisamdef.h" - -int mi_delete_all_rows(MI_INFO *info) -{ - uint i; - MYISAM_SHARE *share=info->s; - MI_STATE_INFO *state=&share->state; - DBUG_ENTER("mi_delete_all_rows"); - - if (share->options & HA_OPTION_READ_ONLY_DATA) - { - DBUG_RETURN(my_errno=EACCES); - } - if (_mi_readinfo(info,F_WRLCK,1)) - DBUG_RETURN(my_errno); - if (_mi_mark_file_changed(info)) - goto err; - - info->state->records=info->state->del=state->split=0; - state->dellink = HA_OFFSET_ERROR; - state->sortkey= (ushort) ~0; - info->state->key_file_length=share->base.keystart; - info->state->data_file_length=0; - info->state->empty=info->state->key_empty=0; - state->checksum=0; - - for (i=share->base.max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; ) - state->key_del[i]= HA_OFFSET_ERROR; - for (i=0 ; i < share->base.keys ; i++) - state->key_root[i]= HA_OFFSET_ERROR; - - myisam_log_command(MI_LOG_DELETE_ALL,info,(byte*) 0,0,0); - /* - If we are using delayed keys or if the user has done changes to the tables - since it was locked then there may be key blocks in the key cache - */ - flush_key_blocks(share->key_cache, share->kfile, FLUSH_IGNORE_CHANGED); - if (my_chsize(info->dfile, 0, 0, MYF(MY_WME)) || - my_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME)) ) - goto err; - VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); - allow_break(); /* Allow SIGHUP & SIGINT */ - DBUG_RETURN(0); - -err: - { - int save_errno=my_errno; - VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); - info->update|=HA_STATE_WRITTEN; /* Buffer changed */ - allow_break(); /* Allow SIGHUP & SIGINT */ - DBUG_RETURN(my_errno=save_errno); - } -} /* mi_delete */ diff --git a/myisam/mi_delete_table.c b/myisam/mi_delete_table.c deleted file mode 100644 index 6843881568d..00000000000 --- a/myisam/mi_delete_table.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - deletes a table -*/ - -#include "fulltext.h" - -int mi_delete_table(const char *name) -{ - char from[FN_REFLEN]; -#ifdef USE_RAID - uint raid_type=0,raid_chunks=0; -#endif - DBUG_ENTER("mi_delete_table"); - -#ifdef EXTRA_DEBUG - check_table_is_closed(name,"delete"); -#endif -#ifdef USE_RAID - { - MI_INFO *info; - /* we use 'open_for_repair' to be able to delete a crashed table */ - if (!(info=mi_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR))) - DBUG_RETURN(my_errno); - raid_type = info->s->base.raid_type; - raid_chunks = info->s->base.raid_chunks; - mi_close(info); - } -#ifdef EXTRA_DEBUG - check_table_is_closed(name,"delete"); -#endif -#endif /* USE_RAID */ - - fn_format(from,name,"",MI_NAME_IEXT,4); - if (my_delete_with_symlink(from, MYF(MY_WME))) - DBUG_RETURN(my_errno); - fn_format(from,name,"",MI_NAME_DEXT,4); -#ifdef USE_RAID - if (raid_type) - DBUG_RETURN(my_raid_delete(from, raid_chunks, MYF(MY_WME)) ? my_errno : 0); -#endif - DBUG_RETURN(my_delete_with_symlink(from, MYF(MY_WME)) ? my_errno : 0); -} diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c deleted file mode 100644 index 9d8e161b8fe..00000000000 --- a/myisam/mi_dynrec.c +++ /dev/null @@ -1,1641 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Functions to handle space-packed-records and blobs - - A row may be stored in one or more linked blocks. - The block size is between MI_MIN_BLOCK_LENGTH and MI_MAX_BLOCK_LENGTH. - Each block is aligned on MI_DYN_ALIGN_SIZE. - The reson for the max block size is to not have too many different types - of blocks. For the differnet block types, look at _mi_get_block_info() -*/ - -#include "myisamdef.h" - -/* Enough for comparing if number is zero */ -static char zero_string[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - -static int write_dynamic_record(MI_INFO *info,const byte *record, - ulong reclength); -static int _mi_find_writepos(MI_INFO *info,ulong reclength,my_off_t *filepos, - ulong *length); -static int update_dynamic_record(MI_INFO *info,my_off_t filepos,byte *record, - ulong reclength); -static int delete_dynamic_record(MI_INFO *info,my_off_t filepos, - uint second_read); -static int _mi_cmp_buffer(File file, const byte *buff, my_off_t filepos, - uint length); - -#ifdef THREAD -/* Play it safe; We have a small stack when using threads */ -#undef my_alloca -#undef my_afree -#define my_alloca(A) my_malloc((A),MYF(0)) -#define my_afree(A) my_free((A),MYF(0)) -#endif - - /* Interface function from MI_INFO */ - -int _mi_write_dynamic_record(MI_INFO *info, const byte *record) -{ - ulong reclength=_mi_rec_pack(info,info->rec_buff,record); - return (write_dynamic_record(info,info->rec_buff,reclength)); -} - -int _mi_update_dynamic_record(MI_INFO *info, my_off_t pos, const byte *record) -{ - uint length=_mi_rec_pack(info,info->rec_buff,record); - return (update_dynamic_record(info,pos,info->rec_buff,length)); -} - -int _mi_write_blob_record(MI_INFO *info, const byte *record) -{ - byte *rec_buff; - int error; - ulong reclength,reclength2,extra; - - extra= (ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+ - MI_DYN_DELETE_BLOCK_HEADER+1); - reclength= (info->s->base.pack_reclength + - _my_calc_total_blob_length(info,record)+ extra); -#ifdef NOT_USED /* We now support big rows */ - if (reclength > MI_DYN_MAX_ROW_LENGTH) - { - my_errno=HA_ERR_TO_BIG_ROW; - return -1; - } -#endif - if (!(rec_buff=(byte*) my_alloca(reclength))) - { - my_errno=ENOMEM; - return(-1); - } - reclength2= _mi_rec_pack(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER), - record); - DBUG_PRINT("info",("reclength: %lu reclength2: %lu", - reclength, reclength2)); - DBUG_ASSERT(reclength2 <= reclength); - error=write_dynamic_record(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER), - reclength2); - my_afree(rec_buff); - return(error); -} - - -int _mi_update_blob_record(MI_INFO *info, my_off_t pos, const byte *record) -{ - byte *rec_buff; - int error; - ulong reclength,extra; - - extra= (ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+ - MI_DYN_DELETE_BLOCK_HEADER); - reclength= (info->s->base.pack_reclength+ - _my_calc_total_blob_length(info,record)+ extra); -#ifdef NOT_USED /* We now support big rows */ - if (reclength > MI_DYN_MAX_ROW_LENGTH) - { - my_errno=HA_ERR_TO_BIG_ROW; - return -1; - } -#endif - if (!(rec_buff=(byte*) my_alloca(reclength))) - { - my_errno=ENOMEM; - return(-1); - } - reclength=_mi_rec_pack(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER), - record); - error=update_dynamic_record(info,pos, - rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER), - reclength); - my_afree(rec_buff); - return(error); -} - - -int _mi_delete_dynamic_record(MI_INFO *info) -{ - return delete_dynamic_record(info,info->lastpos,0); -} - - - /* Write record to data-file */ - -static int write_dynamic_record(MI_INFO *info, const byte *record, - ulong reclength) -{ - int flag; - ulong length; - my_off_t filepos; - DBUG_ENTER("write_dynamic_record"); - - flag=0; - do - { - if (_mi_find_writepos(info,reclength,&filepos,&length)) - goto err; - if (_mi_write_part_record(info,filepos,length,info->s->state.dellink, - (byte**) &record,&reclength,&flag)) - goto err; - } while (reclength); - - DBUG_RETURN(0); -err: - DBUG_RETURN(1); -} - - - /* Get a block for data ; The given data-area must be used !! */ - -static int _mi_find_writepos(MI_INFO *info, - ulong reclength, /* record length */ - my_off_t *filepos, /* Return file pos */ - ulong *length) /* length of block at filepos */ -{ - MI_BLOCK_INFO block_info; - ulong tmp; - DBUG_ENTER("_mi_find_writepos"); - - if (info->s->state.dellink != HA_OFFSET_ERROR) - { - /* Deleted blocks exists; Get last used block */ - *filepos=info->s->state.dellink; - block_info.second_read=0; - info->rec_cache.seek_not_done=1; - if (!(_mi_get_block_info(&block_info,info->dfile,info->s->state.dellink) & - BLOCK_DELETED)) - { - DBUG_PRINT("error",("Delete link crashed")); - my_errno=HA_ERR_WRONG_IN_RECORD; - DBUG_RETURN(-1); - } - info->s->state.dellink=block_info.next_filepos; - info->state->del--; - info->state->empty-= block_info.block_len; - *length= block_info.block_len; - } - else - { - /* No deleted blocks; Allocate a new block */ - *filepos=info->state->data_file_length; - if ((tmp=reclength+3 + test(reclength >= (65520-3))) < - info->s->base.min_block_length) - tmp= info->s->base.min_block_length; - else - tmp= ((tmp+MI_DYN_ALIGN_SIZE-1) & - (~ (ulong) (MI_DYN_ALIGN_SIZE-1))); - if (info->state->data_file_length > - (info->s->base.max_data_file_length - tmp)) - { - my_errno=HA_ERR_RECORD_FILE_FULL; - DBUG_RETURN(-1); - } - if (tmp > MI_MAX_BLOCK_LENGTH) - tmp=MI_MAX_BLOCK_LENGTH; - *length= tmp; - info->state->data_file_length+= tmp; - info->s->state.split++; - info->update|=HA_STATE_WRITE_AT_END; - } - DBUG_RETURN(0); -} /* _mi_find_writepos */ - - - -/* - Unlink a deleted block from the deleted list. - This block will be combined with the preceding or next block to form - a big block. -*/ - -static bool unlink_deleted_block(MI_INFO *info, MI_BLOCK_INFO *block_info) -{ - DBUG_ENTER("unlink_deleted_block"); - if (block_info->filepos == info->s->state.dellink) - { - /* First deleted block; We can just use this ! */ - info->s->state.dellink=block_info->next_filepos; - } - else - { - MI_BLOCK_INFO tmp; - tmp.second_read=0; - /* Unlink block from the previous block */ - if (!(_mi_get_block_info(&tmp,info->dfile,block_info->prev_filepos) - & BLOCK_DELETED)) - DBUG_RETURN(1); /* Something is wrong */ - mi_sizestore(tmp.header+4,block_info->next_filepos); - if (my_pwrite(info->dfile,(char*) tmp.header+4,8, - block_info->prev_filepos+4, MYF(MY_NABP))) - DBUG_RETURN(1); - /* Unlink block from next block */ - if (block_info->next_filepos != HA_OFFSET_ERROR) - { - if (!(_mi_get_block_info(&tmp,info->dfile,block_info->next_filepos) - & BLOCK_DELETED)) - DBUG_RETURN(1); /* Something is wrong */ - mi_sizestore(tmp.header+12,block_info->prev_filepos); - if (my_pwrite(info->dfile,(char*) tmp.header+12,8, - block_info->next_filepos+12, - MYF(MY_NABP))) - DBUG_RETURN(1); - } - } - /* We now have one less deleted block */ - info->state->del--; - info->state->empty-= block_info->block_len; - info->s->state.split--; - - /* - If this was a block that we where accessing through table scan - (mi_rrnd() or mi_scan(), then ensure that we skip over this block - when doing next mi_rrnd() or mi_scan(). - */ - if (info->nextpos == block_info->filepos) - info->nextpos+=block_info->block_len; - DBUG_RETURN(0); -} - - -/* - Add a backward link to delete block - - SYNOPSIS - update_backward_delete_link() - info MyISAM handler - delete_block Position to delete block to update. - If this is 'HA_OFFSET_ERROR', nothing will be done - filepos Position to block that 'delete_block' should point to - - RETURN - 0 ok - 1 error. In this case my_error is set. -*/ - -static int update_backward_delete_link(MI_INFO *info, my_off_t delete_block, - my_off_t filepos) -{ - MI_BLOCK_INFO block_info; - DBUG_ENTER("update_backward_delete_link"); - - if (delete_block != HA_OFFSET_ERROR) - { - block_info.second_read=0; - if (_mi_get_block_info(&block_info,info->dfile,delete_block) - & BLOCK_DELETED) - { - char buff[8]; - mi_sizestore(buff,filepos); - if (my_pwrite(info->dfile,buff, 8, delete_block+12, MYF(MY_NABP))) - DBUG_RETURN(1); /* Error on write */ - } - else - { - my_errno=HA_ERR_WRONG_IN_RECORD; - DBUG_RETURN(1); /* Wrong delete link */ - } - } - DBUG_RETURN(0); -} - - /* Delete datarecord from database */ - /* info->rec_cache.seek_not_done is updated in cmp_record */ - -static int delete_dynamic_record(MI_INFO *info, my_off_t filepos, - uint second_read) -{ - uint length,b_type; - MI_BLOCK_INFO block_info,del_block; - int error; - my_bool remove_next_block; - DBUG_ENTER("delete_dynamic_record"); - - /* First add a link from the last block to the new one */ - error= update_backward_delete_link(info, info->s->state.dellink, filepos); - - block_info.second_read=second_read; - do - { - /* Remove block at 'filepos' */ - if ((b_type=_mi_get_block_info(&block_info,info->dfile,filepos)) - & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR | - BLOCK_FATAL_ERROR) || - (length=(uint) (block_info.filepos-filepos) +block_info.block_len) < - MI_MIN_BLOCK_LENGTH) - { - my_errno=HA_ERR_WRONG_IN_RECORD; - DBUG_RETURN(1); - } - /* Check if next block is a delete block */ - del_block.second_read=0; - remove_next_block=0; - if (_mi_get_block_info(&del_block,info->dfile,filepos+length) & - BLOCK_DELETED && del_block.block_len+length < MI_DYN_MAX_BLOCK_LENGTH) - { - /* We can't remove this yet as this block may be the head block */ - remove_next_block=1; - length+=del_block.block_len; - } - - block_info.header[0]=0; - mi_int3store(block_info.header+1,length); - mi_sizestore(block_info.header+4,info->s->state.dellink); - if (b_type & BLOCK_LAST) - bfill(block_info.header+12,8,255); - else - mi_sizestore(block_info.header+12,block_info.next_filepos); - if (my_pwrite(info->dfile,(byte*) block_info.header,20,filepos, - MYF(MY_NABP))) - DBUG_RETURN(1); - info->s->state.dellink = filepos; - info->state->del++; - info->state->empty+=length; - filepos=block_info.next_filepos; - - /* Now it's safe to unlink the deleted block directly after this one */ - if (remove_next_block && unlink_deleted_block(info,&del_block)) - error=1; - } while (!(b_type & BLOCK_LAST)); - - DBUG_RETURN(error); -} - - - /* Write a block to datafile */ - -int _mi_write_part_record(MI_INFO *info, - my_off_t filepos, /* points at empty block */ - ulong length, /* length of block */ - my_off_t next_filepos,/* Next empty block */ - byte **record, /* pointer to record ptr */ - ulong *reclength, /* length of *record */ - int *flag) /* *flag == 0 if header */ -{ - ulong head_length,res_length,extra_length,long_block,del_length; - byte *pos,*record_end; - my_off_t next_delete_block; - uchar temp[MI_SPLIT_LENGTH+MI_DYN_DELETE_BLOCK_HEADER]; - DBUG_ENTER("_mi_write_part_record"); - - next_delete_block=HA_OFFSET_ERROR; - - res_length=extra_length=0; - if (length > *reclength + MI_SPLIT_LENGTH) - { /* Splitt big block */ - res_length=MY_ALIGN(length- *reclength - MI_EXTEND_BLOCK_LENGTH, - MI_DYN_ALIGN_SIZE); - length-= res_length; /* Use this for first part */ - } - long_block= (length < 65520L && *reclength < 65520L) ? 0 : 1; - if (length == *reclength+ 3 + long_block) - { - /* Block is exactly of the right length */ - temp[0]=(uchar) (1+ *flag)+(uchar) long_block; /* Flag is 0 or 6 */ - if (long_block) - { - mi_int3store(temp+1,*reclength); - head_length=4; - } - else - { - mi_int2store(temp+1,*reclength); - head_length=3; - } - } - else if (length-long_block < *reclength+4) - { /* To short block */ - if (next_filepos == HA_OFFSET_ERROR) - next_filepos=info->s->state.dellink != HA_OFFSET_ERROR ? - info->s->state.dellink : info->state->data_file_length; - if (*flag == 0) /* First block */ - { - if (*reclength > MI_MAX_BLOCK_LENGTH) - { - head_length= 16; - temp[0]=13; - mi_int4store(temp+1,*reclength); - mi_int3store(temp+5,length-head_length); - mi_sizestore((byte*) temp+8,next_filepos); - } - else - { - head_length=5+8+long_block*2; - temp[0]=5+(uchar) long_block; - if (long_block) - { - mi_int3store(temp+1,*reclength); - mi_int3store(temp+4,length-head_length); - mi_sizestore((byte*) temp+7,next_filepos); - } - else - { - mi_int2store(temp+1,*reclength); - mi_int2store(temp+3,length-head_length); - mi_sizestore((byte*) temp+5,next_filepos); - } - } - } - else - { - head_length=3+8+long_block; - temp[0]=11+(uchar) long_block; - if (long_block) - { - mi_int3store(temp+1,length-head_length); - mi_sizestore((byte*) temp+4,next_filepos); - } - else - { - mi_int2store(temp+1,length-head_length); - mi_sizestore((byte*) temp+3,next_filepos); - } - } - } - else - { /* Block with empty info last */ - head_length=4+long_block; - extra_length= length- *reclength-head_length; - temp[0]= (uchar) (3+ *flag)+(uchar) long_block; /* 3,4 or 9,10 */ - if (long_block) - { - mi_int3store(temp+1,*reclength); - temp[4]= (uchar) (extra_length); - } - else - { - mi_int2store(temp+1,*reclength); - temp[3]= (uchar) (extra_length); - } - length= *reclength+head_length; /* Write only what is needed */ - } - DBUG_DUMP("header",(byte*) temp,head_length); - - /* Make a long block for one write */ - record_end= *record+length-head_length; - del_length=(res_length ? MI_DYN_DELETE_BLOCK_HEADER : 0); - bmove((byte*) (*record-head_length),(byte*) temp,head_length); - memcpy(temp,record_end,(size_t) (extra_length+del_length)); - bzero((byte*) record_end,extra_length); - - if (res_length) - { - /* Check first if we can join this block with the next one */ - MI_BLOCK_INFO del_block; - my_off_t next_block=filepos+length+extra_length+res_length; - - del_block.second_read=0; - if (next_block < info->state->data_file_length && - info->s->state.dellink != HA_OFFSET_ERROR) - { - if ((_mi_get_block_info(&del_block,info->dfile,next_block) - & BLOCK_DELETED) && - res_length + del_block.block_len < MI_DYN_MAX_BLOCK_LENGTH) - { - if (unlink_deleted_block(info,&del_block)) - goto err; - res_length+=del_block.block_len; - } - } - - /* Create a delete link of the last part of the block */ - pos=record_end+extra_length; - pos[0]= '\0'; - mi_int3store(pos+1,res_length); - mi_sizestore(pos+4,info->s->state.dellink); - bfill(pos+12,8,255); /* End link */ - next_delete_block=info->s->state.dellink; - info->s->state.dellink= filepos+length+extra_length; - info->state->del++; - info->state->empty+=res_length; - info->s->state.split++; - } - if (info->opt_flag & WRITE_CACHE_USED && - info->update & HA_STATE_WRITE_AT_END) - { - if (info->update & HA_STATE_EXTEND_BLOCK) - { - info->update&= ~HA_STATE_EXTEND_BLOCK; - if (my_block_write(&info->rec_cache,(byte*) *record-head_length, - length+extra_length+del_length,filepos)) - goto err; - } - else if (my_b_write(&info->rec_cache,(byte*) *record-head_length, - length+extra_length+del_length)) - goto err; - } - else - { - info->rec_cache.seek_not_done=1; - if (my_pwrite(info->dfile,(byte*) *record-head_length,length+extra_length+ - del_length,filepos,info->s->write_flag)) - goto err; - } - memcpy(record_end,temp,(size_t) (extra_length+del_length)); - *record=record_end; - *reclength-=(length-head_length); - *flag=6; - - if (del_length) - { - /* link the next delete block to this */ - if (update_backward_delete_link(info, next_delete_block, - info->s->state.dellink)) - goto err; - } - - DBUG_RETURN(0); -err: - DBUG_PRINT("exit",("errno: %d",my_errno)); - DBUG_RETURN(1); -} /*_mi_write_part_record */ - - - /* update record from datafile */ - -static int update_dynamic_record(MI_INFO *info, my_off_t filepos, byte *record, - ulong reclength) -{ - int flag; - uint error; - ulong length; - MI_BLOCK_INFO block_info; - DBUG_ENTER("update_dynamic_record"); - - flag=block_info.second_read=0; - while (reclength > 0) - { - if (filepos != info->s->state.dellink) - { - block_info.next_filepos= HA_OFFSET_ERROR; - if ((error=_mi_get_block_info(&block_info,info->dfile,filepos)) - & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR | - BLOCK_FATAL_ERROR)) - { - DBUG_PRINT("error",("Got wrong block info")); - if (!(error & BLOCK_FATAL_ERROR)) - my_errno=HA_ERR_WRONG_IN_RECORD; - goto err; - } - length=(ulong) (block_info.filepos-filepos) + block_info.block_len; - if (length < reclength) - { - uint tmp=MY_ALIGN(reclength - length + 3 + - test(reclength >= 65520L),MI_DYN_ALIGN_SIZE); - /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */ - tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length; - /* Check if we can extend this block */ - if (block_info.filepos + block_info.block_len == - info->state->data_file_length && - info->state->data_file_length < - info->s->base.max_data_file_length-tmp) - { - /* extend file */ - DBUG_PRINT("info",("Extending file with %d bytes",tmp)); - if (info->nextpos == info->state->data_file_length) - info->nextpos+= tmp; - info->state->data_file_length+= tmp; - info->update|= HA_STATE_WRITE_AT_END | HA_STATE_EXTEND_BLOCK; - length+=tmp; - } - else if (length < MI_MAX_BLOCK_LENGTH - MI_MIN_BLOCK_LENGTH) - { - /* - Check if next block is a deleted block - Above we have MI_MIN_BLOCK_LENGTH to avoid the problem where - the next block is so small it can't be splited which could - casue problems - */ - - MI_BLOCK_INFO del_block; - del_block.second_read=0; - if (_mi_get_block_info(&del_block,info->dfile, - block_info.filepos + block_info.block_len) & - BLOCK_DELETED) - { - /* Use; Unlink it and extend the current block */ - DBUG_PRINT("info",("Extending current block")); - if (unlink_deleted_block(info,&del_block)) - goto err; - if ((length+=del_block.block_len) > MI_MAX_BLOCK_LENGTH) - { - /* - New block was too big, link overflow part back to - delete list - */ - my_off_t next_pos; - ulong rest_length= length-MI_MAX_BLOCK_LENGTH; - set_if_bigger(rest_length, MI_MIN_BLOCK_LENGTH); - next_pos= del_block.filepos+ del_block.block_len - rest_length; - - if (update_backward_delete_link(info, info->s->state.dellink, - next_pos)) - DBUG_RETURN(1); - - /* create delete link for data that didn't fit into the page */ - del_block.header[0]=0; - mi_int3store(del_block.header+1, rest_length); - mi_sizestore(del_block.header+4,info->s->state.dellink); - bfill(del_block.header+12,8,255); - if (my_pwrite(info->dfile,(byte*) del_block.header,20, next_pos, - MYF(MY_NABP))) - DBUG_RETURN(1); - info->s->state.dellink= next_pos; - info->s->state.split++; - info->state->del++; - info->state->empty+= rest_length; - length-= rest_length; - } - } - } - } - } - else - { - if (_mi_find_writepos(info,reclength,&filepos,&length)) - goto err; - } - if (_mi_write_part_record(info,filepos,length,block_info.next_filepos, - &record,&reclength,&flag)) - goto err; - if ((filepos=block_info.next_filepos) == HA_OFFSET_ERROR) - { - /* Start writing data on deleted blocks */ - filepos=info->s->state.dellink; - } - } - - if (block_info.next_filepos != HA_OFFSET_ERROR) - if (delete_dynamic_record(info,block_info.next_filepos,1)) - goto err; - DBUG_RETURN(0); -err: - DBUG_RETURN(1); -} - - - /* Pack a record. Return new reclength */ - -uint _mi_rec_pack(MI_INFO *info, register byte *to, register const byte *from) -{ - uint length,new_length,flag,bit,i; - char *pos,*end,*startpos,*packpos; - enum en_fieldtype type; - reg3 MI_COLUMNDEF *rec; - MI_BLOB *blob; - DBUG_ENTER("_mi_rec_pack"); - - flag=0 ; bit=1; - startpos=packpos=to; to+= info->s->base.pack_bits; blob=info->blobs; - rec=info->s->rec; - - for (i=info->s->base.fields ; i-- > 0; from+= length,rec++) - { - length=(uint) rec->length; - if ((type = (enum en_fieldtype) rec->type) != FIELD_NORMAL) - { - if (type == FIELD_BLOB) - { - if (!blob->length) - flag|=bit; - else - { - char *temp_pos; - size_t tmp_length=length-mi_portable_sizeof_char_ptr; - memcpy((byte*) to,from,tmp_length); - memcpy_fixed(&temp_pos,from+tmp_length,sizeof(char*)); - memcpy(to+tmp_length,temp_pos,(size_t) blob->length); - to+=tmp_length+blob->length; - } - blob++; - } - else if (type == FIELD_SKIP_ZERO) - { - if (memcmp((byte*) from,zero_string,length) == 0) - flag|=bit; - else - { - memcpy((byte*) to,from,(size_t) length); to+=length; - } - } - else if (type == FIELD_SKIP_ENDSPACE || - type == FIELD_SKIP_PRESPACE) - { - pos= (byte*) from; end= (byte*) from + length; - if (type == FIELD_SKIP_ENDSPACE) - { /* Pack trailing spaces */ - while (end > from && *(end-1) == ' ') - end--; - } - else - { /* Pack pref-spaces */ - while (pos < end && *pos == ' ') - pos++; - } - new_length=(uint) (end-pos); - if (new_length +1 + test(rec->length > 255 && new_length > 127) - < length) - { - if (rec->length > 255 && new_length > 127) - { - to[0]=(char) ((new_length & 127)+128); - to[1]=(char) (new_length >> 7); - to+=2; - } - else - *to++= (char) new_length; - memcpy((byte*) to,pos,(size_t) new_length); to+=new_length; - flag|=bit; - } - else - { - memcpy(to,from,(size_t) length); to+=length; - } - } - else if (type == FIELD_VARCHAR) - { - uint pack_length= HA_VARCHAR_PACKLENGTH(rec->length -1); - uint tmp_length; - if (pack_length == 1) - { - tmp_length= (uint) *(uchar*) from; - *to++= *from; - } - else - { - tmp_length= uint2korr(from); - store_key_length_inc(to,tmp_length); - } - memcpy(to, from+pack_length,tmp_length); - to+= tmp_length; - continue; - } - else - { - memcpy(to,from,(size_t) length); to+=length; - continue; /* Normal field */ - } - if ((bit= bit << 1) >= 256) - { - *packpos++ = (char) (uchar) flag; - bit=1; flag=0; - } - } - else - { - memcpy(to,from,(size_t) length); to+=length; - } - } - if (bit != 1) - *packpos= (char) (uchar) flag; - if (info->s->calc_checksum) - *to++=(char) info->checksum; - DBUG_PRINT("exit",("packed length: %d",(int) (to-startpos))); - DBUG_RETURN((uint) (to-startpos)); -} /* _mi_rec_pack */ - - - -/* - Check if a record was correctly packed. Used only by myisamchk - Returns 0 if record is ok. -*/ - -my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *rec_buff, - ulong packed_length) -{ - uint length,new_length,flag,bit,i; - char *pos,*end,*packpos,*to; - enum en_fieldtype type; - reg3 MI_COLUMNDEF *rec; - DBUG_ENTER("_mi_rec_check"); - - packpos=rec_buff; to= rec_buff+info->s->base.pack_bits; - rec=info->s->rec; - flag= *packpos; bit=1; - - for (i=info->s->base.fields ; i-- > 0; record+= length, rec++) - { - length=(uint) rec->length; - if ((type = (enum en_fieldtype) rec->type) != FIELD_NORMAL) - { - if (type == FIELD_BLOB) - { - uint blob_length= - _mi_calc_blob_length(length-mi_portable_sizeof_char_ptr,record); - if (!blob_length && !(flag & bit)) - goto err; - if (blob_length) - to+=length - mi_portable_sizeof_char_ptr+ blob_length; - } - else if (type == FIELD_SKIP_ZERO) - { - if (memcmp((byte*) record,zero_string,length) == 0) - { - if (!(flag & bit)) - goto err; - } - else - to+=length; - } - else if (type == FIELD_SKIP_ENDSPACE || - type == FIELD_SKIP_PRESPACE) - { - pos= (byte*) record; end= (byte*) record + length; - if (type == FIELD_SKIP_ENDSPACE) - { /* Pack trailing spaces */ - while (end > record && *(end-1) == ' ') - end--; - } - else - { /* Pack pre-spaces */ - while (pos < end && *pos == ' ') - pos++; - } - new_length=(uint) (end-pos); - if (new_length +1 + test(rec->length > 255 && new_length > 127) - < length) - { - if (!(flag & bit)) - goto err; - if (rec->length > 255 && new_length > 127) - { - if (to[0] != (char) ((new_length & 127)+128) || - to[1] != (char) (new_length >> 7)) - goto err; - to+=2; - } - else if (*to++ != (char) new_length) - goto err; - to+=new_length; - } - else - to+=length; - } - else if (type == FIELD_VARCHAR) - { - uint pack_length= HA_VARCHAR_PACKLENGTH(rec->length -1); - uint tmp_length; - if (pack_length == 1) - { - tmp_length= (uint) *(uchar*) record; - to+= 1+ tmp_length; - continue; - } - else - { - tmp_length= uint2korr(record); - to+= get_pack_length(tmp_length)+tmp_length; - } - continue; - } - else - { - to+=length; - continue; /* Normal field */ - } - if ((bit= bit << 1) >= 256) - { - flag= *++packpos; - bit=1; - } - } - else - to+= length; - } - if (packed_length != (uint) (to - rec_buff) + test(info->s->calc_checksum) || - (bit != 1 && (flag & ~(bit - 1)))) - goto err; - if (info->s->calc_checksum) - { - if ((uchar) info->checksum != (uchar) *to) - { - DBUG_PRINT("error",("wrong checksum for row")); - goto err; - } - } - DBUG_RETURN(0); - -err: - DBUG_RETURN(1); -} - - - - /* Unpacks a record */ - /* Returns -1 and my_errno =HA_ERR_RECORD_DELETED if reclength isn't */ - /* right. Returns reclength (>0) if ok */ - -ulong _mi_rec_unpack(register MI_INFO *info, register byte *to, byte *from, - ulong found_length) -{ - uint flag,bit,length,rec_length,min_pack_length; - enum en_fieldtype type; - byte *from_end,*to_end,*packpos; - reg3 MI_COLUMNDEF *rec,*end_field; - DBUG_ENTER("_mi_rec_unpack"); - - to_end=to + info->s->base.reclength; - from_end=from+found_length; - flag= (uchar) *from; bit=1; packpos=from; - if (found_length < info->s->base.min_pack_length) - goto err; - from+= info->s->base.pack_bits; - min_pack_length=info->s->base.min_pack_length - info->s->base.pack_bits; - - for (rec=info->s->rec , end_field=rec+info->s->base.fields ; - rec < end_field ; to+= rec_length, rec++) - { - rec_length=rec->length; - if ((type = (enum en_fieldtype) rec->type) != FIELD_NORMAL && - (type != FIELD_CHECK)) - { - if (type == FIELD_VARCHAR) - { - uint pack_length= HA_VARCHAR_PACKLENGTH(rec_length-1); - if (pack_length == 1) - { - length= (uint) *(uchar*) from; - if (length > rec_length-1) - goto err; - *to= *from++; - } - else - { - get_key_length(length, from); - if (length > rec_length-2) - goto err; - int2store(to,length); - } - if (from+length > from_end) - goto err; - memcpy(to+pack_length, from, length); - from+= length; - min_pack_length--; - continue; - } - if (flag & bit) - { - if (type == FIELD_BLOB || type == FIELD_SKIP_ZERO) - bzero((byte*) to,rec_length); - else if (type == FIELD_SKIP_ENDSPACE || - type == FIELD_SKIP_PRESPACE) - { - if (rec->length > 255 && *from & 128) - { - if (from + 1 >= from_end) - goto err; - length= (*from & 127)+ ((uint) (uchar) *(from+1) << 7); from+=2; - } - else - { - if (from == from_end) - goto err; - length= (uchar) *from++; - } - min_pack_length--; - if (length >= rec_length || - min_pack_length + length > (uint) (from_end - from)) - goto err; - if (type == FIELD_SKIP_ENDSPACE) - { - memcpy(to,(byte*) from,(size_t) length); - bfill((byte*) to+length,rec_length-length,' '); - } - else - { - bfill((byte*) to,rec_length-length,' '); - memcpy(to+rec_length-length,(byte*) from,(size_t) length); - } - from+=length; - } - } - else if (type == FIELD_BLOB) - { - uint size_length=rec_length- mi_portable_sizeof_char_ptr; - ulong blob_length=_mi_calc_blob_length(size_length,from); - if ((ulong) (from_end-from) - size_length < blob_length || - min_pack_length > (uint) (from_end -(from+size_length+blob_length))) - goto err; - memcpy((byte*) to,(byte*) from,(size_t) size_length); - from+=size_length; - memcpy_fixed((byte*) to+size_length,(byte*) &from,sizeof(char*)); - from+=blob_length; - } - else - { - if (type == FIELD_SKIP_ENDSPACE || type == FIELD_SKIP_PRESPACE) - min_pack_length--; - if (min_pack_length + rec_length > (uint) (from_end - from)) - goto err; - memcpy(to,(byte*) from,(size_t) rec_length); from+=rec_length; - } - if ((bit= bit << 1) >= 256) - { - flag= (uchar) *++packpos; bit=1; - } - } - else - { - if (min_pack_length > (uint) (from_end - from)) - goto err; - min_pack_length-=rec_length; - memcpy(to, (byte*) from, (size_t) rec_length); - from+=rec_length; - } - } - if (info->s->calc_checksum) - from++; - if (to == to_end && from == from_end && (bit == 1 || !(flag & ~(bit-1)))) - DBUG_RETURN(found_length); - -err: - my_errno= HA_ERR_WRONG_IN_RECORD; - DBUG_PRINT("error",("to_end: %lx -> %lx from_end: %lx -> %lx", - to,to_end,from,from_end)); - DBUG_DUMP("from",(byte*) info->rec_buff,info->s->base.min_pack_length); - DBUG_RETURN(MY_FILE_ERROR); -} /* _mi_rec_unpack */ - - - /* Calc length of blob. Update info in blobs->length */ - -ulong _my_calc_total_blob_length(MI_INFO *info, const byte *record) -{ - ulong length; - MI_BLOB *blob,*end; - - for (length=0, blob= info->blobs, end=blob+info->s->base.blobs ; - blob != end; - blob++) - { - blob->length=_mi_calc_blob_length(blob->pack_length,record + blob->offset); - length+=blob->length; - } - return length; -} - - -ulong _mi_calc_blob_length(uint length, const byte *pos) -{ - switch (length) { - case 1: - return (uint) (uchar) *pos; - case 2: - return (uint) uint2korr(pos); - case 3: - return uint3korr(pos); - case 4: - return uint4korr(pos); - default: - break; - } - return 0; /* Impossible */ -} - - -void _my_store_blob_length(byte *pos,uint pack_length,uint length) -{ - switch (pack_length) { - case 1: - *pos= (uchar) length; - break; - case 2: - int2store(pos,length); - break; - case 3: - int3store(pos,length); - break; - case 4: - int4store(pos,length); - default: - break; - } - return; -} - - - /* Read record from datafile */ - /* Returns 0 if ok, -1 if error */ - -int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf) -{ - int flag; - uint b_type,left_length; - byte *to; - MI_BLOCK_INFO block_info; - File file; - DBUG_ENTER("mi_read_dynamic_record"); - - if (filepos != HA_OFFSET_ERROR) - { - LINT_INIT(to); - LINT_INIT(left_length); - file=info->dfile; - block_info.next_filepos=filepos; /* for easyer loop */ - flag=block_info.second_read=0; - do - { - if (info->opt_flag & WRITE_CACHE_USED && - info->rec_cache.pos_in_file <= block_info.next_filepos && - flush_io_cache(&info->rec_cache)) - goto err; - info->rec_cache.seek_not_done=1; - if ((b_type=_mi_get_block_info(&block_info,file, - block_info.next_filepos)) - & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR | - BLOCK_FATAL_ERROR)) - { - if (b_type & (BLOCK_SYNC_ERROR | BLOCK_DELETED)) - my_errno=HA_ERR_RECORD_DELETED; - goto err; - } - if (flag == 0) /* First block */ - { - flag=1; - if (block_info.rec_len > (uint) info->s->base.max_pack_length) - goto panic; - if (info->s->base.blobs) - { - if (!(to=mi_alloc_rec_buff(info, block_info.rec_len, - &info->rec_buff))) - goto err; - } - else - to= info->rec_buff; - left_length=block_info.rec_len; - } - if (left_length < block_info.data_len || ! block_info.data_len) - goto panic; /* Wrong linked record */ - if (my_pread(file,(byte*) to,block_info.data_len,block_info.filepos, - MYF(MY_NABP))) - goto panic; - left_length-=block_info.data_len; - to+=block_info.data_len; - } while (left_length); - - info->update|= HA_STATE_AKTIV; /* We have a aktive record */ - fast_mi_writeinfo(info); - DBUG_RETURN(_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) != - MY_FILE_ERROR ? 0 : -1); - } - fast_mi_writeinfo(info); - DBUG_RETURN(-1); /* Wrong data to read */ - -panic: - my_errno=HA_ERR_WRONG_IN_RECORD; -err: - VOID(_mi_writeinfo(info,0)); - DBUG_RETURN(-1); -} - - /* compare unique constraint between stored rows */ - -int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def, - const byte *record, my_off_t pos) -{ - byte *rec_buff,*old_record; - int error; - DBUG_ENTER("_mi_cmp_dynamic_unique"); - - if (!(old_record=my_alloca(info->s->base.reclength))) - DBUG_RETURN(1); - - /* Don't let the compare destroy blobs that may be in use */ - rec_buff=info->rec_buff; - if (info->s->base.blobs) - info->rec_buff=0; - error=_mi_read_dynamic_record(info,pos,old_record); - if (!error) - error=mi_unique_comp(def, record, old_record, def->null_are_equal); - if (info->s->base.blobs) - { - my_free(mi_get_rec_buff_ptr(info, info->rec_buff), MYF(MY_ALLOW_ZERO_PTR)); - info->rec_buff=rec_buff; - } - my_afree(old_record); - DBUG_RETURN(error); -} - - - /* Compare of record one disk with packed record in memory */ - -int _mi_cmp_dynamic_record(register MI_INFO *info, register const byte *record) -{ - uint flag,reclength,b_type; - my_off_t filepos; - byte *buffer; - MI_BLOCK_INFO block_info; - DBUG_ENTER("_mi_cmp_dynamic_record"); - - /* We are going to do changes; dont let anybody disturb */ - dont_break(); /* Dont allow SIGHUP or SIGINT */ - - if (info->opt_flag & WRITE_CACHE_USED) - { - info->update&= ~(HA_STATE_WRITE_AT_END | HA_STATE_EXTEND_BLOCK); - if (flush_io_cache(&info->rec_cache)) - DBUG_RETURN(-1); - } - info->rec_cache.seek_not_done=1; - - /* If nobody have touched the database we don't have to test rec */ - - buffer=info->rec_buff; - if ((info->opt_flag & READ_CHECK_USED)) - { /* If check isn't disabled */ - if (info->s->base.blobs) - { - if (!(buffer=(byte*) my_alloca(info->s->base.pack_reclength+ - _my_calc_total_blob_length(info,record)))) - DBUG_RETURN(-1); - } - reclength=_mi_rec_pack(info,buffer,record); - record= buffer; - - filepos=info->lastpos; - flag=block_info.second_read=0; - block_info.next_filepos=filepos; - while (reclength > 0) - { - if ((b_type=_mi_get_block_info(&block_info,info->dfile, - block_info.next_filepos)) - & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR | - BLOCK_FATAL_ERROR)) - { - if (b_type & (BLOCK_SYNC_ERROR | BLOCK_DELETED)) - my_errno=HA_ERR_RECORD_CHANGED; - goto err; - } - if (flag == 0) /* First block */ - { - flag=1; - if (reclength != block_info.rec_len) - { - my_errno=HA_ERR_RECORD_CHANGED; - goto err; - } - } else if (reclength < block_info.data_len) - { - my_errno=HA_ERR_WRONG_IN_RECORD; - goto err; - } - reclength-=block_info.data_len; - if (_mi_cmp_buffer(info->dfile,record,block_info.filepos, - block_info.data_len)) - { - my_errno=HA_ERR_RECORD_CHANGED; - goto err; - } - flag=1; - record+=block_info.data_len; - } - } - my_errno=0; -err: - if (buffer != info->rec_buff) - my_afree((gptr) buffer); - DBUG_RETURN(my_errno); -} - - - /* Compare file to buffert */ - -static int _mi_cmp_buffer(File file, const byte *buff, my_off_t filepos, - uint length) -{ - uint next_length; - char temp_buff[IO_SIZE*2]; - DBUG_ENTER("_mi_cmp_buffer"); - - next_length= IO_SIZE*2 - (uint) (filepos & (IO_SIZE-1)); - - while (length > IO_SIZE*2) - { - if (my_pread(file,temp_buff,next_length,filepos, MYF(MY_NABP)) || - memcmp((byte*) buff,temp_buff,next_length)) - goto err; - filepos+=next_length; - buff+=next_length; - length-= next_length; - next_length=IO_SIZE*2; - } - if (my_pread(file,temp_buff,length,filepos,MYF(MY_NABP))) - goto err; - DBUG_RETURN(memcmp((byte*) buff,temp_buff,length)); -err: - DBUG_RETURN(1); -} - - -int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, - register my_off_t filepos, - my_bool skip_deleted_blocks) -{ - int flag,info_read,save_errno; - uint left_len,b_type; - byte *to; - MI_BLOCK_INFO block_info; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("_mi_read_rnd_dynamic_record"); - - info_read=0; - LINT_INIT(to); - - if (info->lock_type == F_UNLCK) - { -#ifndef UNSAFE_LOCKING - if (share->tot_locks == 0) - { - if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF, - MYF(MY_SEEK_NOT_DONE) | info->lock_wait)) - DBUG_RETURN(my_errno); - } -#else - info->tmp_lock_type=F_RDLCK; -#endif - } - else - info_read=1; /* memory-keyinfoblock is ok */ - - flag=block_info.second_read=0; - left_len=1; - do - { - if (filepos >= info->state->data_file_length) - { - if (!info_read) - { /* Check if changed */ - info_read=1; - info->rec_cache.seek_not_done=1; - if (mi_state_info_read_dsk(share->kfile,&share->state,1)) - goto panic; - } - if (filepos >= info->state->data_file_length) - { - my_errno= HA_ERR_END_OF_FILE; - goto err; - } - } - if (info->opt_flag & READ_CACHE_USED) - { - if (_mi_read_cache(&info->rec_cache,(byte*) block_info.header,filepos, - sizeof(block_info.header), - (!flag && skip_deleted_blocks ? READING_NEXT : 0) | - READING_HEADER)) - goto panic; - b_type=_mi_get_block_info(&block_info,-1,filepos); - } - else - { - if (info->opt_flag & WRITE_CACHE_USED && - info->rec_cache.pos_in_file <= filepos && - flush_io_cache(&info->rec_cache)) - DBUG_RETURN(my_errno); - info->rec_cache.seek_not_done=1; - b_type=_mi_get_block_info(&block_info,info->dfile,filepos); - } - - if (b_type & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR | - BLOCK_FATAL_ERROR)) - { - if ((b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR)) - && skip_deleted_blocks) - { - filepos=block_info.filepos+block_info.block_len; - block_info.second_read=0; - continue; /* Search after next_record */ - } - if (b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR)) - { - my_errno=HA_ERR_RECORD_DELETED; - info->lastpos=block_info.filepos; - info->nextpos=block_info.filepos+block_info.block_len; - } - goto err; - } - if (flag == 0) /* First block */ - { - if (block_info.rec_len > (uint) share->base.max_pack_length) - goto panic; - info->lastpos=filepos; - if (share->base.blobs) - { - if (!(to= mi_alloc_rec_buff(info, block_info.rec_len, - &info->rec_buff))) - goto err; - } - else - to= info->rec_buff; - left_len=block_info.rec_len; - } - if (left_len < block_info.data_len) - goto panic; /* Wrong linked record */ - - /* copy information that is already read */ - { - uint offset=(uint) (block_info.filepos - filepos); - uint tmp_length= (sizeof(block_info.header) - offset); - filepos=block_info.filepos; - - if (tmp_length > block_info.data_len) - tmp_length= block_info.data_len; - if (tmp_length) - { - memcpy((byte*) to, block_info.header+offset,tmp_length); - block_info.data_len-=tmp_length; - left_len-=tmp_length; - to+=tmp_length; - filepos+=tmp_length; - } - } - /* read rest of record from file */ - if (block_info.data_len) - { - if (info->opt_flag & READ_CACHE_USED) - { - if (_mi_read_cache(&info->rec_cache,(byte*) to,filepos, - block_info.data_len, - (!flag && skip_deleted_blocks) ? READING_NEXT :0)) - goto panic; - } - else - { - /* VOID(my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0))); */ - if (my_read(info->dfile,(byte*) to,block_info.data_len,MYF(MY_NABP))) - { - if (my_errno == -1) - my_errno= HA_ERR_WRONG_IN_RECORD; /* Unexpected end of file */ - goto err; - } - } - } - if (flag++ == 0) - { - info->nextpos=block_info.filepos+block_info.block_len; - skip_deleted_blocks=0; - } - left_len-=block_info.data_len; - to+=block_info.data_len; - filepos=block_info.next_filepos; - } while (left_len); - - info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED; - fast_mi_writeinfo(info); - if (_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) != - MY_FILE_ERROR) - DBUG_RETURN(0); - DBUG_RETURN(my_errno); /* Wrong record */ - -panic: - my_errno=HA_ERR_WRONG_IN_RECORD; /* Something is fatal wrong */ -err: - save_errno=my_errno; - VOID(_mi_writeinfo(info,0)); - DBUG_RETURN(my_errno=save_errno); -} - - - /* Read and process header from a dynamic-record-file */ - -uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos) -{ - uint return_val=0; - uchar *header=info->header; - - if (file >= 0) - { - VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0))); - if (my_read(file,(char*) header,sizeof(info->header),MYF(0)) != - sizeof(info->header)) - goto err; - } - DBUG_DUMP("header",(byte*) header,MI_BLOCK_INFO_HEADER_LENGTH); - if (info->second_read) - { - if (info->header[0] <= 6 || info->header[0] == 13) - return_val=BLOCK_SYNC_ERROR; - } - else - { - if (info->header[0] > 6 && info->header[0] != 13) - return_val=BLOCK_SYNC_ERROR; - } - info->next_filepos= HA_OFFSET_ERROR; /* Dummy if no next block */ - - switch (info->header[0]) { - case 0: - if ((info->block_len=(uint) mi_uint3korr(header+1)) < - MI_MIN_BLOCK_LENGTH || - (info->block_len & (MI_DYN_ALIGN_SIZE -1))) - goto err; - info->filepos=filepos; - info->next_filepos=mi_sizekorr(header+4); - info->prev_filepos=mi_sizekorr(header+12); -#if SIZEOF_OFF_T == 4 - if ((mi_uint4korr(header+4) != 0 && - (mi_uint4korr(header+4) != (ulong) ~0 || - info->next_filepos != (ulong) ~0)) || - (mi_uint4korr(header+12) != 0 && - (mi_uint4korr(header+12) != (ulong) ~0 || - info->prev_filepos != (ulong) ~0))) - goto err; -#endif - return return_val | BLOCK_DELETED; /* Deleted block */ - - case 1: - info->rec_len=info->data_len=info->block_len=mi_uint2korr(header+1); - info->filepos=filepos+3; - return return_val | BLOCK_FIRST | BLOCK_LAST; - case 2: - info->rec_len=info->data_len=info->block_len=mi_uint3korr(header+1); - info->filepos=filepos+4; - return return_val | BLOCK_FIRST | BLOCK_LAST; - - case 13: - info->rec_len=mi_uint4korr(header+1); - info->block_len=info->data_len=mi_uint3korr(header+5); - info->next_filepos=mi_sizekorr(header+8); - info->second_read=1; - info->filepos=filepos+16; - return return_val | BLOCK_FIRST; - - case 3: - info->rec_len=info->data_len=mi_uint2korr(header+1); - info->block_len=info->rec_len+ (uint) header[3]; - info->filepos=filepos+4; - return return_val | BLOCK_FIRST | BLOCK_LAST; - case 4: - info->rec_len=info->data_len=mi_uint3korr(header+1); - info->block_len=info->rec_len+ (uint) header[4]; - info->filepos=filepos+5; - return return_val | BLOCK_FIRST | BLOCK_LAST; - - case 5: - info->rec_len=mi_uint2korr(header+1); - info->block_len=info->data_len=mi_uint2korr(header+3); - info->next_filepos=mi_sizekorr(header+5); - info->second_read=1; - info->filepos=filepos+13; - return return_val | BLOCK_FIRST; - case 6: - info->rec_len=mi_uint3korr(header+1); - info->block_len=info->data_len=mi_uint3korr(header+4); - info->next_filepos=mi_sizekorr(header+7); - info->second_read=1; - info->filepos=filepos+15; - return return_val | BLOCK_FIRST; - - /* The following blocks are identical to 1-6 without rec_len */ - case 7: - info->data_len=info->block_len=mi_uint2korr(header+1); - info->filepos=filepos+3; - return return_val | BLOCK_LAST; - case 8: - info->data_len=info->block_len=mi_uint3korr(header+1); - info->filepos=filepos+4; - return return_val | BLOCK_LAST; - - case 9: - info->data_len=mi_uint2korr(header+1); - info->block_len=info->data_len+ (uint) header[3]; - info->filepos=filepos+4; - return return_val | BLOCK_LAST; - case 10: - info->data_len=mi_uint3korr(header+1); - info->block_len=info->data_len+ (uint) header[4]; - info->filepos=filepos+5; - return return_val | BLOCK_LAST; - - case 11: - info->data_len=info->block_len=mi_uint2korr(header+1); - info->next_filepos=mi_sizekorr(header+3); - info->second_read=1; - info->filepos=filepos+11; - return return_val; - case 12: - info->data_len=info->block_len=mi_uint3korr(header+1); - info->next_filepos=mi_sizekorr(header+4); - info->second_read=1; - info->filepos=filepos+12; - return return_val; - } - -err: - my_errno=HA_ERR_WRONG_IN_RECORD; /* Garbage */ - return BLOCK_ERROR; -} diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c deleted file mode 100644 index ba32bb9115a..00000000000 --- a/myisam/mi_extra.c +++ /dev/null @@ -1,405 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "myisamdef.h" -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif - -static void mi_extra_keyflag(MI_INFO *info, enum ha_extra_function function); - - -/* - Set options and buffers to optimize table handling - - SYNOPSIS - mi_extra() - info open table - function operation - extra_arg Pointer to extra argument (normally pointer to ulong) - Used when function is one of: - HA_EXTRA_WRITE_CACHE - HA_EXTRA_CACHE - RETURN VALUES - 0 ok - # error -*/ - -int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) -{ - int error=0; - ulong cache_size; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("mi_extra"); - DBUG_PRINT("enter",("function: %d",(int) function)); - - switch (function) { - case HA_EXTRA_RESET: - /* - Free buffers and reset the following flags: - EXTRA_CACHE, EXTRA_WRITE_CACHE, EXTRA_KEYREAD, EXTRA_QUICK - - If the row buffer cache is large (for dynamic tables), reduce it - to save memory. - */ - if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED)) - { - info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); - error=end_io_cache(&info->rec_cache); - } - if (share->base.blobs) - mi_alloc_rec_buff(info, -1, &info->rec_buff); -#if defined(HAVE_MMAP) && defined(HAVE_MADVICE) - if (info->opt_flag & MEMMAP_USED) - madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM); -#endif - info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS); - info->quick_mode=0; - /* Fall through */ - - case HA_EXTRA_RESET_STATE: /* Reset state (don't free buffers) */ - info->lastinx= 0; /* Use first index as def */ - info->last_search_keypage=info->lastpos= HA_OFFSET_ERROR; - info->page_changed=1; - /* Next/prev gives first/last */ - if (info->opt_flag & READ_CACHE_USED) - { - reinit_io_cache(&info->rec_cache,READ_CACHE,0, - (pbool) (info->lock_type != F_UNLCK), - (pbool) test(info->update & HA_STATE_ROW_CHANGED) - ); - } - info->update= ((info->update & HA_STATE_CHANGED) | HA_STATE_NEXT_FOUND | - HA_STATE_PREV_FOUND); - break; - case HA_EXTRA_CACHE: - if (info->lock_type == F_UNLCK && - (share->options & HA_OPTION_PACK_RECORD)) - { - error=1; /* Not possibly if not locked */ - my_errno=EACCES; - break; - } -#if defined(HAVE_MMAP) && defined(HAVE_MADVICE) - if ((share->options & HA_OPTION_COMPRESS_RECORD)) - { - pthread_mutex_lock(&share->intern_lock); - if (_mi_memmap_file(info)) - { - /* We don't nead MADV_SEQUENTIAL if small file */ - madvise(share->file_map,share->state.state.data_file_length, - share->state.state.data_file_length <= RECORD_CACHE_SIZE*16 ? - MADV_RANDOM : MADV_SEQUENTIAL); - pthread_mutex_unlock(&share->intern_lock); - break; - } - pthread_mutex_unlock(&share->intern_lock); - } -#endif - if (info->opt_flag & WRITE_CACHE_USED) - { - info->opt_flag&= ~WRITE_CACHE_USED; - if ((error=end_io_cache(&info->rec_cache))) - break; - } - if (!(info->opt_flag & - (READ_CACHE_USED | WRITE_CACHE_USED | MEMMAP_USED))) - { - cache_size= (extra_arg ? *(ulong*) extra_arg : - my_default_record_cache_size); - if (!(init_io_cache(&info->rec_cache,info->dfile, - (uint) min(info->state->data_file_length+1, - cache_size), - READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK), - MYF(share->write_flag & MY_WAIT_IF_FULL)))) - { - info->opt_flag|=READ_CACHE_USED; - info->update&= ~HA_STATE_ROW_CHANGED; - } - if (share->concurrent_insert) - info->rec_cache.end_of_file=info->state->data_file_length; - } - break; - case HA_EXTRA_REINIT_CACHE: - if (info->opt_flag & READ_CACHE_USED) - { - reinit_io_cache(&info->rec_cache,READ_CACHE,info->nextpos, - (pbool) (info->lock_type != F_UNLCK), - (pbool) test(info->update & HA_STATE_ROW_CHANGED)); - info->update&= ~HA_STATE_ROW_CHANGED; - if (share->concurrent_insert) - info->rec_cache.end_of_file=info->state->data_file_length; - } - break; - case HA_EXTRA_WRITE_CACHE: - if (info->lock_type == F_UNLCK) - { - error=1; /* Not possibly if not locked */ - break; - } - cache_size= (extra_arg ? *(ulong*) extra_arg : - my_default_record_cache_size); - if (!(info->opt_flag & - (READ_CACHE_USED | WRITE_CACHE_USED | OPT_NO_ROWS)) && - !share->state.header.uniques) - if (!(init_io_cache(&info->rec_cache,info->dfile, cache_size, - WRITE_CACHE,info->state->data_file_length, - (pbool) (info->lock_type != F_UNLCK), - MYF(share->write_flag & MY_WAIT_IF_FULL)))) - { - info->opt_flag|=WRITE_CACHE_USED; - info->update&= ~(HA_STATE_ROW_CHANGED | - HA_STATE_WRITE_AT_END | - HA_STATE_EXTEND_BLOCK); - } - break; - case HA_EXTRA_PREPARE_FOR_UPDATE: - if (info->s->data_file_type != DYNAMIC_RECORD) - break; - /* Remove read/write cache if dynamic rows */ - case HA_EXTRA_NO_CACHE: - if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED)) - { - info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); - error=end_io_cache(&info->rec_cache); - /* Sergei will insert full text index caching here */ - } -#if defined(HAVE_MMAP) && defined(HAVE_MADVICE) - if (info->opt_flag & MEMMAP_USED) - madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM); -#endif - break; - case HA_EXTRA_FLUSH_CACHE: - if (info->opt_flag & WRITE_CACHE_USED) - { - if ((error=flush_io_cache(&info->rec_cache))) - { - mi_print_error(info->s, HA_ERR_CRASHED); - mi_mark_crashed(info); /* Fatal error found */ - } - } - break; - case HA_EXTRA_NO_READCHECK: - info->opt_flag&= ~READ_CHECK_USED; /* No readcheck */ - break; - case HA_EXTRA_READCHECK: - info->opt_flag|= READ_CHECK_USED; - break; - case HA_EXTRA_KEYREAD: /* Read only keys to record */ - case HA_EXTRA_REMEMBER_POS: - info->opt_flag |= REMEMBER_OLD_POS; - bmove((byte*) info->lastkey+share->base.max_key_length*2, - (byte*) info->lastkey,info->lastkey_length); - info->save_update= info->update; - info->save_lastinx= info->lastinx; - info->save_lastpos= info->lastpos; - info->save_lastkey_length=info->lastkey_length; - if (function == HA_EXTRA_REMEMBER_POS) - break; - /* fall through */ - case HA_EXTRA_KEYREAD_CHANGE_POS: - info->opt_flag |= KEY_READ_USED; - info->read_record=_mi_read_key_record; - break; - case HA_EXTRA_NO_KEYREAD: - case HA_EXTRA_RESTORE_POS: - if (info->opt_flag & REMEMBER_OLD_POS) - { - bmove((byte*) info->lastkey, - (byte*) info->lastkey+share->base.max_key_length*2, - info->save_lastkey_length); - info->update= info->save_update | HA_STATE_WRITTEN; - info->lastinx= info->save_lastinx; - info->lastpos= info->save_lastpos; - info->lastkey_length=info->save_lastkey_length; - } - info->read_record= share->read_record; - info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS); - break; - case HA_EXTRA_NO_USER_CHANGE: /* Database is somehow locked agains changes */ - info->lock_type= F_EXTRA_LCK; /* Simulate as locked */ - break; - case HA_EXTRA_WAIT_LOCK: - info->lock_wait=0; - break; - case HA_EXTRA_NO_WAIT_LOCK: - info->lock_wait=MY_DONT_WAIT; - break; - case HA_EXTRA_NO_KEYS: - if (info->lock_type == F_UNLCK) - { - error=1; /* Not possibly if not lock */ - break; - } - if (share->state.key_map) - { - MI_KEYDEF *key=share->keyinfo; - uint i; - for (i=0 ; i < share->base.keys ; i++,key++) - { - if (!(key->flag & HA_NOSAME) && info->s->base.auto_key != i+1) - { - share->state.key_map&= ~ ((ulonglong) 1 << i); - info->update|= HA_STATE_CHANGED; - } - } - - if (!share->changed) - { - share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED; - share->changed=1; /* Update on close */ - if (!share->global_changed) - { - share->global_changed=1; - share->state.open_count++; - } - } - share->state.state= *info->state; - error=mi_state_info_write(share->kfile,&share->state,1 | 2); - } - break; - case HA_EXTRA_FORCE_REOPEN: - pthread_mutex_lock(&THR_LOCK_myisam); - share->last_version= 0L; /* Impossible version */ - pthread_mutex_unlock(&THR_LOCK_myisam); - break; - case HA_EXTRA_PREPARE_FOR_DELETE: - pthread_mutex_lock(&THR_LOCK_myisam); - share->last_version= 0L; /* Impossible version */ -#ifdef __WIN__ - /* Close the isam and data files as Win32 can't drop an open table */ - pthread_mutex_lock(&share->intern_lock); - if (flush_key_blocks(share->key_cache, share->kfile, - (function == HA_EXTRA_FORCE_REOPEN ? - FLUSH_RELEASE : FLUSH_IGNORE_CHANGED))) - { - error=my_errno; - share->changed=1; - mi_print_error(info->s, HA_ERR_CRASHED); - mi_mark_crashed(info); /* Fatal error found */ - } - if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED)) - { - info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); - error=end_io_cache(&info->rec_cache); - } - if (info->lock_type != F_UNLCK && ! info->was_locked) - { - info->was_locked=info->lock_type; - if (mi_lock_database(info,F_UNLCK)) - error=my_errno; - info->lock_type = F_UNLCK; - } - if (share->kfile >= 0) - _mi_decrement_open_count(info); - if (share->kfile >= 0 && my_close(share->kfile,MYF(0))) - error=my_errno; - { - LIST *list_element ; - for (list_element=myisam_open_list ; - list_element ; - list_element=list_element->next) - { - MI_INFO *tmpinfo=(MI_INFO*) list_element->data; - if (tmpinfo->s == info->s) - { - if (tmpinfo->dfile >= 0 && my_close(tmpinfo->dfile,MYF(0))) - error = my_errno; - tmpinfo->dfile= -1; - } - } - } - share->kfile= -1; /* Files aren't open anymore */ - pthread_mutex_unlock(&share->intern_lock); -#endif - pthread_mutex_unlock(&THR_LOCK_myisam); - break; - case HA_EXTRA_FLUSH: - if (!share->temporary) - flush_key_blocks(share->key_cache, share->kfile, FLUSH_KEEP); -#ifdef HAVE_PWRITE - _mi_decrement_open_count(info); -#endif - if (share->not_flushed) - { - share->not_flushed=0; - if (my_sync(share->kfile, MYF(0))) - error= my_errno; - if (my_sync(info->dfile, MYF(0))) - error= my_errno; - if (error) - { - share->changed=1; - mi_print_error(info->s, HA_ERR_CRASHED); - mi_mark_crashed(info); /* Fatal error found */ - } - } - if (share->base.blobs) - mi_alloc_rec_buff(info, -1, &info->rec_buff); - break; - case HA_EXTRA_NORMAL: /* Theese isn't in use */ - info->quick_mode=0; - break; - case HA_EXTRA_QUICK: - info->quick_mode=1; - break; - case HA_EXTRA_NO_ROWS: - if (!share->state.header.uniques) - info->opt_flag|= OPT_NO_ROWS; - break; - case HA_EXTRA_PRELOAD_BUFFER_SIZE: - info->preload_buff_size= *((ulong *) extra_arg); - break; - case HA_EXTRA_CHANGE_KEY_TO_UNIQUE: - case HA_EXTRA_CHANGE_KEY_TO_DUP: - mi_extra_keyflag(info, function); - break; - case HA_EXTRA_KEY_CACHE: - case HA_EXTRA_NO_KEY_CACHE: - default: - break; - } - { - char tmp[1]; - tmp[0]=function; - myisam_log_command(MI_LOG_EXTRA,info,(byte*) tmp,1,error); - } - DBUG_RETURN(error); -} /* mi_extra */ - - -/* - Start/Stop Inserting Duplicates Into a Table, WL#1648. - */ -static void mi_extra_keyflag(MI_INFO *info, enum ha_extra_function function) -{ - uint idx; - - for (idx= 0; idx< info->s->base.keys; idx++) - { - switch (function) { - case HA_EXTRA_CHANGE_KEY_TO_UNIQUE: - info->s->keyinfo[idx].flag|= HA_NOSAME; - break; - case HA_EXTRA_CHANGE_KEY_TO_DUP: - info->s->keyinfo[idx].flag&= ~(HA_NOSAME); - break; - default: - break; - } - } -} - diff --git a/myisam/mi_info.c b/myisam/mi_info.c deleted file mode 100644 index bdece9c2ee3..00000000000 --- a/myisam/mi_info.c +++ /dev/null @@ -1,140 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Return useful base information for an open table */ - -#include "myisamdef.h" -#ifdef __WIN__ -#include <sys/stat.h> -#endif - - /* Get position to last record */ - -my_off_t mi_position(MI_INFO *info) -{ - return info->lastpos; -} - - -/* Get information about the table */ -/* if flag == 2 one get current info (no sync from database */ - -int mi_status(MI_INFO *info, register MI_ISAMINFO *x, uint flag) -{ - MY_STAT state; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("mi_status"); - - x->recpos = info->lastpos; - if (flag == HA_STATUS_POS) - DBUG_RETURN(0); /* Compatible with ISAM */ - if (!(flag & HA_STATUS_NO_LOCK)) - { - pthread_mutex_lock(&share->intern_lock); - VOID(_mi_readinfo(info,F_RDLCK,0)); - fast_mi_writeinfo(info); - pthread_mutex_unlock(&share->intern_lock); - } - if (flag & HA_STATUS_VARIABLE) - { - x->records = info->state->records; - x->deleted = info->state->del; - x->delete_length = info->state->empty; - x->data_file_length =info->state->data_file_length; - x->index_file_length=info->state->key_file_length; - - x->keys = share->state.header.keys; - x->check_time = share->state.check_time; - x->mean_reclength = info->state->records ? - (ulong) ((info->state->data_file_length-info->state->empty)/ - info->state->records) : (ulong) share->min_pack_length; - } - if (flag & HA_STATUS_ERRKEY) - { - x->errkey = info->errkey; - x->dupp_key_pos= info->dupp_key_pos; - } - if (flag & HA_STATUS_CONST) - { - x->reclength = share->base.reclength; - x->max_data_file_length=share->base.max_data_file_length; - x->max_index_file_length=info->s->base.max_key_file_length; - x->filenr = info->dfile; - x->options = share->options; - x->create_time=share->state.create_time; - x->reflength= mi_get_pointer_length(share->base.max_data_file_length, - myisam_data_pointer_size); - x->record_offset= ((share->options & - (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? - 0L : share->base.pack_reclength); - x->sortkey= -1; /* No clustering */ - x->rec_per_key = share->state.rec_per_key_part; - x->key_map = share->state.key_map; - x->data_file_name = share->data_file_name; - x->index_file_name = share->index_file_name; - /* - The following should be included even if we are not compiling with - USE_RAID as the client must be able to request it! - */ - x->raid_type= share->base.raid_type; - x->raid_chunks= share->base.raid_chunks; - x->raid_chunksize= share->base.raid_chunksize; - } - if ((flag & HA_STATUS_TIME) && !my_fstat(info->dfile,&state,MYF(0))) - x->update_time=state.st_mtime; - else - x->update_time=0; - if (flag & HA_STATUS_AUTO) - { - x->auto_increment= share->state.auto_increment+1; - if (!x->auto_increment) /* This shouldn't happen */ - x->auto_increment= ~(ulonglong) 0; - } - DBUG_RETURN(0); -} - - -/* - Write a message to the error log. - - SYNOPSIS - mi_report_error() - file_name Name of table file (e.g. index_file_name). - errcode Error number. - - DESCRIPTION - This function supplies my_error() with a table name. Most error - messages need one. Since string arguments in error messages are limited - to 64 characters by convention, we ensure that in case of truncation, - that the end of the index file path is in the message. This contains - the most valuable information (the table name and the database name). - - RETURN - void -*/ - -void mi_report_error(int errcode, const char *file_name) -{ - size_t lgt; - DBUG_ENTER("mi_report_error"); - DBUG_PRINT("enter",("errcode %d, table '%s'", errcode, file_name)); - - if ((lgt= strlen(file_name)) > 64) - file_name+= lgt - 64; - my_error(errcode, MYF(ME_NOREFRESH), file_name); - DBUG_VOID_RETURN; -} - diff --git a/myisam/mi_key.c b/myisam/mi_key.c deleted file mode 100644 index ab5ddd3a378..00000000000 --- a/myisam/mi_key.c +++ /dev/null @@ -1,574 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Functions to handle keys */ - -#include "myisamdef.h" -#include "m_ctype.h" -#include "sp_defs.h" -#ifdef HAVE_IEEEFP_H -#include <ieeefp.h> -#endif - -#define CHECK_KEYS /* Enable safety checks */ - -#define FIX_LENGTH(cs, pos, length, char_length) \ - do { \ - if (length > char_length) \ - char_length= my_charpos(cs, pos, pos+length, char_length); \ - set_if_smaller(char_length,length); \ - } while(0) - -static int _mi_put_key_in_record(MI_INFO *info,uint keynr,byte *record); - -/* - Make a intern key from a record - - SYNOPSIS - _mi_make_key() - info MyiSAM handler - keynr key number - key Store created key here - record Record - filepos Position to record in the data file - - RETURN - Length of key -*/ - -uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key, - const byte *record, my_off_t filepos) -{ - byte *pos,*end; - uchar *start; - reg1 HA_KEYSEG *keyseg; - my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT; - DBUG_ENTER("_mi_make_key"); - - if (info->s->keyinfo[keynr].flag & HA_SPATIAL) - { - /* - TODO: nulls processing - */ -#ifdef HAVE_SPATIAL - return sp_make_key(info,keynr,key,record,filepos); -#else - DBUG_ASSERT(0); /* mi_open should check that this never happens*/ -#endif - } - - start=key; - for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++) - { - enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type; - uint length=keyseg->length; - uint char_length; - CHARSET_INFO *cs=keyseg->charset; - - if (keyseg->null_bit) - { - if (record[keyseg->null_pos] & keyseg->null_bit) - { - *key++= 0; /* NULL in key */ - continue; - } - *key++=1; /* Not NULL */ - } - - char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : - length); - - pos= (byte*) record+keyseg->start; - if (type == HA_KEYTYPE_BIT) - { - if (keyseg->bit_length) - { - uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos, - keyseg->bit_start, keyseg->bit_length); - *key++= bits; - length--; - } - memcpy((byte*) key, pos, length); - key+= length; - continue; - } - if (keyseg->flag & HA_SPACE_PACK) - { - end=pos+length; - if (type != HA_KEYTYPE_NUM) - { - while (end > pos && end[-1] == ' ') - end--; - } - else - { - while (pos < end && pos[0] == ' ') - pos++; - } - length=(uint) (end-pos); - FIX_LENGTH(cs, pos, length, char_length); - store_key_length_inc(key,char_length); - memcpy((byte*) key,(byte*) pos,(size_t) char_length); - key+=char_length; - continue; - } - if (keyseg->flag & HA_VAR_LENGTH_PART) - { - uint pack_length= keyseg->bit_start; - uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos : - uint2korr(pos)); - pos+= pack_length; /* Skip VARCHAR length */ - set_if_smaller(length,tmp_length); - FIX_LENGTH(cs, pos, length, char_length); - store_key_length_inc(key,char_length); - memcpy((byte*) key,(byte*) pos,(size_t) char_length); - key+= char_length; - continue; - } - else if (keyseg->flag & HA_BLOB_PART) - { - uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos); - memcpy_fixed((byte*) &pos,pos+keyseg->bit_start,sizeof(char*)); - set_if_smaller(length,tmp_length); - FIX_LENGTH(cs, pos, length, char_length); - store_key_length_inc(key,char_length); - memcpy((byte*) key,(byte*) pos,(size_t) char_length); - key+= char_length; - continue; - } - else if (keyseg->flag & HA_SWAP_KEY) - { /* Numerical column */ -#ifdef HAVE_ISNAN - if (type == HA_KEYTYPE_FLOAT) - { - float nr; - float4get(nr,pos); - if (isnan(nr)) - { - /* Replace NAN with zero */ - bzero(key,length); - key+=length; - continue; - } - } - else if (type == HA_KEYTYPE_DOUBLE) - { - double nr; - float8get(nr,pos); - if (isnan(nr)) - { - bzero(key,length); - key+=length; - continue; - } - } -#endif - pos+=length; - while (length--) - { - *key++ = *--pos; - } - continue; - } - FIX_LENGTH(cs, pos, length, char_length); - memcpy((byte*) key, pos, char_length); - if (length > char_length) - cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' '); - key+= length; - } - _mi_dpointer(info,key,filepos); - DBUG_PRINT("exit",("keynr: %d",keynr)); - DBUG_DUMP("key",(byte*) start,(uint) (key-start)+keyseg->length); - DBUG_EXECUTE("key", - _mi_print_key(DBUG_FILE,info->s->keyinfo[keynr].seg,start, - (uint) (key-start));); - DBUG_RETURN((uint) (key-start)); /* Return keylength */ -} /* _mi_make_key */ - - -/* - Pack a key to intern format from given format (c_rkey) - - SYNOPSIS - _mi_pack_key() - info MyISAM handler - uint keynr key number - key Store packed key here - old Not packed key - k_length Length of 'old' to use - last_used_keyseg out parameter. May be NULL - - RETURN - length of packed key - - last_use_keyseg Store pointer to the keyseg after the last used one -*/ - -uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old, - uint k_length, HA_KEYSEG **last_used_keyseg) -{ - uchar *start_key=key; - HA_KEYSEG *keyseg; - my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT; - DBUG_ENTER("_mi_pack_key"); - - for (keyseg=info->s->keyinfo[keynr].seg ; - keyseg->type && (int) k_length > 0; - old+=keyseg->length, keyseg++) - { - enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type; - uint length=min((uint) keyseg->length,(uint) k_length); - uint char_length; - uchar *pos; - CHARSET_INFO *cs=keyseg->charset; - - if (keyseg->null_bit) - { - k_length--; - if (!(*key++= (char) 1-*old++)) /* Copy null marker */ - { - k_length-=length; - if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART)) - k_length-=2; /* Skip length */ - continue; /* Found NULL */ - } - } - char_length= (!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length; - pos=old; - if (keyseg->flag & HA_SPACE_PACK) - { - uchar *end=pos+length; - if (type != HA_KEYTYPE_NUM) - { - while (end > pos && end[-1] == ' ') - end--; - } - else - { - while (pos < end && pos[0] == ' ') - pos++; - } - k_length-=length; - length=(uint) (end-pos); - FIX_LENGTH(cs, pos, length, char_length); - store_key_length_inc(key,char_length); - memcpy((byte*) key,pos,(size_t) char_length); - key+= char_length; - continue; - } - else if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART)) - { - /* Length of key-part used with mi_rkey() always 2 */ - uint tmp_length=uint2korr(pos); - k_length-= 2+length; - pos+=2; - set_if_smaller(length,tmp_length); /* Safety */ - FIX_LENGTH(cs, pos, length, char_length); - store_key_length_inc(key,char_length); - old+=2; /* Skip length */ - memcpy((byte*) key, pos,(size_t) char_length); - key+= char_length; - continue; - } - else if (keyseg->flag & HA_SWAP_KEY) - { /* Numerical column */ - pos+=length; - k_length-=length; - while (length--) - { - *key++ = *--pos; - } - continue; - } - FIX_LENGTH(cs, pos, length, char_length); - memcpy((byte*) key, pos, char_length); - if (length > char_length) - cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' '); - key+= length; - k_length-=length; - } - if (last_used_keyseg) - *last_used_keyseg= keyseg; - -#ifdef NOT_USED - if (keyseg->type) - { - /* Part-key ; fill with ASCII 0 for easier searching */ - length= (uint) -k_length; /* unused part of last key */ - do - { - if (keyseg->flag & HA_NULL_PART) - length++; - if (keyseg->flag & HA_SPACE_PACK) - length+=2; - else - length+= keyseg->length; - keyseg++; - } while (keyseg->type); - bzero((byte*) key,length); - key+=length; - } -#endif - DBUG_RETURN((uint) (key-start_key)); -} /* _mi_pack_key */ - - - /* Put a key in record */ - /* Used when only-keyread is wanted */ - -static int _mi_put_key_in_record(register MI_INFO *info, uint keynr, - byte *record) -{ - reg2 byte *key; - byte *pos,*key_end; - reg1 HA_KEYSEG *keyseg; - byte *blob_ptr; - DBUG_ENTER("_mi_put_key_in_record"); - - if (info->s->base.blobs && info->s->keyinfo[keynr].flag & HA_VAR_LENGTH_KEY) - { - if (!(blob_ptr= - mi_alloc_rec_buff(info, info->s->keyinfo[keynr].keylength, - &info->rec_buff))) - goto err; - } - key=(byte*) info->lastkey; - key_end=key+info->lastkey_length; - for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++) - { - if (keyseg->null_bit) - { - if (!*key++) - { - record[keyseg->null_pos]|= keyseg->null_bit; - continue; - } - record[keyseg->null_pos]&= ~keyseg->null_bit; - } - if (keyseg->type == HA_KEYTYPE_BIT) - { - uint length= keyseg->length; - - if (keyseg->bit_length) - { - uchar bits= *key++; - set_rec_bits(bits, record + keyseg->bit_pos, keyseg->bit_start, - keyseg->bit_length); - length--; - } - else - { - clr_rec_bits(record + keyseg->bit_pos, keyseg->bit_start, - keyseg->bit_length); - } - memcpy(record + keyseg->start, (byte*) key, length); - key+= length; - continue; - } - if (keyseg->flag & HA_SPACE_PACK) - { - uint length; - get_key_length(length,key); -#ifdef CHECK_KEYS - if (length > keyseg->length || key+length > key_end) - goto err; -#endif - pos= record+keyseg->start; - if (keyseg->type != (int) HA_KEYTYPE_NUM) - { - memcpy(pos,key,(size_t) length); - bfill(pos+length,keyseg->length-length,' '); - } - else - { - bfill(pos,keyseg->length-length,' '); - memcpy(pos+keyseg->length-length,key,(size_t) length); - } - key+=length; - continue; - } - - if (keyseg->flag & HA_VAR_LENGTH_PART) - { - uint length; - get_key_length(length,key); -#ifdef CHECK_KEYS - if (length > keyseg->length || key+length > key_end) - goto err; -#endif - /* Store key length */ - if (keyseg->bit_start == 1) - *(uchar*) (record+keyseg->start)= (uchar) length; - else - int2store(record+keyseg->start, length); - /* And key data */ - memcpy(record+keyseg->start + keyseg->bit_start, (byte*) key, length); - key+= length; - } - else if (keyseg->flag & HA_BLOB_PART) - { - uint length; - get_key_length(length,key); -#ifdef CHECK_KEYS - if (length > keyseg->length || key+length > key_end) - goto err; -#endif - memcpy(record+keyseg->start+keyseg->bit_start, - (char*) &blob_ptr,sizeof(char*)); - memcpy(blob_ptr,key,length); - blob_ptr+=length; - _my_store_blob_length(record+keyseg->start, - (uint) keyseg->bit_start,length); - key+=length; - } - else if (keyseg->flag & HA_SWAP_KEY) - { - byte *to= record+keyseg->start+keyseg->length; - byte *end= key+keyseg->length; -#ifdef CHECK_KEYS - if (end > key_end) - goto err; -#endif - do - { - *--to= *key++; - } while (key != end); - continue; - } - else - { -#ifdef CHECK_KEYS - if (key+keyseg->length > key_end) - goto err; -#endif - memcpy(record+keyseg->start,(byte*) key, - (size_t) keyseg->length); - key+= keyseg->length; - } - } - DBUG_RETURN(0); - -err: - DBUG_RETURN(1); /* Crashed row */ -} /* _mi_put_key_in_record */ - - - /* Here when key reads are used */ - -int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf) -{ - fast_mi_writeinfo(info); - if (filepos != HA_OFFSET_ERROR) - { - if (info->lastinx >= 0) - { /* Read only key */ - if (_mi_put_key_in_record(info,(uint) info->lastinx,buf)) - { - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - return -1; - } - info->update|= HA_STATE_AKTIV; /* We should find a record */ - return 0; - } - my_errno=HA_ERR_WRONG_INDEX; - } - return(-1); /* Wrong data to read */ -} - - -/* - Update auto_increment info - - SYNOPSIS - update_auto_increment() - info MyISAM handler - record Row to update - - IMPLEMENTATION - Only replace the auto_increment value if it is higher than the previous - one. For signed columns we don't update the auto increment value if it's - less than zero. -*/ - -void update_auto_increment(MI_INFO *info,const byte *record) -{ - ulonglong value= 0; /* Store unsigned values here */ - longlong s_value= 0; /* Store signed values here */ - HA_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg; - const uchar *key= (uchar*) record + keyseg->start; - - switch (keyseg->type) { - case HA_KEYTYPE_INT8: - s_value= (longlong) *(char*)key; - break; - case HA_KEYTYPE_BINARY: - value=(ulonglong) *(uchar*) key; - break; - case HA_KEYTYPE_SHORT_INT: - s_value= (longlong) sint2korr(key); - break; - case HA_KEYTYPE_USHORT_INT: - value=(ulonglong) uint2korr(key); - break; - case HA_KEYTYPE_LONG_INT: - s_value= (longlong) sint4korr(key); - break; - case HA_KEYTYPE_ULONG_INT: - value=(ulonglong) uint4korr(key); - break; - case HA_KEYTYPE_INT24: - s_value= (longlong) sint3korr(key); - break; - case HA_KEYTYPE_UINT24: - value=(ulonglong) uint3korr(key); - break; - case HA_KEYTYPE_FLOAT: /* This shouldn't be used */ - { - float f_1; - float4get(f_1,key); - /* Ignore negative values */ - value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1; - break; - } - case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */ - { - double f_1; - float8get(f_1,key); - /* Ignore negative values */ - value = (f_1 < 0.0) ? 0 : (ulonglong) f_1; - break; - } - case HA_KEYTYPE_LONGLONG: - s_value= sint8korr(key); - break; - case HA_KEYTYPE_ULONGLONG: - value= uint8korr(key); - break; - default: - DBUG_ASSERT(0); - value=0; /* Error */ - break; - } - - /* - The following code works becasue if s_value < 0 then value is 0 - and if s_value == 0 then value will contain either s_value or the - correct value. - */ - set_if_bigger(info->s->state.auto_increment, - (s_value > 0) ? (ulonglong) s_value : value); -} diff --git a/myisam/mi_keycache.c b/myisam/mi_keycache.c deleted file mode 100644 index fb13f3703a2..00000000000 --- a/myisam/mi_keycache.c +++ /dev/null @@ -1,162 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Key cache assignments -*/ - -#include "myisamdef.h" - -/* - Assign pages of the index file for a table to a key cache - - SYNOPSIS - mi_assign_to_key_cache() - info open table - key_map map of indexes to assign to the key cache - key_cache_ptr pointer to the key cache handle - assign_lock Mutex to lock during assignment - - PREREQUESTS - One must have a READ lock or a WRITE lock on the table when calling - the function to ensure that there is no other writers to it. - - The caller must also ensure that one doesn't call this function from - two different threads with the same table. - - NOTES - At present pages for all indexes must be assigned to the same key cache. - In future only pages for indexes specified in the key_map parameter - of the table will be assigned to the specified key cache. - - RETURN VALUE - 0 If a success - # Error code -*/ - -int mi_assign_to_key_cache(MI_INFO *info, - ulonglong key_map __attribute__((unused)), - KEY_CACHE *key_cache) -{ - int error= 0; - MYISAM_SHARE* share= info->s; - DBUG_ENTER("mi_assign_to_key_cache"); - DBUG_PRINT("enter",("old_key_cache_handle: %lx new_key_cache_handle: %lx", - share->key_cache, key_cache)); - - /* - Skip operation if we didn't change key cache. This can happen if we - call this for all open instances of the same table - */ - if (share->key_cache == key_cache) - DBUG_RETURN(0); - - /* - First flush all blocks for the table in the old key cache. - This is to ensure that the disk is consistent with the data pages - in memory (which may not be the case if the table uses delayed_key_write) - - Note that some other read thread may still fill in the key cache with - new blocks during this call and after, but this doesn't matter as - all threads will start using the new key cache for their next call to - myisam library and we know that there will not be any changed blocks - in the old key cache. - */ - - if (flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE)) - { - error= my_errno; - mi_print_error(info->s, HA_ERR_CRASHED); - mi_mark_crashed(info); /* Mark that table must be checked */ - } - - /* - Flush the new key cache for this file. This is needed to ensure - that there is no old blocks (with outdated data) left in the new key - cache from an earlier assign_to_keycache operation - - (This can never fail as there is never any not written data in the - new key cache) - */ - (void) flush_key_blocks(key_cache, share->kfile, FLUSH_RELEASE); - - /* - ensure that setting the key cache and changing the multi_key_cache - is done atomicly - */ - pthread_mutex_lock(&share->intern_lock); - /* - Tell all threads to use the new key cache - This should be seen at the lastes for the next call to an myisam function. - */ - share->key_cache= key_cache; - - /* store the key cache in the global hash structure for future opens */ - if (multi_key_cache_set(share->unique_file_name, share->unique_name_length, - share->key_cache)) - error= my_errno; - pthread_mutex_unlock(&share->intern_lock); - DBUG_RETURN(error); -} - - -/* - Change all MyISAM entries that uses one key cache to another key cache - - SYNOPSIS - mi_change_key_cache() - old_key_cache Old key cache - new_key_cache New key cache - - NOTES - This is used when we delete one key cache. - - To handle the case where some other threads tries to open an MyISAM - table associated with the to-be-deleted key cache while this operation - is running, we have to call 'multi_key_cache_change()' from this - function while we have a lock on the MyISAM table list structure. - - This is safe as long as it's only MyISAM that is using this specific - key cache. -*/ - - -void mi_change_key_cache(KEY_CACHE *old_key_cache, - KEY_CACHE *new_key_cache) -{ - LIST *pos; - DBUG_ENTER("mi_change_key_cache"); - - /* - Lock list to ensure that no one can close the table while we manipulate it - */ - pthread_mutex_lock(&THR_LOCK_myisam); - for (pos=myisam_open_list ; pos ; pos=pos->next) - { - MI_INFO *info= (MI_INFO*) pos->data; - MYISAM_SHARE *share= info->s; - if (share->key_cache == old_key_cache) - mi_assign_to_key_cache(info, (ulonglong) ~0, new_key_cache); - } - - /* - We have to do the following call while we have the lock on the - MyISAM list structure to ensure that another thread is not trying to - open a new table that will be associted with the old key cache - */ - multi_key_cache_change(old_key_cache, new_key_cache); - pthread_mutex_unlock(&THR_LOCK_myisam); -} diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c deleted file mode 100644 index 789d74680ef..00000000000 --- a/myisam/mi_locking.c +++ /dev/null @@ -1,510 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - locking of isam-tables. - reads info from a isam-table. Must be first request before doing any furter - calls to any isamfunktion. Is used to allow many process use the same - isamdatabase. -*/ - -#include "myisamdef.h" - - /* lock table by F_UNLCK, F_RDLCK or F_WRLCK */ - -int mi_lock_database(MI_INFO *info, int lock_type) -{ - int error; - uint count; - MYISAM_SHARE *share=info->s; - uint flag; - DBUG_ENTER("mi_lock_database"); - DBUG_PRINT("enter",("lock_type: %d old lock %d r_locks: %u w_locks: %u " - "global_changed: %d open_count: %u name: '%s'", - lock_type, info->lock_type, share->r_locks, - share->w_locks, - share->global_changed, share->state.open_count, - share->index_file_name)); - - if (share->options & HA_OPTION_READ_ONLY_DATA || - info->lock_type == lock_type) - DBUG_RETURN(0); - if (lock_type == F_EXTRA_LCK) /* Used by TMP tables */ - { - ++share->w_locks; - ++share->tot_locks; - info->lock_type= lock_type; - DBUG_RETURN(0); - } - - flag=error=0; - pthread_mutex_lock(&share->intern_lock); - if (share->kfile >= 0) /* May only be false on windows */ - { - switch (lock_type) { - case F_UNLCK: - if (info->lock_type == F_RDLCK) - count= --share->r_locks; - else - count= --share->w_locks; - --share->tot_locks; - if (info->lock_type == F_WRLCK && !share->w_locks && - !share->delay_key_write && flush_key_blocks(share->key_cache, - share->kfile,FLUSH_KEEP)) - { - error=my_errno; - mi_print_error(info->s, HA_ERR_CRASHED); - mi_mark_crashed(info); /* Mark that table must be checked */ - } - if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED)) - { - if (end_io_cache(&info->rec_cache)) - { - error=my_errno; - mi_print_error(info->s, HA_ERR_CRASHED); - mi_mark_crashed(info); - } - } - if (!count) - { - DBUG_PRINT("info",("changed: %u w_locks: %u", - (uint) share->changed, share->w_locks)); - if (share->changed && !share->w_locks) - { - share->state.process= share->last_process=share->this_process; - share->state.unique= info->last_unique= info->this_unique; - share->state.update_count= info->last_loop= ++info->this_loop; - if (mi_state_info_write(share->kfile, &share->state, 1)) - error=my_errno; - share->changed=0; - if (myisam_flush) - { - if (my_sync(share->kfile, MYF(0))) - error= my_errno; - if (my_sync(info->dfile, MYF(0))) - error= my_errno; - } - else - share->not_flushed=1; - if (error) - { - mi_print_error(info->s, HA_ERR_CRASHED); - mi_mark_crashed(info); - } - } - if (info->lock_type != F_EXTRA_LCK) - { - if (share->r_locks) - { /* Only read locks left */ - flag=1; - if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF, - MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error) - error=my_errno; - } - else if (!share->w_locks) - { /* No more locks */ - flag=1; - if (my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF, - MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error) - error=my_errno; - } - } - } - info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); - info->lock_type= F_UNLCK; - break; - case F_RDLCK: - if (info->lock_type == F_WRLCK) - { - /* - Change RW to READONLY - - mysqld does not turn write locks to read locks, - so we're never here in mysqld. - */ - if (share->w_locks == 1) - { - flag=1; - if (my_lock(share->kfile,lock_type,0L,F_TO_EOF, - MYF(MY_SEEK_NOT_DONE))) - { - error=my_errno; - break; - } - } - share->w_locks--; - share->r_locks++; - info->lock_type=lock_type; - break; - } - if (!share->r_locks && !share->w_locks) - { - flag=1; - if (my_lock(share->kfile,lock_type,0L,F_TO_EOF, - info->lock_wait | MY_SEEK_NOT_DONE)) - { - error=my_errno; - break; - } - if (mi_state_info_read_dsk(share->kfile, &share->state, 1)) - { - error=my_errno; - VOID(my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE))); - my_errno=error; - break; - } - } - VOID(_mi_test_if_changed(info)); - share->r_locks++; - share->tot_locks++; - info->lock_type=lock_type; - break; - case F_WRLCK: - if (info->lock_type == F_RDLCK) - { /* Change READONLY to RW */ - if (share->r_locks == 1) - { - flag=1; - if (my_lock(share->kfile,lock_type,0L,F_TO_EOF, - MYF(info->lock_wait | MY_SEEK_NOT_DONE))) - { - error=my_errno; - break; - } - share->r_locks--; - share->w_locks++; - info->lock_type=lock_type; - break; - } - } - if (!(share->options & HA_OPTION_READ_ONLY_DATA)) - { - if (!share->w_locks) - { - flag=1; - if (my_lock(share->kfile,lock_type,0L,F_TO_EOF, - info->lock_wait | MY_SEEK_NOT_DONE)) - { - error=my_errno; - break; - } - if (!share->r_locks) - { - if (mi_state_info_read_dsk(share->kfile, &share->state, 1)) - { - error=my_errno; - VOID(my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF, - info->lock_wait | MY_SEEK_NOT_DONE)); - my_errno=error; - break; - } - } - } - } - VOID(_mi_test_if_changed(info)); - info->lock_type=lock_type; - info->invalidator=info->s->invalidator; - share->w_locks++; - share->tot_locks++; - break; - default: - break; /* Impossible */ - } - } - pthread_mutex_unlock(&share->intern_lock); -#if defined(FULL_LOG) || defined(_lint) - lock_type|=(int) (flag << 8); /* Set bit to set if real lock */ - myisam_log_command(MI_LOG_LOCK,info,(byte*) &lock_type,sizeof(lock_type), - error); -#endif - DBUG_RETURN(error); -} /* mi_lock_database */ - - -/**************************************************************************** - The following functions are called by thr_lock() in threaded applications -****************************************************************************/ - -void mi_get_status(void* param) -{ - MI_INFO *info=(MI_INFO*) param; - DBUG_ENTER("mi_get_status"); - DBUG_PRINT("info",("key_file: %ld data_file: %ld", - (long) info->s->state.state.key_file_length, - (long) info->s->state.state.data_file_length)); -#ifndef DBUG_OFF - if (info->state->key_file_length > info->s->state.state.key_file_length || - info->state->data_file_length > info->s->state.state.data_file_length) - DBUG_PRINT("warning",("old info: key_file: %ld data_file: %ld", - (long) info->state->key_file_length, - (long) info->state->data_file_length)); -#endif - info->save_state=info->s->state.state; - info->state= &info->save_state; - DBUG_VOID_RETURN; -} - -void mi_update_status(void* param) -{ - MI_INFO *info=(MI_INFO*) param; - /* - Because someone may have closed the table we point at, we only - update the state if its our own state. This isn't a problem as - we are always pointing at our own lock or at a read lock. - (This is enforced by thr_multi_lock.c) - */ - if (info->state == &info->save_state) - { -#ifndef DBUG_OFF - DBUG_PRINT("info",("updating status: key_file: %ld data_file: %ld", - (long) info->state->key_file_length, - (long) info->state->data_file_length)); - if (info->state->key_file_length < info->s->state.state.key_file_length || - info->state->data_file_length < info->s->state.state.data_file_length) - DBUG_PRINT("warning",("old info: key_file: %ld data_file: %ld", - (long) info->s->state.state.key_file_length, - (long) info->s->state.state.data_file_length)); -#endif - info->s->state.state= *info->state; - info->state= &info->s->state.state; - } - - /* - We have to flush the write cache here as other threads may start - reading the table before mi_lock_database() is called - */ - if (info->opt_flag & WRITE_CACHE_USED) - { - if (end_io_cache(&info->rec_cache)) - { - mi_print_error(info->s, HA_ERR_CRASHED); - mi_mark_crashed(info); - } - info->opt_flag&= ~WRITE_CACHE_USED; - } -} - -void mi_copy_status(void* to,void *from) -{ - ((MI_INFO*) to)->state= &((MI_INFO*) from)->save_state; -} - - -/* - Check if should allow concurrent inserts - - IMPLEMENTATION - Don't allow concurrent inserts if we have a hole in the table. - - NOTES - Rtree indexes are disabled in mi_open() - - RETURN - 0 ok to use concurrent inserts - 1 not ok -*/ - -my_bool mi_check_status(void* param) -{ - MI_INFO *info=(MI_INFO*) param; - return (my_bool) (info->s->state.dellink != HA_OFFSET_ERROR); -} - - -/**************************************************************************** - ** functions to read / write the state -****************************************************************************/ - -int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer) -{ - DBUG_ENTER("_mi_readinfo"); - - if (info->lock_type == F_UNLCK) - { - MYISAM_SHARE *share=info->s; - if (!share->tot_locks) - { - if (my_lock(share->kfile,lock_type,0L,F_TO_EOF, - info->lock_wait | MY_SEEK_NOT_DONE)) - DBUG_RETURN(1); - if (mi_state_info_read_dsk(share->kfile, &share->state, 1)) - { - int error=my_errno ? my_errno : -1; - VOID(my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF, - MYF(MY_SEEK_NOT_DONE))); - my_errno=error; - DBUG_RETURN(1); - } - } - if (check_keybuffer) - VOID(_mi_test_if_changed(info)); - info->invalidator=info->s->invalidator; - } - else if (lock_type == F_WRLCK && info->lock_type == F_RDLCK) - { - my_errno=EACCES; /* Not allowed to change */ - DBUG_RETURN(-1); /* when have read_lock() */ - } - DBUG_RETURN(0); -} /* _mi_readinfo */ - - -/* - Every isam-function that uppdates the isam-database MUST end with this - request -*/ - -int _mi_writeinfo(register MI_INFO *info, uint operation) -{ - int error,olderror; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("_mi_writeinfo"); - DBUG_PRINT("info",("operation: %u tot_locks: %u", operation, - share->tot_locks)); - - error=0; - if (share->tot_locks == 0) - { - olderror=my_errno; /* Remember last error */ - if (operation) - { /* Two threads can't be here */ - share->state.process= share->last_process= share->this_process; - share->state.unique= info->last_unique= info->this_unique; - share->state.update_count= info->last_loop= ++info->this_loop; - if ((error=mi_state_info_write(share->kfile, &share->state, 1))) - olderror=my_errno; -#ifdef __WIN__ - if (myisam_flush) - { - _commit(share->kfile); - _commit(info->dfile); - } -#endif - } - if (!(operation & WRITEINFO_NO_UNLOCK) && - my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF, - MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error) - DBUG_RETURN(1); - my_errno=olderror; - } - else if (operation) - share->changed= 1; /* Mark keyfile changed */ - DBUG_RETURN(error); -} /* _mi_writeinfo */ - - - /* Test if someone has changed the database */ - /* (Should be called after readinfo) */ - -int _mi_test_if_changed(register MI_INFO *info) -{ - MYISAM_SHARE *share=info->s; - if (share->state.process != share->last_process || - share->state.unique != info->last_unique || - share->state.update_count != info->last_loop) - { /* Keyfile has changed */ - DBUG_PRINT("info",("index file changed")); - if (share->state.process != share->this_process) - VOID(flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE)); - share->last_process=share->state.process; - info->last_unique= share->state.unique; - info->last_loop= share->state.update_count; - info->update|= HA_STATE_WRITTEN; /* Must use file on next */ - info->data_changed= 1; /* For mi_is_changed */ - return 1; - } - return (!(info->update & HA_STATE_AKTIV) || - (info->update & (HA_STATE_WRITTEN | HA_STATE_DELETED | - HA_STATE_KEY_CHANGED))); -} /* _mi_test_if_changed */ - - -/* - Put a mark in the .MYI file that someone is updating the table - - - DOCUMENTATION - - state.open_count in the .MYI file is used the following way: - - For the first change of the .MYI file in this process open_count is - incremented by mi_mark_file_change(). (We have a write lock on the file - when this happens) - - In mi_close() it's decremented by _mi_decrement_open_count() if it - was incremented in the same process. - - This mean that if we are the only process using the file, the open_count - tells us if the MYISAM file wasn't properly closed. (This is true if - my_disable_locking is set). -*/ - - -int _mi_mark_file_changed(MI_INFO *info) -{ - char buff[3]; - register MYISAM_SHARE *share=info->s; - DBUG_ENTER("_mi_mark_file_changed"); - - if (!(share->state.changed & STATE_CHANGED) || ! share->global_changed) - { - share->state.changed|=(STATE_CHANGED | STATE_NOT_ANALYZED | - STATE_NOT_OPTIMIZED_KEYS); - if (!share->global_changed) - { - share->global_changed=1; - share->state.open_count++; - } - if (!share->temporary) - { - mi_int2store(buff,share->state.open_count); - buff[2]=1; /* Mark that it's changed */ - DBUG_RETURN(my_pwrite(share->kfile,buff,sizeof(buff), - sizeof(share->state.header), - MYF(MY_NABP))); - } - } - DBUG_RETURN(0); -} - - -/* - This is only called by close or by extra(HA_FLUSH) if the OS has the pwrite() - call. In these context the following code should be safe! - */ - -int _mi_decrement_open_count(MI_INFO *info) -{ - char buff[2]; - register MYISAM_SHARE *share=info->s; - int lock_error=0,write_error=0; - if (share->global_changed) - { - uint old_lock=info->lock_type; - share->global_changed=0; - lock_error=mi_lock_database(info,F_WRLCK); - /* Its not fatal even if we couldn't get the lock ! */ - if (share->state.open_count > 0) - { - share->state.open_count--; - mi_int2store(buff,share->state.open_count); - write_error=my_pwrite(share->kfile,buff,sizeof(buff), - sizeof(share->state.header), - MYF(MY_NABP)); - } - if (!lock_error) - lock_error=mi_lock_database(info,old_lock); - } - return test(lock_error || write_error); -} diff --git a/myisam/mi_log.c b/myisam/mi_log.c deleted file mode 100644 index 13842c56828..00000000000 --- a/myisam/mi_log.c +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Logging of MyISAM commands and records on logfile for debugging - The log can be examined with help of the myisamlog command. -*/ - -#include "myisamdef.h" -#if defined(MSDOS) || defined(__WIN__) -#include <fcntl.h> -#ifndef __WIN__ -#include <process.h> -#endif -#endif -#ifdef VMS -#include <processes.h> -#endif - -#undef GETPID /* For HPUX */ -#ifdef THREAD -#define GETPID() (log_type == 1 ? (long) myisam_pid : (long) my_thread_id()); -#else -#define GETPID() myisam_pid -#endif - - /* Activate logging if flag is 1 and reset logging if flag is 0 */ - -static int log_type=0; -ulong myisam_pid=0; - -int mi_log(int activate_log) -{ - int error=0; - char buff[FN_REFLEN]; - DBUG_ENTER("mi_log"); - - log_type=activate_log; - if (activate_log) - { - if (!myisam_pid) - myisam_pid=(ulong) getpid(); - if (myisam_log_file < 0) - { - if ((myisam_log_file = my_create(fn_format(buff,myisam_log_filename, - "",".log",4), - 0,(O_RDWR | O_BINARY | O_APPEND),MYF(0))) - < 0) - DBUG_RETURN(my_errno); - } - } - else if (myisam_log_file >= 0) - { - error=my_close(myisam_log_file,MYF(0)) ? my_errno : 0 ; - myisam_log_file= -1; - } - DBUG_RETURN(error); -} - - - /* Logging of records and commands on logfile */ - /* All logs starts with command(1) dfile(2) process(4) result(2) */ - -void _myisam_log(enum myisam_log_commands command, MI_INFO *info, - const byte *buffert, uint length) -{ - char buff[11]; - int error,old_errno; - ulong pid=(ulong) GETPID(); - old_errno=my_errno; - bzero(buff,sizeof(buff)); - buff[0]=(char) command; - mi_int2store(buff+1,info->dfile); - mi_int4store(buff+3,pid); - mi_int2store(buff+9,length); - - pthread_mutex_lock(&THR_LOCK_myisam); - error=my_lock(myisam_log_file,F_WRLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)); - VOID(my_write(myisam_log_file,buff,sizeof(buff),MYF(0))); - VOID(my_write(myisam_log_file,buffert,length,MYF(0))); - if (!error) - error=my_lock(myisam_log_file,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)); - pthread_mutex_unlock(&THR_LOCK_myisam); - my_errno=old_errno; -} - - -void _myisam_log_command(enum myisam_log_commands command, MI_INFO *info, - const byte *buffert, uint length, int result) -{ - char buff[9]; - int error,old_errno; - ulong pid=(ulong) GETPID(); - - old_errno=my_errno; - buff[0]=(char) command; - mi_int2store(buff+1,info->dfile); - mi_int4store(buff+3,pid); - mi_int2store(buff+7,result); - pthread_mutex_lock(&THR_LOCK_myisam); - error=my_lock(myisam_log_file,F_WRLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)); - VOID(my_write(myisam_log_file,buff,sizeof(buff),MYF(0))); - if (buffert) - VOID(my_write(myisam_log_file,buffert,length,MYF(0))); - if (!error) - error=my_lock(myisam_log_file,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)); - pthread_mutex_unlock(&THR_LOCK_myisam); - my_errno=old_errno; -} - - -void _myisam_log_record(enum myisam_log_commands command, MI_INFO *info, - const byte *record, my_off_t filepos, int result) -{ - char buff[21],*pos; - int error,old_errno; - uint length; - ulong pid=(ulong) GETPID(); - - old_errno=my_errno; - if (!info->s->base.blobs) - length=info->s->base.reclength; - else - length=info->s->base.reclength+ _my_calc_total_blob_length(info,record); - buff[0]=(char) command; - mi_int2store(buff+1,info->dfile); - mi_int4store(buff+3,pid); - mi_int2store(buff+7,result); - mi_sizestore(buff+9,filepos); - mi_int4store(buff+17,length); - pthread_mutex_lock(&THR_LOCK_myisam); - error=my_lock(myisam_log_file,F_WRLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)); - VOID(my_write(myisam_log_file,buff,sizeof(buff),MYF(0))); - VOID(my_write(myisam_log_file,(byte*) record,info->s->base.reclength,MYF(0))); - if (info->s->base.blobs) - { - MI_BLOB *blob,*end; - - for (end=info->blobs+info->s->base.blobs, blob= info->blobs; - blob != end ; - blob++) - { - memcpy_fixed(&pos,record+blob->offset+blob->pack_length,sizeof(char*)); - VOID(my_write(myisam_log_file,pos,blob->length,MYF(0))); - } - } - if (!error) - error=my_lock(myisam_log_file,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)); - pthread_mutex_unlock(&THR_LOCK_myisam); - my_errno=old_errno; -} diff --git a/myisam/mi_open.c b/myisam/mi_open.c deleted file mode 100644 index d65a46a92fb..00000000000 --- a/myisam/mi_open.c +++ /dev/null @@ -1,1270 +0,0 @@ -/* Copyright (C) 2000,2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* open a isam-database */ - -#include "fulltext.h" -#include "sp_defs.h" -#include "rt_index.h" -#include <m_ctype.h> - -#if defined(MSDOS) || defined(__WIN__) -#ifdef __WIN__ -#include <fcntl.h> -#else -#include <process.h> /* Prototype for getpid */ -#endif -#endif -#ifdef VMS -#include "static.c" -#endif - -static void setup_key_functions(MI_KEYDEF *keyinfo); -#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \ - pos+=size;} - - -#define disk_pos_assert(pos, end_pos) \ -if (pos > end_pos) \ -{ \ - my_errno=HA_ERR_CRASHED; \ - goto err; \ -} - - -/****************************************************************************** -** Return the shared struct if the table is already open. -** In MySQL the server will handle version issues. -******************************************************************************/ - -MI_INFO *test_if_reopen(char *filename) -{ - LIST *pos; - - for (pos=myisam_open_list ; pos ; pos=pos->next) - { - MI_INFO *info=(MI_INFO*) pos->data; - MYISAM_SHARE *share=info->s; - if (!strcmp(share->unique_file_name,filename) && share->last_version) - return info; - } - return 0; -} - - -/****************************************************************************** - open a MyISAM database. - See my_base.h for the handle_locking argument - if handle_locking and HA_OPEN_ABORT_IF_CRASHED then abort if the table - is marked crashed or if we are not using locking and the table doesn't - have an open count of 0. -******************************************************************************/ - -MI_INFO *mi_open(const char *name, int mode, uint open_flags) -{ - int lock_error,kfile,open_mode,save_errno,have_rtree=0; - uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys, - key_parts,unique_key_parts,fulltext_keys,uniques; - char name_buff[FN_REFLEN], org_name [FN_REFLEN], index_name[FN_REFLEN], - data_name[FN_REFLEN]; - char *disk_cache, *disk_pos, *end_pos; - MI_INFO info,*m_info,*old_info; - MYISAM_SHARE share_buff,*share; - ulong rec_per_key_part[MI_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG]; - my_off_t key_root[MI_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE]; - ulonglong max_key_file_length, max_data_file_length; - DBUG_ENTER("mi_open"); - - LINT_INIT(m_info); - kfile= -1; - lock_error=1; - errpos=0; - head_length=sizeof(share_buff.state.header); - bzero((byte*) &info,sizeof(info)); - - my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0)); - pthread_mutex_lock(&THR_LOCK_myisam); - if (!(old_info=test_if_reopen(name_buff))) - { - share= &share_buff; - bzero((gptr) &share_buff,sizeof(share_buff)); - share_buff.state.rec_per_key_part=rec_per_key_part; - share_buff.state.key_root=key_root; - share_buff.state.key_del=key_del; - share_buff.key_cache= multi_key_cache_search(name_buff, strlen(name_buff)); - - DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_open", - if (strstr(name, "/t1")) - { - my_errno= HA_ERR_CRASHED; - goto err; - }); - if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0) - { - if ((errno != EROFS && errno != EACCES) || - mode != O_RDONLY || - (kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0) - goto err; - } - share->mode=open_mode; - errpos=1; - if (my_read(kfile,(char*) share->state.header.file_version,head_length, - MYF(MY_NABP))) - { - my_errno= HA_ERR_NOT_A_TABLE; - goto err; - } - if (memcmp((byte*) share->state.header.file_version, - (byte*) myisam_file_magic, 4)) - { - DBUG_PRINT("error",("Wrong header in %s",name_buff)); - DBUG_DUMP("error_dump",(char*) share->state.header.file_version, - head_length); - my_errno=HA_ERR_NOT_A_TABLE; - goto err; - } - share->options= mi_uint2korr(share->state.header.options); - if (share->options & - ~(HA_OPTION_PACK_RECORD | HA_OPTION_PACK_KEYS | - HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA | - HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM | - HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE)) - { - DBUG_PRINT("error",("wrong options: 0x%lx", share->options)); - my_errno=HA_ERR_OLD_FILE; - goto err; - } - /* Don't call realpath() if the name can't be a link */ - if (!strcmp(name_buff, org_name) || - my_readlink(index_name, org_name, MYF(0)) == -1) - (void) strmov(index_name, org_name); - (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,2+4+16); - - info_length=mi_uint2korr(share->state.header.header_length); - base_pos=mi_uint2korr(share->state.header.base_pos); - if (!(disk_cache=(char*) my_alloca(info_length+128))) - { - my_errno=ENOMEM; - goto err; - } - end_pos=disk_cache+info_length; - errpos=2; - - VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0))); - if (!(open_flags & HA_OPEN_TMP_TABLE)) - { - if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF, - MYF(open_flags & HA_OPEN_WAIT_IF_LOCKED ? - 0 : MY_DONT_WAIT))) && - !(open_flags & HA_OPEN_IGNORE_IF_LOCKED)) - goto err; - } - errpos=3; - if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP))) - { - my_errno=HA_ERR_CRASHED; - goto err; - } - len=mi_uint2korr(share->state.header.state_info_length); - keys= (uint) share->state.header.keys; - uniques= (uint) share->state.header.uniques; - fulltext_keys= (uint) share->state.header.fulltext_keys; - key_parts= mi_uint2korr(share->state.header.key_parts); - unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts); - if (len != MI_STATE_INFO_SIZE) - { - DBUG_PRINT("warning", - ("saved_state_info_length: %d state_info_length: %d", - len,MI_STATE_INFO_SIZE)); - } - share->state_diff_length=len-MI_STATE_INFO_SIZE; - - mi_state_info_read(disk_cache, &share->state); - len= mi_uint2korr(share->state.header.base_info_length); - if (len != MI_BASE_INFO_SIZE) - { - DBUG_PRINT("warning",("saved_base_info_length: %d base_info_length: %d", - len,MI_BASE_INFO_SIZE)) - } - disk_pos=my_n_base_info_read(disk_cache+base_pos, &share->base); - share->state.state_length=base_pos; - - if (!(open_flags & HA_OPEN_FOR_REPAIR) && - ((share->state.changed & STATE_CRASHED) || - ((open_flags & HA_OPEN_ABORT_IF_CRASHED) && - (my_disable_locking && share->state.open_count)))) - { - DBUG_PRINT("error",("Table is marked as crashed")); - my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ? - HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE); - goto err; - } - - /* sanity check */ - if (share->base.keystart > 65535 || share->base.rec_reflength > 8) - { - my_errno=HA_ERR_CRASHED; - goto err; - } - - key_parts+=fulltext_keys*FT_SEGS; - if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY || - key_parts >= MI_MAX_KEY * MI_MAX_KEY_SEG) - { - DBUG_PRINT("error",("Wrong key info: Max_key_length: %d keys: %d key_parts: %d", share->base.max_key_length, keys, key_parts)); - my_errno=HA_ERR_UNSUPPORTED; - goto err; - } - - /* Correct max_file_length based on length of sizeof(off_t) */ - max_data_file_length= - (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? - (((ulonglong) 1 << (share->base.rec_reflength*8))-1) : - (mi_safe_mul(share->base.pack_reclength, - (ulonglong) 1 << (share->base.rec_reflength*8))-1); - max_key_file_length= - mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH, - ((ulonglong) 1 << (share->base.key_reflength*8))-1); -#if SIZEOF_OFF_T == 4 - set_if_smaller(max_data_file_length, INT_MAX32); - set_if_smaller(max_key_file_length, INT_MAX32); -#endif -#if USE_RAID && SYSTEM_SIZEOF_OFF_T == 4 - set_if_smaller(max_key_file_length, INT_MAX32); - if (!share->base.raid_type) - { - set_if_smaller(max_data_file_length, INT_MAX32); - } - else - { - set_if_smaller(max_data_file_length, - (ulonglong) share->base.raid_chunks << 31); - } -#elif !defined(USE_RAID) - if (share->base.raid_type) - { - DBUG_PRINT("error",("Table uses RAID but we don't have RAID support")); - my_errno=HA_ERR_UNSUPPORTED; - goto err; - } -#endif - share->base.max_data_file_length=(my_off_t) max_data_file_length; - share->base.max_key_file_length=(my_off_t) max_key_file_length; - - if (share->options & HA_OPTION_COMPRESS_RECORD) - share->base.max_key_length+=2; /* For safety */ - - if (!my_multi_malloc(MY_WME, - &share,sizeof(*share), - &share->state.rec_per_key_part,sizeof(long)*key_parts, - &share->keyinfo,keys*sizeof(MI_KEYDEF), - &share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF), - &share->keyparts, - (key_parts+unique_key_parts+keys+uniques) * - sizeof(HA_KEYSEG), - &share->rec, - (share->base.fields+1)*sizeof(MI_COLUMNDEF), - &share->blobs,sizeof(MI_BLOB)*share->base.blobs, - &share->unique_file_name,strlen(name_buff)+1, - &share->index_file_name,strlen(index_name)+1, - &share->data_file_name,strlen(data_name)+1, - &share->state.key_root,keys*sizeof(my_off_t), - &share->state.key_del, - (share->state.header.max_block_size*sizeof(my_off_t)), -#ifdef THREAD - &share->key_root_lock,sizeof(rw_lock_t)*keys, -#endif - NullS)) - goto err; - errpos=4; - *share=share_buff; - memcpy((char*) share->state.rec_per_key_part, - (char*) rec_per_key_part, sizeof(long)*key_parts); - memcpy((char*) share->state.key_root, - (char*) key_root, sizeof(my_off_t)*keys); - memcpy((char*) share->state.key_del, - (char*) key_del, (sizeof(my_off_t) * - share->state.header.max_block_size)); - strmov(share->unique_file_name, name_buff); - share->unique_name_length= strlen(name_buff); - strmov(share->index_file_name, index_name); - strmov(share->data_file_name, data_name); - - share->blocksize=min(IO_SIZE,myisam_block_size); - { - HA_KEYSEG *pos=share->keyparts; - for (i=0 ; i < keys ; i++) - { - share->keyinfo[i].share= share; - disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]); - disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE, - end_pos); - if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE) - have_rtree=1; - set_if_smaller(share->blocksize,share->keyinfo[i].block_length); - share->keyinfo[i].seg=pos; - for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++) - { - disk_pos=mi_keyseg_read(disk_pos, pos); - - if (pos->type == HA_KEYTYPE_TEXT || - pos->type == HA_KEYTYPE_VARTEXT1 || - pos->type == HA_KEYTYPE_VARTEXT2) - { - if (!pos->language) - pos->charset=default_charset_info; - else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME)))) - { - my_errno=HA_ERR_UNKNOWN_CHARSET; - goto err; - } - } - } - if (share->keyinfo[i].flag & HA_SPATIAL) - { -#ifdef HAVE_SPATIAL - uint sp_segs=SPDIMS*2; - share->keyinfo[i].seg=pos-sp_segs; - share->keyinfo[i].keysegs--; -#else - my_errno=HA_ERR_UNSUPPORTED; - goto err; -#endif - } - else if (share->keyinfo[i].flag & HA_FULLTEXT) - { - if (!fulltext_keys) - { /* 4.0 compatibility code, to be removed in 5.0 */ - share->keyinfo[i].seg=pos-FT_SEGS; - share->keyinfo[i].keysegs-=FT_SEGS; - } - else - { - uint j; - share->keyinfo[i].seg=pos; - for (j=0; j < FT_SEGS; j++) - { - *pos=ft_keysegs[j]; - pos[0].language= pos[-1].language; - if (!(pos[0].charset= pos[-1].charset)) - { - my_errno=HA_ERR_CRASHED; - goto err; - } - pos++; - } - } - if (!share->ft2_keyinfo.seg) - { - memcpy(& share->ft2_keyinfo, & share->keyinfo[i], sizeof(MI_KEYDEF)); - share->ft2_keyinfo.keysegs=1; - share->ft2_keyinfo.flag=0; - share->ft2_keyinfo.keylength= - share->ft2_keyinfo.minlength= - share->ft2_keyinfo.maxlength=HA_FT_WLEN+share->base.rec_reflength; - share->ft2_keyinfo.seg=pos-1; - share->ft2_keyinfo.end=pos; - setup_key_functions(& share->ft2_keyinfo); - } - } - setup_key_functions(share->keyinfo+i); - share->keyinfo[i].end=pos; - pos->type=HA_KEYTYPE_END; /* End */ - pos->length=share->base.rec_reflength; - pos->null_bit=0; - pos->flag=0; /* For purify */ - pos++; - } - for (i=0 ; i < uniques ; i++) - { - disk_pos=mi_uniquedef_read(disk_pos, &share->uniqueinfo[i]); - disk_pos_assert(disk_pos + share->uniqueinfo[i].keysegs * - HA_KEYSEG_SIZE, end_pos); - share->uniqueinfo[i].seg=pos; - for (j=0 ; j < share->uniqueinfo[i].keysegs; j++,pos++) - { - disk_pos=mi_keyseg_read(disk_pos, pos); - if (pos->type == HA_KEYTYPE_TEXT || - pos->type == HA_KEYTYPE_VARTEXT1 || - pos->type == HA_KEYTYPE_VARTEXT2) - { - if (!pos->language) - pos->charset=default_charset_info; - else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME)))) - { - my_errno=HA_ERR_UNKNOWN_CHARSET; - goto err; - } - } - } - share->uniqueinfo[i].end=pos; - pos->type=HA_KEYTYPE_END; /* End */ - pos->null_bit=0; - pos->flag=0; - pos++; - } - } - - disk_pos_assert(disk_pos + share->base.fields *MI_COLUMNDEF_SIZE, end_pos); - for (i=j=offset=0 ; i < share->base.fields ; i++) - { - disk_pos=mi_recinfo_read(disk_pos,&share->rec[i]); - share->rec[i].pack_type=0; - share->rec[i].huff_tree=0; - share->rec[i].offset=offset; - if (share->rec[i].type == (int) FIELD_BLOB) - { - share->blobs[j].pack_length= - share->rec[i].length-mi_portable_sizeof_char_ptr;; - share->blobs[j].offset=offset; - j++; - } - offset+=share->rec[i].length; - } - share->rec[i].type=(int) FIELD_LAST; /* End marker */ - - if (! lock_error) - { - VOID(my_lock(kfile,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE))); - lock_error=1; /* Database unlocked */ - } - - if (mi_open_datafile(&info, share, -1)) - goto err; - errpos=5; - - share->kfile=kfile; - share->this_process=(ulong) getpid(); - share->last_process= share->state.process; - share->base.key_parts=key_parts; - share->base.all_key_parts=key_parts+unique_key_parts; - if (!(share->last_version=share->state.version)) - share->last_version=1; /* Safety */ - share->rec_reflength=share->base.rec_reflength; /* May be changed */ - share->base.margin_key_file_length=(share->base.max_key_file_length - - (keys ? MI_INDEX_BLOCK_MARGIN * - share->blocksize * keys : 0)); - share->blocksize=min(IO_SIZE,myisam_block_size); - - share->data_file_type=STATIC_RECORD; - if (share->options & HA_OPTION_COMPRESS_RECORD) - { - share->data_file_type = COMPRESSED_RECORD; - share->options|= HA_OPTION_READ_ONLY_DATA; - info.s=share; - if (_mi_read_pack_info(&info, - (pbool) - test(!(share->options & - (HA_OPTION_PACK_RECORD | - HA_OPTION_TEMP_COMPRESS_RECORD))))) - goto err; - } - else if (share->options & HA_OPTION_PACK_RECORD) - share->data_file_type = DYNAMIC_RECORD; - my_afree((gptr) disk_cache); - mi_setup_functions(share); -#ifdef THREAD - thr_lock_init(&share->lock); - VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST)); - for (i=0; i<keys; i++) - VOID(my_rwlock_init(&share->key_root_lock[i], NULL)); - if (!thr_lock_inited) - { - /* Probably a single threaded program; Don't use concurrent inserts */ - myisam_concurrent_insert=0; - } - else if (myisam_concurrent_insert) - { - share->concurrent_insert= - ((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE | - HA_OPTION_COMPRESS_RECORD | - HA_OPTION_TEMP_COMPRESS_RECORD)) || - (open_flags & HA_OPEN_TMP_TABLE) || - have_rtree) ? 0 : 1; - if (share->concurrent_insert) - { - share->lock.get_status=mi_get_status; - share->lock.copy_status=mi_copy_status; - share->lock.update_status=mi_update_status; - share->lock.check_status=mi_check_status; - } - } -#endif - } - else - { - share= old_info->s; - if (mode == O_RDWR && share->mode == O_RDONLY) - { - my_errno=EACCES; /* Can't open in write mode */ - goto err; - } - if (mi_open_datafile(&info, share, old_info->dfile)) - goto err; - errpos=5; - have_rtree= old_info->rtree_recursion_state != NULL; - } - - /* alloc and set up private structure parts */ - if (!my_multi_malloc(MY_WME, - &m_info,sizeof(MI_INFO), - &info.blobs,sizeof(MI_BLOB)*share->base.blobs, - &info.buff,(share->base.max_key_block_length*2+ - share->base.max_key_length), - &info.lastkey,share->base.max_key_length*3+1, - &info.first_mbr_key, share->base.max_key_length, - &info.filename,strlen(org_name)+1, - &info.rtree_recursion_state,have_rtree ? 1024 : 0, - NullS)) - goto err; - errpos=6; - - if (!have_rtree) - info.rtree_recursion_state= NULL; - - strmov(info.filename,org_name); - memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs); - info.lastkey2=info.lastkey+share->base.max_key_length; - - info.s=share; - info.lastpos= HA_OFFSET_ERROR; - info.update= (short) (HA_STATE_NEXT_FOUND+HA_STATE_PREV_FOUND); - info.opt_flag=READ_CHECK_USED; - info.this_unique= (ulong) info.dfile; /* Uniq number in process */ - if (share->data_file_type == COMPRESSED_RECORD) - info.this_unique= share->state.unique; - info.this_loop=0; /* Update counter */ - info.last_unique= share->state.unique; - info.last_loop= share->state.update_count; - if (mode == O_RDONLY) - share->options|=HA_OPTION_READ_ONLY_DATA; - info.lock_type=F_UNLCK; - info.quick_mode=0; - info.bulk_insert=0; - info.ft1_to_ft2=0; - info.errkey= -1; - info.page_changed=1; - pthread_mutex_lock(&share->intern_lock); - info.read_record=share->read_record; - share->reopen++; - share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL); - if (share->options & HA_OPTION_READ_ONLY_DATA) - { - info.lock_type=F_RDLCK; - share->r_locks++; - share->tot_locks++; - } - if ((open_flags & HA_OPEN_TMP_TABLE) || - (share->options & HA_OPTION_TMP_TABLE)) - { - share->temporary=share->delay_key_write=1; - share->write_flag=MYF(MY_NABP); - share->w_locks++; /* We don't have to update status */ - share->tot_locks++; - info.lock_type=F_WRLCK; - } - if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) || - (share->options & HA_OPTION_DELAY_KEY_WRITE)) && - myisam_delay_key_write) - share->delay_key_write=1; - info.state= &share->state.state; /* Change global values by default */ - pthread_mutex_unlock(&share->intern_lock); - - /* Allocate buffer for one record */ - - /* prerequisites: bzero(info) && info->s=share; are met. */ - if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff)) - goto err; - bzero(info.rec_buff, mi_get_rec_buff_len(&info, info.rec_buff)); - - *m_info=info; -#ifdef THREAD - thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info); -#endif - m_info->open_list.data=(void*) m_info; - myisam_open_list=list_add(myisam_open_list,&m_info->open_list); - - pthread_mutex_unlock(&THR_LOCK_myisam); - if (myisam_log_file >= 0) - { - intern_filename(name_buff,share->index_file_name); - _myisam_log(MI_LOG_OPEN,m_info,name_buff,(uint) strlen(name_buff)); - } - DBUG_RETURN(m_info); - -err: - save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE; - if ((save_errno == HA_ERR_CRASHED) || - (save_errno == HA_ERR_CRASHED_ON_USAGE) || - (save_errno == HA_ERR_CRASHED_ON_REPAIR)) - mi_report_error(save_errno, name); - switch (errpos) { - case 6: - my_free((gptr) m_info,MYF(0)); - /* fall through */ - case 5: - VOID(my_close(info.dfile,MYF(0))); - if (old_info) - break; /* Don't remove open table */ - /* fall through */ - case 4: - my_free((gptr) share,MYF(0)); - /* fall through */ - case 3: - if (! lock_error) - VOID(my_lock(kfile, F_UNLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE))); - /* fall through */ - case 2: - my_afree((gptr) disk_cache); - /* fall through */ - case 1: - VOID(my_close(kfile,MYF(0))); - /* fall through */ - case 0: - default: - break; - } - pthread_mutex_unlock(&THR_LOCK_myisam); - my_errno=save_errno; - DBUG_RETURN (NULL); -} /* mi_open */ - - -byte *mi_alloc_rec_buff(MI_INFO *info, ulong length, byte **buf) -{ - uint extra; - uint32 old_length; - LINT_INIT(old_length); - - if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf))) - { - byte *newptr = *buf; - - /* to simplify initial init of info->rec_buf in mi_open and mi_extra */ - if (length == (ulong) -1) - { - length= max(info->s->base.pack_reclength, - info->s->base.max_key_length); - /* Avoid unnecessary realloc */ - if (newptr && length == old_length) - return newptr; - } - - extra= ((info->s->options & HA_OPTION_PACK_RECORD) ? - ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+ - MI_REC_BUFF_OFFSET : 0); - if (extra && newptr) - newptr-= MI_REC_BUFF_OFFSET; - if (!(newptr=(byte*) my_realloc((gptr)newptr, length+extra+8, - MYF(MY_ALLOW_ZERO_PTR)))) - return newptr; - *((uint32 *) newptr)= (uint32) length; - *buf= newptr+(extra ? MI_REC_BUFF_OFFSET : 0); - } - return *buf; -} - - -ulonglong mi_safe_mul(ulonglong a, ulonglong b) -{ - ulonglong max_val= ~ (ulonglong) 0; /* my_off_t is unsigned */ - - if (!a || max_val / a < b) - return max_val; - return a*b; -} - - /* Set up functions in structs */ - -void mi_setup_functions(register MYISAM_SHARE *share) -{ - if (share->options & HA_OPTION_COMPRESS_RECORD) - { - share->read_record=_mi_read_pack_record; - share->read_rnd=_mi_read_rnd_pack_record; - if (!(share->options & HA_OPTION_TEMP_COMPRESS_RECORD)) - share->calc_checksum=0; /* No checksum */ - else if (share->options & HA_OPTION_PACK_RECORD) - share->calc_checksum= mi_checksum; - else - share->calc_checksum= mi_static_checksum; - } - else if (share->options & HA_OPTION_PACK_RECORD) - { - share->read_record=_mi_read_dynamic_record; - share->read_rnd=_mi_read_rnd_dynamic_record; - share->delete_record=_mi_delete_dynamic_record; - share->compare_record=_mi_cmp_dynamic_record; - share->compare_unique=_mi_cmp_dynamic_unique; - share->calc_checksum= mi_checksum; - - /* add bits used to pack data to pack_reclength for faster allocation */ - share->base.pack_reclength+= share->base.pack_bits; - if (share->base.blobs) - { - share->update_record=_mi_update_blob_record; - share->write_record=_mi_write_blob_record; - } - else - { - share->write_record=_mi_write_dynamic_record; - share->update_record=_mi_update_dynamic_record; - } - } - else - { - share->read_record=_mi_read_static_record; - share->read_rnd=_mi_read_rnd_static_record; - share->delete_record=_mi_delete_static_record; - share->compare_record=_mi_cmp_static_record; - share->update_record=_mi_update_static_record; - share->write_record=_mi_write_static_record; - share->compare_unique=_mi_cmp_static_unique; - share->calc_checksum= mi_static_checksum; - } - if (!(share->options & HA_OPTION_CHECKSUM)) - share->calc_checksum=0; - return; -} - - -static void setup_key_functions(register MI_KEYDEF *keyinfo) -{ - if (keyinfo->key_alg == HA_KEY_ALG_RTREE) - { -#ifdef HAVE_RTREE_KEYS - keyinfo->ck_insert = rtree_insert; - keyinfo->ck_delete = rtree_delete; -#else - DBUG_ASSERT(0); /* mi_open should check it never happens */ -#endif - } - else - { - keyinfo->ck_insert = _mi_ck_write; - keyinfo->ck_delete = _mi_ck_delete; - } - if (keyinfo->flag & HA_BINARY_PACK_KEY) - { /* Simple prefix compression */ - keyinfo->bin_search=_mi_seq_search; - keyinfo->get_key=_mi_get_binary_pack_key; - keyinfo->pack_key=_mi_calc_bin_pack_key_length; - keyinfo->store_key=_mi_store_bin_pack_key; - } - else if (keyinfo->flag & HA_VAR_LENGTH_KEY) - { - keyinfo->get_key= _mi_get_pack_key; - if (keyinfo->seg[0].flag & HA_PACK_KEY) - { /* Prefix compression */ - if (!keyinfo->seg->charset || use_strnxfrm(keyinfo->seg->charset) || - (keyinfo->seg->flag & HA_NULL_PART)) - keyinfo->bin_search=_mi_seq_search; - else - keyinfo->bin_search=_mi_prefix_search; - keyinfo->pack_key=_mi_calc_var_pack_key_length; - keyinfo->store_key=_mi_store_var_pack_key; - } - else - { - keyinfo->bin_search=_mi_seq_search; - keyinfo->pack_key=_mi_calc_var_key_length; /* Variable length key */ - keyinfo->store_key=_mi_store_static_key; - } - } - else - { - keyinfo->bin_search=_mi_bin_search; - keyinfo->get_key=_mi_get_static_key; - keyinfo->pack_key=_mi_calc_static_key_length; - keyinfo->store_key=_mi_store_static_key; - } - return; -} - - -/* - Function to save and store the header in the index file (.MYI) -*/ - -uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite) -{ - uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE]; - uchar *ptr=buff; - uint i, keys= (uint) state->header.keys, - key_blocks=state->header.max_block_size; - DBUG_ENTER("mi_state_info_write"); - - memcpy_fixed(ptr,&state->header,sizeof(state->header)); - ptr+=sizeof(state->header); - - /* open_count must be first because of _mi_mark_file_changed ! */ - mi_int2store(ptr,state->open_count); ptr +=2; - *ptr++= (uchar)state->changed; *ptr++= state->sortkey; - mi_rowstore(ptr,state->state.records); ptr +=8; - mi_rowstore(ptr,state->state.del); ptr +=8; - mi_rowstore(ptr,state->split); ptr +=8; - mi_sizestore(ptr,state->dellink); ptr +=8; - mi_sizestore(ptr,state->state.key_file_length); ptr +=8; - mi_sizestore(ptr,state->state.data_file_length); ptr +=8; - mi_sizestore(ptr,state->state.empty); ptr +=8; - mi_sizestore(ptr,state->state.key_empty); ptr +=8; - mi_int8store(ptr,state->auto_increment); ptr +=8; - mi_int8store(ptr,(ulonglong) state->checksum);ptr +=8; - mi_int4store(ptr,state->process); ptr +=4; - mi_int4store(ptr,state->unique); ptr +=4; - mi_int4store(ptr,state->status); ptr +=4; - mi_int4store(ptr,state->update_count); ptr +=4; - - ptr+=state->state_diff_length; - - for (i=0; i < keys; i++) - { - mi_sizestore(ptr,state->key_root[i]); ptr +=8; - } - for (i=0; i < key_blocks; i++) - { - mi_sizestore(ptr,state->key_del[i]); ptr +=8; - } - if (pWrite & 2) /* From isamchk */ - { - uint key_parts= mi_uint2korr(state->header.key_parts); - mi_int4store(ptr,state->sec_index_changed); ptr +=4; - mi_int4store(ptr,state->sec_index_used); ptr +=4; - mi_int4store(ptr,state->version); ptr +=4; - mi_int8store(ptr,state->key_map); ptr +=8; - mi_int8store(ptr,(ulonglong) state->create_time); ptr +=8; - mi_int8store(ptr,(ulonglong) state->recover_time); ptr +=8; - mi_int8store(ptr,(ulonglong) state->check_time); ptr +=8; - mi_sizestore(ptr,state->rec_per_key_rows); ptr+=8; - for (i=0 ; i < key_parts ; i++) - { - mi_int4store(ptr,state->rec_per_key_part[i]); ptr+=4; - } - } - - if (pWrite & 1) - DBUG_RETURN(my_pwrite(file,(char*) buff, (uint) (ptr-buff), 0L, - MYF(MY_NABP | MY_THREADSAFE))); - DBUG_RETURN(my_write(file, (char*) buff, (uint) (ptr-buff), - MYF(MY_NABP))); -} - - -char *mi_state_info_read(char *ptr, MI_STATE_INFO *state) -{ - uint i,keys,key_parts,key_blocks; - memcpy_fixed(&state->header,ptr, sizeof(state->header)); - ptr +=sizeof(state->header); - keys=(uint) state->header.keys; - key_parts=mi_uint2korr(state->header.key_parts); - key_blocks=state->header.max_block_size; - - state->open_count = mi_uint2korr(ptr); ptr +=2; - state->changed= (bool) *ptr++; - state->sortkey = (uint) *ptr++; - state->state.records= mi_rowkorr(ptr); ptr +=8; - state->state.del = mi_rowkorr(ptr); ptr +=8; - state->split = mi_rowkorr(ptr); ptr +=8; - state->dellink= mi_sizekorr(ptr); ptr +=8; - state->state.key_file_length = mi_sizekorr(ptr); ptr +=8; - state->state.data_file_length= mi_sizekorr(ptr); ptr +=8; - state->state.empty = mi_sizekorr(ptr); ptr +=8; - state->state.key_empty= mi_sizekorr(ptr); ptr +=8; - state->auto_increment=mi_uint8korr(ptr); ptr +=8; - state->checksum=(ha_checksum) mi_uint8korr(ptr); ptr +=8; - state->process= mi_uint4korr(ptr); ptr +=4; - state->unique = mi_uint4korr(ptr); ptr +=4; - state->status = mi_uint4korr(ptr); ptr +=4; - state->update_count=mi_uint4korr(ptr); ptr +=4; - - ptr+= state->state_diff_length; - - for (i=0; i < keys; i++) - { - state->key_root[i]= mi_sizekorr(ptr); ptr +=8; - } - for (i=0; i < key_blocks; i++) - { - state->key_del[i] = mi_sizekorr(ptr); ptr +=8; - } - state->sec_index_changed = mi_uint4korr(ptr); ptr +=4; - state->sec_index_used = mi_uint4korr(ptr); ptr +=4; - state->version = mi_uint4korr(ptr); ptr +=4; - state->key_map = mi_uint8korr(ptr); ptr +=8; - state->create_time = (time_t) mi_sizekorr(ptr); ptr +=8; - state->recover_time =(time_t) mi_sizekorr(ptr); ptr +=8; - state->check_time = (time_t) mi_sizekorr(ptr); ptr +=8; - state->rec_per_key_rows=mi_sizekorr(ptr); ptr +=8; - for (i=0 ; i < key_parts ; i++) - { - state->rec_per_key_part[i]= mi_uint4korr(ptr); ptr+=4; - } - return ptr; -} - - -uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead) -{ - char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE]; - - if (!myisam_single_user) - { - if (pRead) - { - if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP))) - return (MY_FILE_ERROR); - } - else if (my_read(file, buff, state->state_length,MYF(MY_NABP))) - return (MY_FILE_ERROR); - mi_state_info_read(buff, state); - } - return 0; -} - - -/**************************************************************************** -** store and read of MI_BASE_INFO -****************************************************************************/ - -uint mi_base_info_write(File file, MI_BASE_INFO *base) -{ - uchar buff[MI_BASE_INFO_SIZE], *ptr=buff; - - mi_sizestore(ptr,base->keystart); ptr +=8; - mi_sizestore(ptr,base->max_data_file_length); ptr +=8; - mi_sizestore(ptr,base->max_key_file_length); ptr +=8; - mi_rowstore(ptr,base->records); ptr +=8; - mi_rowstore(ptr,base->reloc); ptr +=8; - mi_int4store(ptr,base->mean_row_length); ptr +=4; - mi_int4store(ptr,base->reclength); ptr +=4; - mi_int4store(ptr,base->pack_reclength); ptr +=4; - mi_int4store(ptr,base->min_pack_length); ptr +=4; - mi_int4store(ptr,base->max_pack_length); ptr +=4; - mi_int4store(ptr,base->min_block_length); ptr +=4; - mi_int4store(ptr,base->fields); ptr +=4; - mi_int4store(ptr,base->pack_fields); ptr +=4; - *ptr++=base->rec_reflength; - *ptr++=base->key_reflength; - *ptr++=base->keys; - *ptr++=base->auto_key; - mi_int2store(ptr,base->pack_bits); ptr +=2; - mi_int2store(ptr,base->blobs); ptr +=2; - mi_int2store(ptr,base->max_key_block_length); ptr +=2; - mi_int2store(ptr,base->max_key_length); ptr +=2; - mi_int2store(ptr,base->extra_alloc_bytes); ptr +=2; - *ptr++= base->extra_alloc_procent; - *ptr++= base->raid_type; - mi_int2store(ptr,base->raid_chunks); ptr +=2; - mi_int4store(ptr,base->raid_chunksize); ptr +=4; - bzero(ptr,6); ptr +=6; /* extra */ - return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP)); -} - - -char *my_n_base_info_read(char *ptr, MI_BASE_INFO *base) -{ - base->keystart = mi_sizekorr(ptr); ptr +=8; - base->max_data_file_length = mi_sizekorr(ptr); ptr +=8; - base->max_key_file_length = mi_sizekorr(ptr); ptr +=8; - base->records = (ha_rows) mi_sizekorr(ptr); ptr +=8; - base->reloc = (ha_rows) mi_sizekorr(ptr); ptr +=8; - base->mean_row_length = mi_uint4korr(ptr); ptr +=4; - base->reclength = mi_uint4korr(ptr); ptr +=4; - base->pack_reclength = mi_uint4korr(ptr); ptr +=4; - base->min_pack_length = mi_uint4korr(ptr); ptr +=4; - base->max_pack_length = mi_uint4korr(ptr); ptr +=4; - base->min_block_length = mi_uint4korr(ptr); ptr +=4; - base->fields = mi_uint4korr(ptr); ptr +=4; - base->pack_fields = mi_uint4korr(ptr); ptr +=4; - - base->rec_reflength = *ptr++; - base->key_reflength = *ptr++; - base->keys= *ptr++; - base->auto_key= *ptr++; - base->pack_bits = mi_uint2korr(ptr); ptr +=2; - base->blobs = mi_uint2korr(ptr); ptr +=2; - base->max_key_block_length= mi_uint2korr(ptr); ptr +=2; - base->max_key_length = mi_uint2korr(ptr); ptr +=2; - base->extra_alloc_bytes = mi_uint2korr(ptr); ptr +=2; - base->extra_alloc_procent = *ptr++; - base->raid_type= *ptr++; - base->raid_chunks= mi_uint2korr(ptr); ptr +=2; - base->raid_chunksize= mi_uint4korr(ptr); ptr +=4; - /* TO BE REMOVED: Fix for old RAID files */ - if (base->raid_type == 0) - { - base->raid_chunks=0; - base->raid_chunksize=0; - } - - ptr+=6; - return ptr; -} - -/*-------------------------------------------------------------------------- - mi_keydef ----------------------------------------------------------------------------*/ - -uint mi_keydef_write(File file, MI_KEYDEF *keydef) -{ - uchar buff[MI_KEYDEF_SIZE]; - uchar *ptr=buff; - - *ptr++ = (uchar) keydef->keysegs; - *ptr++ = keydef->key_alg; /* Rtree or Btree */ - mi_int2store(ptr,keydef->flag); ptr +=2; - mi_int2store(ptr,keydef->block_length); ptr +=2; - mi_int2store(ptr,keydef->keylength); ptr +=2; - mi_int2store(ptr,keydef->minlength); ptr +=2; - mi_int2store(ptr,keydef->maxlength); ptr +=2; - return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP)); -} - -char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef) -{ - keydef->keysegs = (uint) *ptr++; - keydef->key_alg = *ptr++; /* Rtree or Btree */ - - keydef->flag = mi_uint2korr(ptr); ptr +=2; - keydef->block_length = mi_uint2korr(ptr); ptr +=2; - keydef->keylength = mi_uint2korr(ptr); ptr +=2; - keydef->minlength = mi_uint2korr(ptr); ptr +=2; - keydef->maxlength = mi_uint2korr(ptr); ptr +=2; - keydef->block_size = keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1; - keydef->underflow_block_length=keydef->block_length/3; - keydef->version = 0; /* Not saved */ - return ptr; -} - -/*************************************************************************** -** mi_keyseg -***************************************************************************/ - -int mi_keyseg_write(File file, const HA_KEYSEG *keyseg) -{ - uchar buff[HA_KEYSEG_SIZE]; - uchar *ptr=buff; - ulong pos; - - *ptr++= keyseg->type; - *ptr++= keyseg->language; - *ptr++= keyseg->null_bit; - *ptr++= keyseg->bit_start; - *ptr++= keyseg->bit_end; - *ptr++= keyseg->bit_length; - mi_int2store(ptr,keyseg->flag); ptr+=2; - mi_int2store(ptr,keyseg->length); ptr+=2; - mi_int4store(ptr,keyseg->start); ptr+=4; - pos= keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos; - mi_int4store(ptr, pos); - ptr+=4; - - return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP)); -} - - -char *mi_keyseg_read(char *ptr, HA_KEYSEG *keyseg) -{ - keyseg->type = *ptr++; - keyseg->language = *ptr++; - keyseg->null_bit = *ptr++; - keyseg->bit_start = *ptr++; - keyseg->bit_end = *ptr++; - keyseg->bit_length = *ptr++; - keyseg->flag = mi_uint2korr(ptr); ptr +=2; - keyseg->length = mi_uint2korr(ptr); ptr +=2; - keyseg->start = mi_uint4korr(ptr); ptr +=4; - keyseg->null_pos = mi_uint4korr(ptr); ptr +=4; - keyseg->charset=0; /* Will be filled in later */ - if (keyseg->null_bit) - keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == 7)); - else - { - keyseg->bit_pos= (uint16)keyseg->null_pos; - keyseg->null_pos= 0; - } - return ptr; -} - -/*-------------------------------------------------------------------------- - mi_uniquedef ----------------------------------------------------------------------------*/ - -uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def) -{ - uchar buff[MI_UNIQUEDEF_SIZE]; - uchar *ptr=buff; - - mi_int2store(ptr,def->keysegs); ptr+=2; - *ptr++= (uchar) def->key; - *ptr++ = (uchar) def->null_are_equal; - - return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP)); -} - -char *mi_uniquedef_read(char *ptr, MI_UNIQUEDEF *def) -{ - def->keysegs = mi_uint2korr(ptr); - def->key = ptr[2]; - def->null_are_equal=ptr[3]; - return ptr+4; /* 1 extra byte */ -} - -/*************************************************************************** -** MI_COLUMNDEF -***************************************************************************/ - -uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo) -{ - uchar buff[MI_COLUMNDEF_SIZE]; - uchar *ptr=buff; - - mi_int2store(ptr,recinfo->type); ptr +=2; - mi_int2store(ptr,recinfo->length); ptr +=2; - *ptr++ = recinfo->null_bit; - mi_int2store(ptr,recinfo->null_pos); ptr+= 2; - return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP)); -} - -char *mi_recinfo_read(char *ptr, MI_COLUMNDEF *recinfo) -{ - recinfo->type= mi_sint2korr(ptr); ptr +=2; - recinfo->length=mi_uint2korr(ptr); ptr +=2; - recinfo->null_bit= (uint8) *ptr++; - recinfo->null_pos=mi_uint2korr(ptr); ptr +=2; - return ptr; -} - -/************************************************************************** -Open data file with or without RAID -We can't use dup() here as the data file descriptors need to have different -active seek-positions. - -The argument file_to_dup is here for the future if there would on some OS -exist a dup()-like call that would give us two different file descriptors. -*************************************************************************/ - -int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup __attribute__((unused))) -{ -#ifdef USE_RAID - if (share->base.raid_type) - { - info->dfile=my_raid_open(share->data_file_name, - share->mode | O_SHARE, - share->base.raid_type, - share->base.raid_chunks, - share->base.raid_chunksize, - MYF(MY_WME | MY_RAID)); - } - else -#endif - info->dfile=my_open(share->data_file_name, share->mode | O_SHARE, - MYF(MY_WME)); - return info->dfile >= 0 ? 0 : 1; -} - - -int mi_open_keyfile(MYISAM_SHARE *share) -{ - if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE, - MYF(MY_WME))) < 0) - return 1; - return 0; -} - - -/* - Disable all indexes. - - SYNOPSIS - mi_disable_indexes() - info A pointer to the MyISAM storage engine MI_INFO struct. - - DESCRIPTION - Disable all indexes. - - RETURN - 0 ok -*/ - -int mi_disable_indexes(MI_INFO *info) -{ - MYISAM_SHARE *share= info->s; - - share->state.key_map= 0; - return 0; -} - - -/* - Enable all indexes - - SYNOPSIS - mi_enable_indexes() - info A pointer to the MyISAM storage engine MI_INFO struct. - - DESCRIPTION - Enable all indexes. The indexes might have been disabled - by mi_disable_index() before. - The function works only if both data and indexes are empty, - otherwise a repair is required. - To be sure, call handler::delete_all_rows() before. - - RETURN - 0 ok - HA_ERR_CRASHED data or index is non-empty. -*/ - -int mi_enable_indexes(MI_INFO *info) -{ - int error= 0; - MYISAM_SHARE *share= info->s; - - if (share->state.state.data_file_length || - (share->state.state.key_file_length != share->base.keystart)) - { - mi_print_error(info->s, HA_ERR_CRASHED); - error= HA_ERR_CRASHED; - } - else - share->state.key_map= ((ulonglong) 1L << share->base.keys) - 1; - return error; -} - - -/* - Test if indexes are disabled. - - SYNOPSIS - mi_indexes_are_disabled() - info A pointer to the MyISAM storage engine MI_INFO struct. - - DESCRIPTION - Test if indexes are disabled. - - RETURN - 0 indexes are not disabled - 1 all indexes are disabled - [2 non-unique indexes are disabled - NOT YET IMPLEMENTED] -*/ - -int mi_indexes_are_disabled(MI_INFO *info) -{ - MYISAM_SHARE *share= info->s; - - return (! share->state.key_map && share->base.keys); -} - diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c deleted file mode 100644 index 4b512dd89dd..00000000000 --- a/myisam/mi_packrec.c +++ /dev/null @@ -1,1358 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - - /* Functions to compressed records */ - -#include "myisamdef.h" - -#define IS_CHAR ((uint) 32768) /* Bit if char (not offset) in tree */ - -#if INT_MAX > 65536L -#define BITS_SAVED 32 -#define MAX_QUICK_TABLE_BITS 9 /* Because we may shift in 24 bits */ -#else -#define BITS_SAVED 16 -#define MAX_QUICK_TABLE_BITS 6 -#endif - -#define get_bit(BU) ((BU)->bits ? \ - (BU)->current_byte & ((mi_bit_type) 1 << --(BU)->bits) :\ - (fill_buffer(BU), (BU)->bits= BITS_SAVED-1,\ - (BU)->current_byte & ((mi_bit_type) 1 << (BITS_SAVED-1)))) -#define skip_to_next_byte(BU) ((BU)->bits&=~7) -#define get_bits(BU,count) (((BU)->bits >= count) ? (((BU)->current_byte >> ((BU)->bits-=count)) & mask[count]) : fill_and_get_bits(BU,count)) - -#define decode_bytes_test_bit(bit) \ - if (low_byte & (1 << (7-bit))) \ - pos++; \ - if (*pos & IS_CHAR) \ - { bits-=(bit+1); break; } \ - pos+= *pos - -#define OFFSET_TABLE_SIZE 512 - -static uint read_huff_table(MI_BIT_BUFF *bit_buff,MI_DECODE_TREE *decode_tree, - uint16 **decode_table,byte **intervall_buff, - uint16 *tmp_buff); -static void make_quick_table(uint16 *to_table,uint16 *decode_table, - uint *next_free,uint value,uint bits, - uint max_bits); -static void fill_quick_table(uint16 *table,uint bits, uint max_bits, - uint value); -static uint copy_decode_table(uint16 *to_pos,uint offset, - uint16 *decode_table); -static uint find_longest_bitstream(uint16 *table, uint16 *end); -static void (*get_unpack_function(MI_COLUMNDEF *rec))(MI_COLUMNDEF *field, - MI_BIT_BUFF *buff, - uchar *to, - uchar *end); -static void uf_zerofill_skip_zero(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_skip_zero(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_space_normal(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_space_endspace_selected(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end); -static void uf_endspace_selected(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_space_endspace(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_endspace(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_space_prespace_selected(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end); -static void uf_prespace_selected(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_space_prespace(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_prespace(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_zerofill_normal(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_constant(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_intervall(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_zero(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static void uf_blob(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end); -static void uf_varchar1(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end); -static void uf_varchar2(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end); -static void decode_bytes(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff, - uchar *to,uchar *end); -static uint decode_pos(MI_BIT_BUFF *bit_buff,MI_DECODE_TREE *decode_tree); -static void init_bit_buffer(MI_BIT_BUFF *bit_buff,uchar *buffer,uint length); -static uint fill_and_get_bits(MI_BIT_BUFF *bit_buff,uint count); -static void fill_buffer(MI_BIT_BUFF *bit_buff); -static uint max_bit(uint value); -#ifdef HAVE_MMAP -static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info, - uchar *header); -#endif - -static mi_bit_type mask[]= -{ - 0x00000000, - 0x00000001, 0x00000003, 0x00000007, 0x0000000f, - 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, - 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, - 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, -#if BITS_SAVED > 16 - 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, - 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, - 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, - 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff, -#endif - }; - - - /* Read all packed info, allocate memory and fix field structs */ - -my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys) -{ - File file; - int diff_length; - uint i,trees,huff_tree_bits,rec_reflength,length; - uint16 *decode_table,*tmp_buff; - ulong elements,intervall_length; - char *disk_cache,*intervall_buff; - uchar header[32]; - MYISAM_SHARE *share=info->s; - MI_BIT_BUFF bit_buff; - DBUG_ENTER("_mi_read_pack_info"); - - if (myisam_quick_table_bits < 4) - myisam_quick_table_bits=4; - else if (myisam_quick_table_bits > MAX_QUICK_TABLE_BITS) - myisam_quick_table_bits=MAX_QUICK_TABLE_BITS; - - file=info->dfile; - my_errno=0; - if (my_read(file,(byte*) header,sizeof(header),MYF(MY_NABP))) - { - if (!my_errno) - my_errno=HA_ERR_END_OF_FILE; - goto err0; - } - if (memcmp((byte*) header,(byte*) myisam_pack_file_magic,4)) - { - my_errno=HA_ERR_WRONG_IN_RECORD; - goto err0; - } - share->pack.header_length= uint4korr(header+4); - share->min_pack_length=(uint) uint4korr(header+8); - share->max_pack_length=(uint) uint4korr(header+12); - set_if_bigger(share->base.pack_reclength,share->max_pack_length); - elements=uint4korr(header+16); - intervall_length=uint4korr(header+20); - trees=uint2korr(header+24); - share->pack.ref_length=header[26]; - rec_reflength=header[27]; - diff_length=(int) rec_reflength - (int) share->base.rec_reflength; - if (fix_keys) - share->rec_reflength=rec_reflength; - share->base.min_block_length=share->min_pack_length+1; - if (share->min_pack_length > 254) - share->base.min_block_length+=2; - - if (!(share->decode_trees=(MI_DECODE_TREE*) - my_malloc((uint) (trees*sizeof(MI_DECODE_TREE)+ - intervall_length*sizeof(byte)), - MYF(MY_WME)))) - goto err0; - intervall_buff=(byte*) (share->decode_trees+trees); - - length=(uint) (elements*2+trees*(1 << myisam_quick_table_bits)); - if (!(share->decode_tables=(uint16*) - my_malloc((length+OFFSET_TABLE_SIZE)*sizeof(uint16)+ - (uint) (share->pack.header_length+7), - MYF(MY_WME | MY_ZEROFILL)))) - goto err1; - tmp_buff=share->decode_tables+length; - disk_cache=(byte*) (tmp_buff+OFFSET_TABLE_SIZE); - - if (my_read(file,disk_cache, - (uint) (share->pack.header_length-sizeof(header)), - MYF(MY_NABP))) - goto err2; - - huff_tree_bits=max_bit(trees ? trees-1 : 0); - init_bit_buffer(&bit_buff, (uchar*) disk_cache, - (uint) (share->pack.header_length-sizeof(header))); - /* Read new info for each field */ - for (i=0 ; i < share->base.fields ; i++) - { - share->rec[i].base_type=(enum en_fieldtype) get_bits(&bit_buff,5); - share->rec[i].pack_type=(uint) get_bits(&bit_buff,6); - share->rec[i].space_length_bits=get_bits(&bit_buff,5); - share->rec[i].huff_tree=share->decode_trees+(uint) get_bits(&bit_buff, - huff_tree_bits); - share->rec[i].unpack=get_unpack_function(share->rec+i); - } - skip_to_next_byte(&bit_buff); - decode_table=share->decode_tables; - for (i=0 ; i < trees ; i++) - if (read_huff_table(&bit_buff,share->decode_trees+i,&decode_table, - &intervall_buff,tmp_buff)) - goto err3; - decode_table=(uint16*) - my_realloc((gptr) share->decode_tables, - (uint) ((byte*) decode_table - (byte*) share->decode_tables), - MYF(MY_HOLD_ON_ERROR)); - { - long diff=PTR_BYTE_DIFF(decode_table,share->decode_tables); - share->decode_tables=decode_table; - for (i=0 ; i < trees ; i++) - share->decode_trees[i].table=ADD_TO_PTR(share->decode_trees[i].table, - diff, uint16*); - } - - /* Fix record-ref-length for keys */ - if (fix_keys) - { - for (i=0 ; i < share->base.keys ; i++) - { - share->keyinfo[i].keylength+=(uint16) diff_length; - share->keyinfo[i].minlength+=(uint16) diff_length; - share->keyinfo[i].maxlength+=(uint16) diff_length; - share->keyinfo[i].seg[share->keyinfo[i].keysegs].length= - (uint16) rec_reflength; - } - } - - if (bit_buff.error || bit_buff.pos < bit_buff.end) - goto err3; - - DBUG_RETURN(0); - -err3: - my_errno=HA_ERR_WRONG_IN_RECORD; -err2: - my_free((gptr) share->decode_tables,MYF(0)); -err1: - my_free((gptr) share->decode_trees,MYF(0)); -err0: - DBUG_RETURN(1); -} - - - /* Read on huff-code-table from datafile */ - -static uint read_huff_table(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree, - uint16 **decode_table, byte **intervall_buff, - uint16 *tmp_buff) -{ - uint min_chr,elements,char_bits,offset_bits,size,intervall_length,table_bits, - next_free_offset; - uint16 *ptr,*end; - - LINT_INIT(ptr); - if (!get_bits(bit_buff,1)) - { - min_chr=get_bits(bit_buff,8); - elements=get_bits(bit_buff,9); - char_bits=get_bits(bit_buff,5); - offset_bits=get_bits(bit_buff,5); - intervall_length=0; - ptr=tmp_buff; - } - else - { - min_chr=0; - elements=get_bits(bit_buff,15); - intervall_length=get_bits(bit_buff,16); - char_bits=get_bits(bit_buff,5); - offset_bits=get_bits(bit_buff,5); - decode_tree->quick_table_bits=0; - ptr= *decode_table; - } - size=elements*2-2; - - for (end=ptr+size ; ptr < end ; ptr++) - { - if (get_bit(bit_buff)) - *ptr= (uint16) get_bits(bit_buff,offset_bits); - else - *ptr= (uint16) (IS_CHAR + (get_bits(bit_buff,char_bits) + min_chr)); - } - skip_to_next_byte(bit_buff); - - decode_tree->table= *decode_table; - decode_tree->intervalls= *intervall_buff; - if (! intervall_length) - { - table_bits=find_longest_bitstream(tmp_buff, tmp_buff+OFFSET_TABLE_SIZE); - if (table_bits == (uint) ~0) - return 1; - if (table_bits > myisam_quick_table_bits) - table_bits=myisam_quick_table_bits; - next_free_offset= (1 << table_bits); - make_quick_table(*decode_table,tmp_buff,&next_free_offset,0,table_bits, - table_bits); - (*decode_table)+= next_free_offset; - decode_tree->quick_table_bits=table_bits; - } - else - { - (*decode_table)=end; - bit_buff->pos-= bit_buff->bits/8; - memcpy(*intervall_buff,bit_buff->pos,(size_t) intervall_length); - (*intervall_buff)+=intervall_length; - bit_buff->pos+=intervall_length; - bit_buff->bits=0; - } - return 0; -} - - -static void make_quick_table(uint16 *to_table, uint16 *decode_table, - uint *next_free_offset, uint value, uint bits, - uint max_bits) -{ - if (!bits--) - { - to_table[value]= (uint16) *next_free_offset; - *next_free_offset=copy_decode_table(to_table, *next_free_offset, - decode_table); - return; - } - if (!(*decode_table & IS_CHAR)) - { - make_quick_table(to_table,decode_table+ *decode_table, - next_free_offset,value,bits,max_bits); - } - else - fill_quick_table(to_table+value,bits,max_bits,(uint) *decode_table); - decode_table++; - value|= (1 << bits); - if (!(*decode_table & IS_CHAR)) - { - make_quick_table(to_table,decode_table+ *decode_table, - next_free_offset,value,bits,max_bits); - } - else - fill_quick_table(to_table+value,bits,max_bits,(uint) *decode_table); - return; -} - - -static void fill_quick_table(uint16 *table, uint bits, uint max_bits, - uint value) -{ - uint16 *end; - value|=(max_bits-bits) << 8; - for (end=table+ (1 << bits) ; - table < end ; - *table++ = (uint16) value | IS_CHAR) ; -} - - -static uint copy_decode_table(uint16 *to_pos, uint offset, - uint16 *decode_table) -{ - uint prev_offset; - prev_offset= offset; - - if (!(*decode_table & IS_CHAR)) - { - to_pos[offset]=2; - offset=copy_decode_table(to_pos,offset+2,decode_table+ *decode_table); - } - else - { - to_pos[offset]= *decode_table; - offset+=2; - } - decode_table++; - - if (!(*decode_table & IS_CHAR)) - { - to_pos[prev_offset+1]=(uint16) (offset-prev_offset-1); - offset=copy_decode_table(to_pos,offset,decode_table+ *decode_table); - } - else - to_pos[prev_offset+1]= *decode_table; - return offset; -} - - -static uint find_longest_bitstream(uint16 *table, uint16 *end) -{ - uint length=1,length2; - if (!(*table & IS_CHAR)) - { - uint16 *next= table + *table; - if (next > end || next == table) - return ~0; - length=find_longest_bitstream(next, end)+1; - } - table++; - if (!(*table & IS_CHAR)) - { - uint16 *next= table + *table; - if (next > end || next == table) - return ~0; - length2=find_longest_bitstream(table+ *table, end)+1; - length=max(length,length2); - } - return length; -} - - - /* Read record from datafile */ - /* Returns length of packed record, -1 if error */ - -int _mi_read_pack_record(MI_INFO *info, my_off_t filepos, byte *buf) -{ - MI_BLOCK_INFO block_info; - File file; - DBUG_ENTER("mi_read_pack_record"); - - if (filepos == HA_OFFSET_ERROR) - DBUG_RETURN(-1); /* _search() didn't find record */ - - file=info->dfile; - if (_mi_pack_get_block_info(info, &block_info, file, filepos)) - goto err; - if (my_read(file,(byte*) info->rec_buff + block_info.offset , - block_info.rec_len - block_info.offset, MYF(MY_NABP))) - goto panic; - info->update|= HA_STATE_AKTIV; - DBUG_RETURN(_mi_pack_rec_unpack(info,buf,info->rec_buff,block_info.rec_len)); -panic: - my_errno=HA_ERR_WRONG_IN_RECORD; -err: - DBUG_RETURN(-1); -} - - - -int _mi_pack_rec_unpack(register MI_INFO *info, register byte *to, byte *from, - ulong reclength) -{ - byte *end_field; - reg3 MI_COLUMNDEF *end; - MI_COLUMNDEF *current_field; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("_mi_pack_rec_unpack"); - - init_bit_buffer(&info->bit_buff, (uchar*) from,reclength); - - for (current_field=share->rec, end=current_field+share->base.fields ; - current_field < end ; - current_field++,to=end_field) - { - end_field=to+current_field->length; - (*current_field->unpack)(current_field,&info->bit_buff,(uchar*) to, - (uchar*) end_field); - } - if (! info->bit_buff.error && - info->bit_buff.pos - info->bit_buff.bits/8 == info->bit_buff.end) - DBUG_RETURN(0); - info->update&= ~HA_STATE_AKTIV; - DBUG_RETURN(my_errno=HA_ERR_WRONG_IN_RECORD); -} /* _mi_pack_rec_unpack */ - - - /* Return function to unpack field */ - -static void (*get_unpack_function(MI_COLUMNDEF *rec)) -(MI_COLUMNDEF *, MI_BIT_BUFF *, uchar *, uchar *) -{ - switch (rec->base_type) { - case FIELD_SKIP_ZERO: - if (rec->pack_type & PACK_TYPE_ZERO_FILL) - return &uf_zerofill_skip_zero; - return &uf_skip_zero; - case FIELD_NORMAL: - if (rec->pack_type & PACK_TYPE_SPACE_FIELDS) - return &uf_space_normal; - if (rec->pack_type & PACK_TYPE_ZERO_FILL) - return &uf_zerofill_normal; - return &decode_bytes; - case FIELD_SKIP_ENDSPACE: - if (rec->pack_type & PACK_TYPE_SPACE_FIELDS) - { - if (rec->pack_type & PACK_TYPE_SELECTED) - return &uf_space_endspace_selected; - return &uf_space_endspace; - } - if (rec->pack_type & PACK_TYPE_SELECTED) - return &uf_endspace_selected; - return &uf_endspace; - case FIELD_SKIP_PRESPACE: - if (rec->pack_type & PACK_TYPE_SPACE_FIELDS) - { - if (rec->pack_type & PACK_TYPE_SELECTED) - return &uf_space_prespace_selected; - return &uf_space_prespace; - } - if (rec->pack_type & PACK_TYPE_SELECTED) - return &uf_prespace_selected; - return &uf_prespace; - case FIELD_CONSTANT: - return &uf_constant; - case FIELD_INTERVALL: - return &uf_intervall; - case FIELD_ZERO: - case FIELD_CHECK: - return &uf_zero; - case FIELD_BLOB: - return &uf_blob; - case FIELD_VARCHAR: - if (rec->length <= 256) /* 255 + 1 byte length */ - return &uf_varchar1; - return &uf_varchar2; - case FIELD_LAST: - default: - return 0; /* This should never happend */ - } -} - - /* The different functions to unpack a field */ - -static void uf_zerofill_skip_zero(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end) -{ - if (get_bit(bit_buff)) - bzero((char*) to,(uint) (end-to)); - else - { - end-=rec->space_length_bits; - decode_bytes(rec,bit_buff,to,end); - bzero((char*) end,rec->space_length_bits); - } -} - -static void uf_skip_zero(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, - uchar *end) -{ - if (get_bit(bit_buff)) - bzero((char*) to,(uint) (end-to)); - else - decode_bytes(rec,bit_buff,to,end); -} - -static void uf_space_normal(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, - uchar *end) -{ - if (get_bit(bit_buff)) - bfill((byte*) to,(end-to),' '); - else - decode_bytes(rec,bit_buff,to,end); -} - -static void uf_space_endspace_selected(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end) -{ - uint spaces; - if (get_bit(bit_buff)) - bfill((byte*) to,(end-to),' '); - else - { - if (get_bit(bit_buff)) - { - if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end) - { - bit_buff->error=1; - return; - } - if (to+spaces != end) - decode_bytes(rec,bit_buff,to,end-spaces); - bfill((byte*) end-spaces,spaces,' '); - } - else - decode_bytes(rec,bit_buff,to,end); - } -} - -static void uf_endspace_selected(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end) -{ - uint spaces; - if (get_bit(bit_buff)) - { - if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end) - { - bit_buff->error=1; - return; - } - if (to+spaces != end) - decode_bytes(rec,bit_buff,to,end-spaces); - bfill((byte*) end-spaces,spaces,' '); - } - else - decode_bytes(rec,bit_buff,to,end); -} - -static void uf_space_endspace(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, - uchar *end) -{ - uint spaces; - if (get_bit(bit_buff)) - bfill((byte*) to,(end-to),' '); - else - { - if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end) - { - bit_buff->error=1; - return; - } - if (to+spaces != end) - decode_bytes(rec,bit_buff,to,end-spaces); - bfill((byte*) end-spaces,spaces,' '); - } -} - -static void uf_endspace(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, - uchar *end) -{ - uint spaces; - if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end) - { - bit_buff->error=1; - return; - } - if (to+spaces != end) - decode_bytes(rec,bit_buff,to,end-spaces); - bfill((byte*) end-spaces,spaces,' '); -} - -static void uf_space_prespace_selected(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end) -{ - uint spaces; - if (get_bit(bit_buff)) - bfill((byte*) to,(end-to),' '); - else - { - if (get_bit(bit_buff)) - { - if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end) - { - bit_buff->error=1; - return; - } - bfill((byte*) to,spaces,' '); - if (to+spaces != end) - decode_bytes(rec,bit_buff,to+spaces,end); - } - else - decode_bytes(rec,bit_buff,to,end); - } -} - - -static void uf_prespace_selected(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end) -{ - uint spaces; - if (get_bit(bit_buff)) - { - if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end) - { - bit_buff->error=1; - return; - } - bfill((byte*) to,spaces,' '); - if (to+spaces != end) - decode_bytes(rec,bit_buff,to+spaces,end); - } - else - decode_bytes(rec,bit_buff,to,end); -} - - -static void uf_space_prespace(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, - uchar *end) -{ - uint spaces; - if (get_bit(bit_buff)) - bfill((byte*) to,(end-to),' '); - else - { - if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end) - { - bit_buff->error=1; - return; - } - bfill((byte*) to,spaces,' '); - if (to+spaces != end) - decode_bytes(rec,bit_buff,to+spaces,end); - } -} - -static void uf_prespace(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, - uchar *end) -{ - uint spaces; - if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end) - { - bit_buff->error=1; - return; - } - bfill((byte*) to,spaces,' '); - if (to+spaces != end) - decode_bytes(rec,bit_buff,to+spaces,end); -} - -static void uf_zerofill_normal(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, - uchar *end) -{ - end-=rec->space_length_bits; - decode_bytes(rec,bit_buff,(uchar*) to,end); - bzero((char*) end,rec->space_length_bits); -} - -static void uf_constant(MI_COLUMNDEF *rec, - MI_BIT_BUFF *bit_buff __attribute__((unused)), - uchar *to, - uchar *end) -{ - memcpy(to,rec->huff_tree->intervalls,(size_t) (end-to)); -} - -static void uf_intervall(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, - uchar *end) -{ - reg1 uint field_length=(uint) (end-to); - memcpy(to,rec->huff_tree->intervalls+field_length*decode_pos(bit_buff, - rec->huff_tree), - (size_t) field_length); -} - - -/*ARGSUSED*/ -static void uf_zero(MI_COLUMNDEF *rec __attribute__((unused)), - MI_BIT_BUFF *bit_buff __attribute__((unused)), - uchar *to, uchar *end) -{ - bzero((char*) to,(uint) (end-to)); -} - -static void uf_blob(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end) -{ - if (get_bit(bit_buff)) - bzero((byte*) to,(end-to)); - else - { - ulong length=get_bits(bit_buff,rec->space_length_bits); - uint pack_length=(uint) (end-to)-mi_portable_sizeof_char_ptr; - if (bit_buff->blob_pos+length > bit_buff->blob_end) - { - bit_buff->error=1; - bzero((byte*) to,(end-to)); - return; - } - decode_bytes(rec,bit_buff,bit_buff->blob_pos,bit_buff->blob_pos+length); - _my_store_blob_length((byte*) to,pack_length,length); - memcpy_fixed((char*) to+pack_length,(char*) &bit_buff->blob_pos, - sizeof(char*)); - bit_buff->blob_pos+=length; - } -} - - -static void uf_varchar1(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end __attribute__((unused))) -{ - if (get_bit(bit_buff)) - to[0]= 0; /* Zero lengths */ - else - { - ulong length=get_bits(bit_buff,rec->space_length_bits); - *to= (uchar) length; - decode_bytes(rec,bit_buff,to+1,to+1+length); - } -} - - -static void uf_varchar2(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, - uchar *to, uchar *end __attribute__((unused))) -{ - if (get_bit(bit_buff)) - to[0]=to[1]=0; /* Zero lengths */ - else - { - ulong length=get_bits(bit_buff,rec->space_length_bits); - int2store(to,length); - decode_bytes(rec,bit_buff,to+2,to+2+length); - } -} - - /* Functions to decode of buffer of bits */ - -#if BITS_SAVED == 64 - -static void decode_bytes(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,uchar *to, - uchar *end) -{ - reg1 uint bits,low_byte; - reg3 uint16 *pos; - reg4 uint table_bits,table_and; - MI_DECODE_TREE *decode_tree; - - decode_tree=rec->decode_tree; - bits=bit_buff->bits; /* Save in reg for quicker access */ - table_bits=decode_tree->quick_table_bits; - table_and= (1 << table_bits)-1; - - do - { - if (bits <= 32) - { - if (bit_buff->pos > bit_buff->end+4) - { - bit_buff->error=1; - return; /* Can't be right */ - } - bit_buff->current_byte= (bit_buff->current_byte << 32) + - ((((uint) bit_buff->pos[3])) + - (((uint) bit_buff->pos[2]) << 8) + - (((uint) bit_buff->pos[1]) << 16) + - (((uint) bit_buff->pos[0]) << 24)); - bit_buff->pos+=4; - bits+=32; - } - /* First use info in quick_table */ - low_byte=(uint) (bit_buff->current_byte >> (bits - table_bits)) & table_and; - low_byte=decode_tree->table[low_byte]; - if (low_byte & IS_CHAR) - { - *to++ = (low_byte & 255); /* Found char in quick table */ - bits-= ((low_byte >> 8) & 31); /* Remove bits used */ - } - else - { /* Map through rest of decode-table */ - pos=decode_tree->table+low_byte; - bits-=table_bits; - for (;;) - { - low_byte=(uint) (bit_buff->current_byte >> (bits-8)); - decode_bytes_test_bit(0); - decode_bytes_test_bit(1); - decode_bytes_test_bit(2); - decode_bytes_test_bit(3); - decode_bytes_test_bit(4); - decode_bytes_test_bit(5); - decode_bytes_test_bit(6); - decode_bytes_test_bit(7); - bits-=8; - } - *to++ = *pos; - } - } while (to != end); - - bit_buff->bits=bits; - return; -} - -#else - -static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, - uchar *end) -{ - reg1 uint bits,low_byte; - reg3 uint16 *pos; - reg4 uint table_bits,table_and; - MI_DECODE_TREE *decode_tree; - - decode_tree=rec->huff_tree; - bits=bit_buff->bits; /* Save in reg for quicker access */ - table_bits=decode_tree->quick_table_bits; - table_and= (1 << table_bits)-1; - - do - { - if (bits < table_bits) - { - if (bit_buff->pos > bit_buff->end+1) - { - bit_buff->error=1; - return; /* Can't be right */ - } -#if BITS_SAVED == 32 - bit_buff->current_byte= (bit_buff->current_byte << 24) + - (((uint) ((uchar) bit_buff->pos[2]))) + - (((uint) ((uchar) bit_buff->pos[1])) << 8) + - (((uint) ((uchar) bit_buff->pos[0])) << 16); - bit_buff->pos+=3; - bits+=24; -#else - if (bits) /* We must have at leasts 9 bits */ - { - bit_buff->current_byte= (bit_buff->current_byte << 8) + - (uint) ((uchar) bit_buff->pos[0]); - bit_buff->pos++; - bits+=8; - } - else - { - bit_buff->current_byte= ((uint) ((uchar) bit_buff->pos[0]) << 8) + - ((uint) ((uchar) bit_buff->pos[1])); - bit_buff->pos+=2; - bits+=16; - } -#endif - } - /* First use info in quick_table */ - low_byte=(bit_buff->current_byte >> (bits - table_bits)) & table_and; - low_byte=decode_tree->table[low_byte]; - if (low_byte & IS_CHAR) - { - *to++ = (low_byte & 255); /* Found char in quick table */ - bits-= ((low_byte >> 8) & 31); /* Remove bits used */ - } - else - { /* Map through rest of decode-table */ - pos=decode_tree->table+low_byte; - bits-=table_bits; - for (;;) - { - if (bits < 8) - { /* We don't need to check end */ -#if BITS_SAVED == 32 - bit_buff->current_byte= (bit_buff->current_byte << 24) + - (((uint) ((uchar) bit_buff->pos[2]))) + - (((uint) ((uchar) bit_buff->pos[1])) << 8) + - (((uint) ((uchar) bit_buff->pos[0])) << 16); - bit_buff->pos+=3; - bits+=24; -#else - bit_buff->current_byte= (bit_buff->current_byte << 8) + - (uint) ((uchar) bit_buff->pos[0]); - bit_buff->pos+=1; - bits+=8; -#endif - } - low_byte=(uint) (bit_buff->current_byte >> (bits-8)); - decode_bytes_test_bit(0); - decode_bytes_test_bit(1); - decode_bytes_test_bit(2); - decode_bytes_test_bit(3); - decode_bytes_test_bit(4); - decode_bytes_test_bit(5); - decode_bytes_test_bit(6); - decode_bytes_test_bit(7); - bits-=8; - } - *to++ = (uchar) *pos; - } - } while (to != end); - - bit_buff->bits=bits; - return; -} -#endif /* BIT_SAVED == 64 */ - - -static uint decode_pos(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree) -{ - uint16 *pos=decode_tree->table; - for (;;) - { - if (get_bit(bit_buff)) - pos++; - if (*pos & IS_CHAR) - return (uint) (*pos & ~IS_CHAR); - pos+= *pos; - } -} - - -int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf, - register my_off_t filepos, - my_bool skip_deleted_blocks) -{ - uint b_type; - MI_BLOCK_INFO block_info; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("_mi_read_rnd_pack_record"); - - if (filepos >= info->state->data_file_length) - { - my_errno= HA_ERR_END_OF_FILE; - goto err; - } - - if (info->opt_flag & READ_CACHE_USED) - { - if (_mi_read_cache(&info->rec_cache,(byte*) block_info.header,filepos, - share->pack.ref_length, skip_deleted_blocks)) - goto err; - b_type=_mi_pack_get_block_info(info,&block_info,-1, filepos); - } - else - b_type=_mi_pack_get_block_info(info,&block_info,info->dfile,filepos); - if (b_type) - goto err; /* Error code is already set */ -#ifndef DBUG_OFF - if (block_info.rec_len > share->max_pack_length) - { - my_errno=HA_ERR_WRONG_IN_RECORD; - goto err; - } -#endif - - if (info->opt_flag & READ_CACHE_USED) - { - if (_mi_read_cache(&info->rec_cache,(byte*) info->rec_buff, - block_info.filepos, block_info.rec_len, - skip_deleted_blocks)) - goto err; - } - else - { - if (my_read(info->dfile,(byte*) info->rec_buff + block_info.offset, - block_info.rec_len-block_info.offset, - MYF(MY_NABP))) - goto err; - } - info->packed_length=block_info.rec_len; - info->lastpos=filepos; - info->nextpos=block_info.filepos+block_info.rec_len; - info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED; - - DBUG_RETURN (_mi_pack_rec_unpack(info,buf,info->rec_buff, - block_info.rec_len)); - err: - DBUG_RETURN(my_errno); -} - - - /* Read and process header from a huff-record-file */ - -uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BLOCK_INFO *info, File file, - my_off_t filepos) -{ - uchar *header=info->header; - uint head_length,ref_length; - LINT_INIT(ref_length); - - if (file >= 0) - { - ref_length=myisam->s->pack.ref_length; - /* - We can't use my_pread() here because mi_read_rnd_pack_record assumes - position is ok - */ - VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0))); - if (my_read(file,(char*) header,ref_length,MYF(MY_NABP))) - return BLOCK_FATAL_ERROR; - DBUG_DUMP("header",(byte*) header,ref_length); - } - if (header[0] < 254) - { - info->rec_len=header[0]; - head_length=1; - } - else if (header[0] == 254) - { - info->rec_len=uint2korr(header+1); - head_length=3; - } - else - { - info->rec_len=uint3korr(header+1); - head_length=4; - } - if (myisam->s->base.blobs) - { - if (header[head_length] < 254) - { - info->blob_len=header[head_length]; - head_length++; - } - else if (header[head_length] == 254) - { - info->blob_len=uint2korr(header+head_length+1); - head_length+=3; - } - else - { - info->blob_len=uint3korr(header+head_length+1); - head_length+=4; - } - if (!(mi_alloc_rec_buff(myisam,info->rec_len + info->blob_len, - &myisam->rec_buff))) - return BLOCK_FATAL_ERROR; /* not enough memory */ - myisam->bit_buff.blob_pos=(uchar*) myisam->rec_buff+info->rec_len; - myisam->bit_buff.blob_end= myisam->bit_buff.blob_pos+info->blob_len; - myisam->blob_length=info->blob_len; - } - info->filepos=filepos+head_length; - if (file > 0) - { - info->offset=min(info->rec_len, ref_length - head_length); - memcpy(myisam->rec_buff, header+head_length, info->offset); - } - return 0; -} - - - /* rutines for bit buffer */ - /* Note buffer must be 6 byte bigger than longest row */ - -static void init_bit_buffer(MI_BIT_BUFF *bit_buff, uchar *buffer, uint length) -{ - bit_buff->pos=buffer; - bit_buff->end=buffer+length; - bit_buff->bits=bit_buff->error=0; - bit_buff->current_byte=0; /* Avoid purify errors */ -} - -static uint fill_and_get_bits(MI_BIT_BUFF *bit_buff, uint count) -{ - uint tmp; - count-=bit_buff->bits; - tmp=(bit_buff->current_byte & mask[bit_buff->bits]) << count; - fill_buffer(bit_buff); - bit_buff->bits=BITS_SAVED - count; - return tmp+(bit_buff->current_byte >> (BITS_SAVED - count)); -} - - /* Fill in empty bit_buff->current_byte from buffer */ - /* Sets bit_buff->error if buffer is exhausted */ - -static void fill_buffer(MI_BIT_BUFF *bit_buff) -{ - if (bit_buff->pos >= bit_buff->end) - { - bit_buff->error= 1; - bit_buff->current_byte=0; - return; - } -#if BITS_SAVED == 64 - bit_buff->current_byte= ((((uint) ((uchar) bit_buff->pos[7]))) + - (((uint) ((uchar) bit_buff->pos[6])) << 8) + - (((uint) ((uchar) bit_buff->pos[5])) << 16) + - (((uint) ((uchar) bit_buff->pos[4])) << 24) + - ((ulonglong) - ((((uint) ((uchar) bit_buff->pos[3]))) + - (((uint) ((uchar) bit_buff->pos[2])) << 8) + - (((uint) ((uchar) bit_buff->pos[1])) << 16) + - (((uint) ((uchar) bit_buff->pos[0])) << 24)) << 32)); - bit_buff->pos+=8; -#else -#if BITS_SAVED == 32 - bit_buff->current_byte= (((uint) ((uchar) bit_buff->pos[3])) + - (((uint) ((uchar) bit_buff->pos[2])) << 8) + - (((uint) ((uchar) bit_buff->pos[1])) << 16) + - (((uint) ((uchar) bit_buff->pos[0])) << 24)); - bit_buff->pos+=4; -#else - bit_buff->current_byte= (uint) (((uint) ((uchar) bit_buff->pos[1]))+ - (((uint) ((uchar) bit_buff->pos[0])) << 8)); - bit_buff->pos+=2; -#endif -#endif -} - - /* Get number of bits neaded to represent value */ - -static uint max_bit(register uint value) -{ - reg2 uint power=1; - - while ((value>>=1)) - power++; - return (power); -} - - -/***************************************************************************** - Some redefined functions to handle files when we are using memmap -*****************************************************************************/ -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif - -#ifdef HAVE_MMAP - -static int _mi_read_mempack_record(MI_INFO *info,my_off_t filepos,byte *buf); -static int _mi_read_rnd_mempack_record(MI_INFO*, byte *,my_off_t, my_bool); - -#ifndef MAP_NORESERVE -#define MAP_NORESERVE 0 /* For irix */ -#endif -#ifndef MAP_FAILED -#define MAP_FAILED -1 -#endif - -my_bool _mi_memmap_file(MI_INFO *info) -{ - byte *file_map; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("mi_memmap_file"); - - if (!info->s->file_map) - { - if (my_seek(info->dfile,0L,MY_SEEK_END,MYF(0)) < - share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN) - { - DBUG_PRINT("warning",("File isn't extended for memmap")); - DBUG_RETURN(0); - } - file_map=(byte*) - my_mmap(0,(size_t)(share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN),PROT_READ, - MAP_SHARED | MAP_NORESERVE,info->dfile,0L); - if (file_map == (byte*) MAP_FAILED) - { - DBUG_PRINT("warning",("mmap failed: errno: %d",errno)); - my_errno=errno; - DBUG_RETURN(0); - } - info->s->file_map=file_map; - } - info->opt_flag|= MEMMAP_USED; - info->read_record=share->read_record=_mi_read_mempack_record; - share->read_rnd=_mi_read_rnd_mempack_record; - DBUG_RETURN(1); -} - - -void _mi_unmap_file(MI_INFO *info) -{ - VOID(my_munmap(info->s->file_map, - (size_t) info->s->state.state.data_file_length+ - MEMMAP_EXTRA_MARGIN)); -} - - -static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info, - uchar *header) -{ - if (header[0] < 254) - info->rec_len= *header++; - else if (header[0] == 254) - { - info->rec_len=uint2korr(header+1); - header+=3; - } - else - { - info->rec_len=uint3korr(header+1); - header+=4; - } - if (myisam->s->base.blobs) - { - if (header[0] < 254) - { - info->blob_len= *header++; - } - else if (header[0] == 254) - { - info->blob_len=uint2korr(header+1); - header+=3; - } - else - { - info->blob_len=uint3korr(header+1); - header+=4; - } - /* mi_alloc_rec_buff sets my_errno on error */ - if (!(mi_alloc_rec_buff(myisam, info->blob_len, - &myisam->rec_buff))) - return 0; /* not enough memory */ - myisam->bit_buff.blob_pos=(uchar*) myisam->rec_buff; - myisam->bit_buff.blob_end= (uchar*) myisam->rec_buff + info->blob_len; - } - return header; -} - - -static int _mi_read_mempack_record(MI_INFO *info, my_off_t filepos, byte *buf) -{ - MI_BLOCK_INFO block_info; - MYISAM_SHARE *share=info->s; - byte *pos; - DBUG_ENTER("mi_read_mempack_record"); - - if (filepos == HA_OFFSET_ERROR) - DBUG_RETURN(-1); /* _search() didn't find record */ - - if (!(pos= (byte*) _mi_mempack_get_block_info(info,&block_info, - (uchar*) share->file_map+ - filepos))) - DBUG_RETURN(-1); - DBUG_RETURN(_mi_pack_rec_unpack(info, buf, pos, block_info.rec_len)); -} - - -/*ARGSUSED*/ -static int _mi_read_rnd_mempack_record(MI_INFO *info, byte *buf, - register my_off_t filepos, - my_bool skip_deleted_blocks - __attribute__((unused))) -{ - MI_BLOCK_INFO block_info; - MYISAM_SHARE *share=info->s; - byte *pos,*start; - DBUG_ENTER("_mi_read_rnd_mempack_record"); - - if (filepos >= share->state.state.data_file_length) - { - my_errno=HA_ERR_END_OF_FILE; - goto err; - } - if (!(pos= (byte*) _mi_mempack_get_block_info(info,&block_info, - (uchar*) - (start=share->file_map+ - filepos)))) - goto err; -#ifndef DBUG_OFF - if (block_info.rec_len > info->s->max_pack_length) - { - my_errno=HA_ERR_WRONG_IN_RECORD; - goto err; - } -#endif - info->packed_length=block_info.rec_len; - info->lastpos=filepos; - info->nextpos=filepos+(uint) (pos-start)+block_info.rec_len; - info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED; - - DBUG_RETURN (_mi_pack_rec_unpack(info,buf,pos, block_info.rec_len)); - err: - DBUG_RETURN(my_errno); -} - -#endif /* HAVE_MMAP */ - - /* Save length of row */ - -uint save_pack_length(byte *block_buff,ulong length) -{ - if (length < 254) - { - *(uchar*) block_buff= (uchar) length; - return 1; - } - if (length <= 65535) - { - *(uchar*) block_buff=254; - int2store(block_buff+1,(uint) length); - return 3; - } - *(uchar*) block_buff=255; - int3store(block_buff+1,(ulong) length); - return 4; -} diff --git a/myisam/mi_page.c b/myisam/mi_page.c deleted file mode 100644 index 5240c063fba..00000000000 --- a/myisam/mi_page.c +++ /dev/null @@ -1,160 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Read and write key blocks */ - -#include "myisamdef.h" - - /* Fetch a key-page in memory */ - -uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo, - my_off_t page, int level, - uchar *buff, int return_buffer) -{ - uchar *tmp; - uint page_size; - DBUG_ENTER("_mi_fetch_keypage"); - DBUG_PRINT("enter",("page: %ld",page)); - - tmp=(uchar*) key_cache_read(info->s->key_cache, - info->s->kfile, page, level, (byte*) buff, - (uint) keyinfo->block_length, - (uint) keyinfo->block_length, - return_buffer); - if (tmp == info->buff) - info->buff_used=1; - else if (!tmp) - { - DBUG_PRINT("error",("Got errno: %d from key_cache_read",my_errno)); - info->last_keypage=HA_OFFSET_ERROR; - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - DBUG_RETURN(0); - } - info->last_keypage=page; - page_size=mi_getint(tmp); - if (page_size < 4 || page_size > keyinfo->block_length) - { - DBUG_PRINT("error",("page %lu had wrong page length: %u", - (ulong) page, page_size)); - DBUG_DUMP("page", (char*) tmp, keyinfo->block_length); - info->last_keypage = HA_OFFSET_ERROR; - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno = HA_ERR_CRASHED; - tmp = 0; - } - DBUG_RETURN(tmp); -} /* _mi_fetch_keypage */ - - - /* Write a key-page on disk */ - -int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo, - my_off_t page, int level, uchar *buff) -{ - reg3 uint length; - DBUG_ENTER("_mi_write_keypage"); - -#ifndef FAST /* Safety check */ - if (page < info->s->base.keystart || - page+keyinfo->block_length > info->state->key_file_length || - (page & (MI_MIN_KEY_BLOCK_LENGTH-1))) - { - DBUG_PRINT("error",("Trying to write inside key status region: key_start: %lu length: %lu page: %lu", - (long) info->s->base.keystart, - (long) info->state->key_file_length, - (long) page)); - my_errno=EINVAL; - DBUG_RETURN((-1)); - } - DBUG_PRINT("page",("write page at: %lu",(long) page,buff)); - DBUG_DUMP("buff",(byte*) buff,mi_getint(buff)); -#endif - - if ((length=keyinfo->block_length) > IO_SIZE*2 && - info->state->key_file_length != page+length) - length= ((mi_getint(buff)+IO_SIZE-1) & (uint) ~(IO_SIZE-1)); -#ifdef HAVE_purify - { - length=mi_getint(buff); - bzero((byte*) buff+length,keyinfo->block_length-length); - length=keyinfo->block_length; - } -#endif - DBUG_RETURN((key_cache_write(info->s->key_cache, - info->s->kfile,page, level, (byte*) buff,length, - (uint) keyinfo->block_length, - (int) ((info->lock_type != F_UNLCK) || - info->s->delay_key_write)))); -} /* mi_write_keypage */ - - - /* Remove page from disk */ - -int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos, - int level) -{ - my_off_t old_link; - char buff[8]; - DBUG_ENTER("_mi_dispose"); - DBUG_PRINT("enter",("pos: %ld", (long) pos)); - - old_link=info->s->state.key_del[keyinfo->block_size]; - info->s->state.key_del[keyinfo->block_size]=pos; - mi_sizestore(buff,old_link); - info->s->state.changed|= STATE_NOT_SORTED_PAGES; - DBUG_RETURN(key_cache_write(info->s->key_cache, - info->s->kfile, pos , level, buff, - sizeof(buff), - (uint) keyinfo->block_length, - (int) (info->lock_type != F_UNLCK))); -} /* _mi_dispose */ - - - /* Make new page on disk */ - -my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo, int level) -{ - my_off_t pos; - char buff[8]; - DBUG_ENTER("_mi_new"); - - if ((pos=info->s->state.key_del[keyinfo->block_size]) == HA_OFFSET_ERROR) - { - if (info->state->key_file_length >= - info->s->base.max_key_file_length - keyinfo->block_length) - { - my_errno=HA_ERR_INDEX_FILE_FULL; - DBUG_RETURN(HA_OFFSET_ERROR); - } - pos=info->state->key_file_length; - info->state->key_file_length+= keyinfo->block_length; - } - else - { - if (!key_cache_read(info->s->key_cache, - info->s->kfile, pos, level, - buff, - (uint) sizeof(buff), - (uint) keyinfo->block_length,0)) - pos= HA_OFFSET_ERROR; - else - info->s->state.key_del[keyinfo->block_size]=mi_sizekorr(buff); - } - info->s->state.changed|= STATE_NOT_SORTED_PAGES; - DBUG_PRINT("exit",("Pos: %ld",(long) pos)); - DBUG_RETURN(pos); -} /* _mi_new */ diff --git a/myisam/mi_panic.c b/myisam/mi_panic.c deleted file mode 100644 index 78698d88c54..00000000000 --- a/myisam/mi_panic.c +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "fulltext.h" - - /* if flag == HA_PANIC_CLOSE then all misam files are closed */ - /* if flag == HA_PANIC_WRITE then all misam files are unlocked and - all changed data in single user misam is written to file */ - /* if flag == HA_PANIC_READ then all misam files that was locked when - mi_panic(HA_PANIC_WRITE) was done is locked. A mi_readinfo() is - done for all single user files to get changes in database */ - - -int mi_panic(enum ha_panic_function flag) -{ - int error=0; - LIST *list_element,*next_open; - MI_INFO *info; - DBUG_ENTER("mi_panic"); - - pthread_mutex_lock(&THR_LOCK_myisam); - for (list_element=myisam_open_list ; list_element ; list_element=next_open) - { - next_open=list_element->next; /* Save if close */ - info=(MI_INFO*) list_element->data; - switch (flag) { - case HA_PANIC_CLOSE: - pthread_mutex_unlock(&THR_LOCK_myisam); /* Not exactly right... */ - if (mi_close(info)) - error=my_errno; - pthread_mutex_lock(&THR_LOCK_myisam); - break; - case HA_PANIC_WRITE: /* Do this to free databases */ -#ifdef CANT_OPEN_FILES_TWICE - if (info->s->options & HA_OPTION_READ_ONLY_DATA) - break; -#endif - if (flush_key_blocks(info->s->key_cache, info->s->kfile, FLUSH_RELEASE)) - error=my_errno; - if (info->opt_flag & WRITE_CACHE_USED) - if (flush_io_cache(&info->rec_cache)) - error=my_errno; - if (info->opt_flag & READ_CACHE_USED) - { - if (flush_io_cache(&info->rec_cache)) - error=my_errno; - reinit_io_cache(&info->rec_cache,READ_CACHE,0, - (pbool) (info->lock_type != F_UNLCK),1); - } - if (info->lock_type != F_UNLCK && ! info->was_locked) - { - info->was_locked=info->lock_type; - if (mi_lock_database(info,F_UNLCK)) - error=my_errno; - } -#ifdef CANT_OPEN_FILES_TWICE - if (info->s->kfile >= 0 && my_close(info->s->kfile,MYF(0))) - error = my_errno; - if (info->dfile >= 0 && my_close(info->dfile,MYF(0))) - error = my_errno; - info->s->kfile=info->dfile= -1; /* Files aren't open anymore */ - break; -#endif - case HA_PANIC_READ: /* Restore to before WRITE */ -#ifdef CANT_OPEN_FILES_TWICE - { /* Open closed files */ - char name_buff[FN_REFLEN]; - if (info->s->kfile < 0) - if ((info->s->kfile= my_open(fn_format(name_buff,info->filename,"", - N_NAME_IEXT,4),info->mode, - MYF(MY_WME))) < 0) - error = my_errno; - if (info->dfile < 0) - { - if ((info->dfile= my_open(fn_format(name_buff,info->filename,"", - N_NAME_DEXT,4),info->mode, - MYF(MY_WME))) < 0) - error = my_errno; - info->rec_cache.file=info->dfile; - } - } -#endif - if (info->was_locked) - { - if (mi_lock_database(info, info->was_locked)) - error=my_errno; - info->was_locked=0; - } - break; - } - } - if (flag == HA_PANIC_CLOSE) - { - VOID(mi_log(0)); /* Close log if neaded */ - ft_free_stopwords(); - } - pthread_mutex_unlock(&THR_LOCK_myisam); - if (!error) - DBUG_RETURN(0); - DBUG_RETURN(my_errno=error); -} /* mi_panic */ diff --git a/myisam/mi_preload.c b/myisam/mi_preload.c deleted file mode 100644 index 317ab4ad7fe..00000000000 --- a/myisam/mi_preload.c +++ /dev/null @@ -1,118 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Preload indexes into key cache -*/ - -#include "myisamdef.h" - - -/* - Preload pages of the index file for a table into the key cache - - SYNOPSIS - mi_preload() - info open table - map map of indexes to preload into key cache - ignore_leaves only non-leaves pages are to be preloaded - - RETURN VALUE - 0 if a success. error code - otherwise. - - NOTES. - At present pages for all indexes are preloaded. - In future only pages for indexes specified in the key_map parameter - of the table will be preloaded. -*/ - -int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) -{ - uint i; - ulong length, block_length= 0; - uchar *buff= NULL; - MYISAM_SHARE* share= info->s; - uint keys= share->state.header.keys; - MI_KEYDEF *keyinfo= share->keyinfo; - my_off_t key_file_length= share->state.state.key_file_length; - my_off_t pos= share->base.keystart; - DBUG_ENTER("mi_preload"); - - if (!keys || !key_map || key_file_length == pos) - DBUG_RETURN(0); - - block_length= keyinfo[0].block_length; - - /* Check whether all indexes use the same block size */ - for (i= 1 ; i < keys ; i++) - { - if (keyinfo[i].block_length != block_length) - DBUG_RETURN(my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE); - } - - length= info->preload_buff_size/block_length * block_length; - set_if_bigger(length, block_length); - - if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME)))) - DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM); - - if (flush_key_blocks(share->key_cache,share->kfile, FLUSH_RELEASE)) - goto err; - - do - { - /* Read the next block of index file into the preload buffer */ - if ((my_off_t) length > (key_file_length-pos)) - length= (ulong) (key_file_length-pos); - if (my_pread(share->kfile, (byte*) buff, length, pos, MYF(MY_FAE|MY_FNABP))) - goto err; - - if (ignore_leaves) - { - uchar *end= buff+length; - do - { - if (mi_test_if_nod(buff)) - { - if (key_cache_insert(share->key_cache, - share->kfile, pos, DFLT_INIT_HITS, - (byte*) buff, block_length)) - goto err; - } - pos+= block_length; - } - while ((buff+= block_length) != end); - buff= end-length; - } - else - { - if (key_cache_insert(share->key_cache, - share->kfile, pos, DFLT_INIT_HITS, - (byte*) buff, length)) - goto err; - pos+= length; - } - } - while (pos != key_file_length); - - my_free((char*) buff, MYF(0)); - DBUG_RETURN(0); - -err: - my_free((char*) buff, MYF(MY_ALLOW_ZERO_PTR)); - DBUG_RETURN(my_errno= errno); -} - diff --git a/myisam/mi_range.c b/myisam/mi_range.c deleted file mode 100644 index e78f3b11625..00000000000 --- a/myisam/mi_range.c +++ /dev/null @@ -1,244 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Gives a approximated number of how many records there is between two keys. - Used when optimizing querries. - */ - -#include "myisamdef.h" -#include "rt_index.h" - -static ha_rows _mi_record_pos(MI_INFO *info,const byte *key,uint key_len, - enum ha_rkey_function search_flag); -static double _mi_search_pos(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key, - uint key_len,uint nextflag,my_off_t pos); -static uint _mi_keynr(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *page, - uchar *keypos,uint *ret_max_key); - - -/* - Estimate how many records there is in a given range - - SYNOPSIS - mi_records_in_range() - info MyISAM handler - inx Index to use - min_key Min key. Is = 0 if no min range - max_key Max key. Is = 0 if no max range - - NOTES - We should ONLY return 0 if there is no rows in range - - RETURN - HA_POS_ERROR error (or we can't estimate number of rows) - number Estimated number of rows -*/ - - -ha_rows mi_records_in_range(MI_INFO *info, int inx, key_range *min_key, - key_range *max_key) -{ - ha_rows start_pos,end_pos,res; - DBUG_ENTER("mi_records_in_range"); - - if ((inx = _mi_check_index(info,inx)) < 0) - DBUG_RETURN(HA_POS_ERROR); - - if (fast_mi_readinfo(info)) - DBUG_RETURN(HA_POS_ERROR); - info->update&= (HA_STATE_CHANGED+HA_STATE_ROW_CHANGED); - if (info->s->concurrent_insert) - rw_rdlock(&info->s->key_root_lock[inx]); - - switch(info->s->keyinfo[inx].key_alg){ -#ifdef HAVE_RTREE_KEYS - case HA_KEY_ALG_RTREE: - { - uchar * key_buff; - uint start_key_len; - - key_buff= info->lastkey+info->s->base.max_key_length; - start_key_len= _mi_pack_key(info,inx, key_buff, - (uchar*) min_key->key, min_key->length, - (HA_KEYSEG**) 0); - res= rtree_estimate(info, inx, key_buff, start_key_len, - myisam_read_vec[min_key->flag]); - res= res ? res : 1; /* Don't return 0 */ - break; - } -#endif - case HA_KEY_ALG_BTREE: - default: - start_pos= (min_key ? - _mi_record_pos(info, min_key->key, min_key->length, - min_key->flag) : - (ha_rows) 0); - end_pos= (max_key ? - _mi_record_pos(info, max_key->key, max_key->length, - max_key->flag) : - info->state->records+ (ha_rows) 1); - res= (end_pos < start_pos ? (ha_rows) 0 : - (end_pos == start_pos ? (ha_rows) 1 : end_pos-start_pos)); - if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR) - res=HA_POS_ERROR; - } - - if (info->s->concurrent_insert) - rw_unlock(&info->s->key_root_lock[inx]); - fast_mi_writeinfo(info); - - DBUG_PRINT("info",("records: %ld",(ulong) (res))); - DBUG_RETURN(res); -} - - - /* Find relative position (in records) for key in index-tree */ - -static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len, - enum ha_rkey_function search_flag) -{ - uint inx=(uint) info->lastinx, nextflag; - MI_KEYDEF *keyinfo=info->s->keyinfo+inx; - uchar *key_buff; - double pos; - - DBUG_ENTER("_mi_record_pos"); - DBUG_PRINT("enter",("search_flag: %d",search_flag)); - - if (key_len == 0) - key_len=USE_WHOLE_KEY; - key_buff=info->lastkey+info->s->base.max_key_length; - key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key,key_len, - (HA_KEYSEG**) 0); - DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg, - (uchar*) key_buff,key_len);); - nextflag=myisam_read_vec[search_flag]; - if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST))) - key_len=USE_WHOLE_KEY; - - pos=_mi_search_pos(info,keyinfo,key_buff,key_len, - nextflag | SEARCH_SAVE_BUFF, - info->s->state.key_root[inx]); - if (pos >= 0.0) - { - DBUG_PRINT("exit",("pos: %ld",(ulong) (pos*info->state->records))); - DBUG_RETURN((ulong) (pos*info->state->records+0.5)); - } - DBUG_RETURN(HA_POS_ERROR); -} - - - /* This is a modified version of _mi_search */ - /* Returns offset for key in indextable (decimal 0.0 <= x <= 1.0) */ - -static double _mi_search_pos(register MI_INFO *info, - register MI_KEYDEF *keyinfo, - uchar *key, uint key_len, uint nextflag, - register my_off_t pos) -{ - int flag; - uint nod_flag,keynr,max_keynr; - my_bool after_key; - uchar *keypos,*buff; - double offset; - DBUG_ENTER("_mi_search_pos"); - - if (pos == HA_OFFSET_ERROR) - DBUG_RETURN(0.5); - - if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,1))) - goto err; - flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag, - &keypos,info->lastkey, &after_key); - nod_flag=mi_test_if_nod(buff); - keynr=_mi_keynr(info,keyinfo,buff,keypos,&max_keynr); - - if (flag) - { - if (flag == MI_FOUND_WRONG_KEY) - DBUG_RETURN(-1); /* error */ - /* - Didn't found match. keypos points at next (bigger) key - Try to find a smaller, better matching key. - Matches keynr + [0-1] - */ - if (flag > 0 && ! nod_flag) - offset= 1.0; - else if ((offset=_mi_search_pos(info,keyinfo,key,key_len,nextflag, - _mi_kpos(nod_flag,keypos))) < 0) - DBUG_RETURN(offset); - } - else - { - /* - Found match. Keypos points at the start of the found key - Matches keynr+1 - */ - offset=1.0; /* Matches keynr+1 */ - if ((nextflag & SEARCH_FIND) && nod_flag && - ((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME || - key_len != USE_WHOLE_KEY)) - { - /* - There may be identical keys in the tree. Try to match on of those. - Matches keynr + [0-1] - */ - if ((offset=_mi_search_pos(info,keyinfo,key,key_len,SEARCH_FIND, - _mi_kpos(nod_flag,keypos))) < 0) - DBUG_RETURN(offset); /* Read error */ - } - } - DBUG_PRINT("info",("keynr: %d offset: %g max_keynr: %d nod: %d flag: %d", - keynr,offset,max_keynr,nod_flag,flag)); - DBUG_RETURN((keynr+offset)/(max_keynr+1)); -err: - DBUG_PRINT("exit",("Error: %d",my_errno)); - DBUG_RETURN (-1.0); -} - - - /* Get keynummer of current key and max number of keys in nod */ - -static uint _mi_keynr(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, - uchar *keypos, uint *ret_max_key) -{ - uint nod_flag,keynr,max_key; - uchar t_buff[MI_MAX_KEY_BUFF],*end; - - end= page+mi_getint(page); - nod_flag=mi_test_if_nod(page); - page+=2+nod_flag; - - if (!(keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY))) - { - *ret_max_key= (uint) (end-page)/(keyinfo->keylength+nod_flag); - return (uint) (keypos-page)/(keyinfo->keylength+nod_flag); - } - - max_key=keynr=0; - t_buff[0]=0; /* Safety */ - while (page < end) - { - if (!(*keyinfo->get_key)(keyinfo,nod_flag,&page,t_buff)) - return 0; /* Error */ - max_key++; - if (page == keypos) - keynr=max_key; - } - *ret_max_key=max_key; - return(keynr); -} diff --git a/myisam/mi_rename.c b/myisam/mi_rename.c deleted file mode 100644 index 8380ee1bfad..00000000000 --- a/myisam/mi_rename.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Rename a table -*/ - -#include "fulltext.h" - -int mi_rename(const char *old_name, const char *new_name) -{ - char from[FN_REFLEN],to[FN_REFLEN]; -#ifdef USE_RAID - uint raid_type=0,raid_chunks=0; -#endif - DBUG_ENTER("mi_rename"); - -#ifdef EXTRA_DEBUG - check_table_is_closed(old_name,"rename old_table"); - check_table_is_closed(new_name,"rename new table2"); -#endif -#ifdef USE_RAID - { - MI_INFO *info; - if (!(info=mi_open(old_name, O_RDONLY, 0))) - DBUG_RETURN(my_errno); - raid_type = info->s->base.raid_type; - raid_chunks = info->s->base.raid_chunks; - mi_close(info); - } -#ifdef EXTRA_DEBUG - check_table_is_closed(old_name,"rename raidcheck"); -#endif -#endif /* USE_RAID */ - - fn_format(from,old_name,"",MI_NAME_IEXT,4); - fn_format(to,new_name,"",MI_NAME_IEXT,4); - if (my_rename_with_symlink(from, to, MYF(MY_WME))) - DBUG_RETURN(my_errno); - fn_format(from,old_name,"",MI_NAME_DEXT,4); - fn_format(to,new_name,"",MI_NAME_DEXT,4); -#ifdef USE_RAID - if (raid_type) - DBUG_RETURN(my_raid_rename(from, to, raid_chunks, MYF(MY_WME)) ? my_errno : - 0); -#endif - DBUG_RETURN(my_rename_with_symlink(from, to,MYF(MY_WME)) ? my_errno : 0); -} diff --git a/myisam/mi_rfirst.c b/myisam/mi_rfirst.c deleted file mode 100644 index e30f61801a0..00000000000 --- a/myisam/mi_rfirst.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "myisamdef.h" - - /* Read first row through a specfic key */ - -int mi_rfirst(MI_INFO *info, byte *buf, int inx) -{ - DBUG_ENTER("mi_rfirst"); - info->lastpos= HA_OFFSET_ERROR; - info->update|= HA_STATE_PREV_FOUND; - DBUG_RETURN(mi_rnext(info,buf,inx)); -} /* mi_rfirst */ diff --git a/myisam/mi_rkey.c b/myisam/mi_rkey.c deleted file mode 100644 index 635a7eb2c48..00000000000 --- a/myisam/mi_rkey.c +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Read record based on a key */ - -#include "myisamdef.h" -#include "rt_index.h" - - /* Read a record using key */ - /* Ordinary search_flag is 0 ; Give error if no record with key */ - -int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, - enum ha_rkey_function search_flag) -{ - uchar *key_buff; - MYISAM_SHARE *share=info->s; - MI_KEYDEF *keyinfo; - HA_KEYSEG *last_used_keyseg; - uint pack_key_length, use_key_length, nextflag; - DBUG_ENTER("mi_rkey"); - DBUG_PRINT("enter",("base: %lx inx: %d search_flag: %d", - info,inx,search_flag)); - - if ((inx = _mi_check_index(info,inx)) < 0) - DBUG_RETURN(my_errno); - - info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - info->last_key_func= search_flag; - keyinfo= share->keyinfo + inx; - - if (info->once_flags & USE_PACKED_KEYS) - { - info->once_flags&= ~USE_PACKED_KEYS; /* Reset flag */ - /* - key is already packed!; This happens when we are using a MERGE TABLE - */ - key_buff=info->lastkey+info->s->base.max_key_length; - pack_key_length= key_len; - bmove(key_buff,key,key_len); - last_used_keyseg= 0; - } - else - { - if (key_len == 0) - key_len=USE_WHOLE_KEY; - key_buff=info->lastkey+info->s->base.max_key_length; - pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (uchar*) key, - key_len, &last_used_keyseg); - DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg, - key_buff, pack_key_length);); - } - - if (fast_mi_readinfo(info)) - goto err; - if (share->concurrent_insert) - rw_rdlock(&share->key_root_lock[inx]); - - nextflag=myisam_read_vec[search_flag]; - use_key_length=pack_key_length; - if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST))) - use_key_length=USE_WHOLE_KEY; - - switch (info->s->keyinfo[inx].key_alg) { -#ifdef HAVE_RTREE_KEYS - case HA_KEY_ALG_RTREE: - if (rtree_find_first(info,inx,key_buff,use_key_length,nextflag) < 0) - { - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - goto err; - } - break; -#endif - case HA_KEY_ALG_BTREE: - default: - if (!_mi_search(info, keyinfo, key_buff, use_key_length, - myisam_read_vec[search_flag], info->s->state.key_root[inx])) - { - while (info->lastpos >= info->state->data_file_length) - { - /* - Skip rows that are inserted by other threads since we got a lock - Note that this can only happen if we are not searching after an - exact key, because the keys are sorted according to position - */ - - if (_mi_search_next(info, keyinfo, info->lastkey, - info->lastkey_length, - myisam_readnext_vec[search_flag], - info->s->state.key_root[inx])) - break; - } - } - } - if (share->concurrent_insert) - rw_unlock(&share->key_root_lock[inx]); - - /* Calculate length of the found key; Used by mi_rnext_same */ - if ((keyinfo->flag & HA_VAR_LENGTH_KEY) && last_used_keyseg && - info->lastpos != HA_OFFSET_ERROR) - info->last_rkey_length= _mi_keylength_part(keyinfo, info->lastkey, - last_used_keyseg); - else - info->last_rkey_length= pack_key_length; - - /* Check if we don't want to have record back, only error message */ - if (!buf) - DBUG_RETURN(info->lastpos == HA_OFFSET_ERROR ? my_errno : 0); - - if (!(*info->read_record)(info,info->lastpos,buf)) - { - info->update|= HA_STATE_AKTIV; /* Record is read */ - DBUG_RETURN(0); - } - - info->lastpos = HA_OFFSET_ERROR; /* Didn't find key */ - - /* Store last used key as a base for read next */ - memcpy(info->lastkey,key_buff,pack_key_length); - info->last_rkey_length= pack_key_length; - bzero((char*) info->lastkey+pack_key_length,info->s->base.rec_reflength); - info->lastkey_length=pack_key_length+info->s->base.rec_reflength; - - if (search_flag == HA_READ_AFTER_KEY) - info->update|=HA_STATE_NEXT_FOUND; /* Previous gives last row */ -err: - DBUG_RETURN(my_errno); -} /* _mi_rkey */ diff --git a/myisam/mi_rlast.c b/myisam/mi_rlast.c deleted file mode 100644 index 61c3ff58fd5..00000000000 --- a/myisam/mi_rlast.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "myisamdef.h" - - /* Read last row with the same key as the previous read. */ - -int mi_rlast(MI_INFO *info, byte *buf, int inx) -{ - DBUG_ENTER("mi_rlast"); - info->lastpos= HA_OFFSET_ERROR; - info->update|= HA_STATE_NEXT_FOUND; - DBUG_RETURN(mi_rprev(info,buf,inx)); -} /* mi_rlast */ diff --git a/myisam/mi_rnext.c b/myisam/mi_rnext.c deleted file mode 100644 index 69bf5c8deae..00000000000 --- a/myisam/mi_rnext.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "myisamdef.h" - -#include "rt_index.h" - - /* - Read next row with the same key as previous read - One may have done a write, update or delete of the previous row. - NOTE! Even if one changes the previous row, the next read is done - based on the position of the last used key! - */ - -int mi_rnext(MI_INFO *info, byte *buf, int inx) -{ - int error,changed; - uint flag; - DBUG_ENTER("mi_rnext"); - - if ((inx = _mi_check_index(info,inx)) < 0) - DBUG_RETURN(my_errno); - flag=SEARCH_BIGGER; /* Read next */ - if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_PREV_FOUND) - flag=0; /* Read first */ - - if (fast_mi_readinfo(info)) - DBUG_RETURN(my_errno); - if (info->s->concurrent_insert) - rw_rdlock(&info->s->key_root_lock[inx]); - changed=_mi_test_if_changed(info); - if (!flag) - { - switch(info->s->keyinfo[inx].key_alg){ -#ifdef HAVE_RTREE_KEYS - case HA_KEY_ALG_RTREE: - error=rtree_get_first(info,inx,info->lastkey_length); - break; -#endif - case HA_KEY_ALG_BTREE: - default: - error=_mi_search_first(info,info->s->keyinfo+inx, - info->s->state.key_root[inx]); - break; - } - } - else - { - switch (info->s->keyinfo[inx].key_alg) { -#ifdef HAVE_RTREE_KEYS - case HA_KEY_ALG_RTREE: - /* - Note that rtree doesn't support that the table - may be changed since last call, so we do need - to skip rows inserted by other threads like in btree - */ - error= rtree_get_next(info,inx,info->lastkey_length); - break; -#endif - case HA_KEY_ALG_BTREE: - default: - if (!changed) - error= _mi_search_next(info,info->s->keyinfo+inx,info->lastkey, - info->lastkey_length,flag, - info->s->state.key_root[inx]); - else - error= _mi_search(info,info->s->keyinfo+inx,info->lastkey, - USE_WHOLE_KEY,flag, info->s->state.key_root[inx]); - } - } - - if (info->s->concurrent_insert) - { - if (!error) - { - while (info->lastpos >= info->state->data_file_length) - { - /* Skip rows inserted by other threads since we got a lock */ - if ((error=_mi_search_next(info,info->s->keyinfo+inx, - info->lastkey, - info->lastkey_length, - SEARCH_BIGGER, - info->s->state.key_root[inx]))) - break; - } - } - rw_unlock(&info->s->key_root_lock[inx]); - } - /* Don't clear if database-changed */ - info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - info->update|= HA_STATE_NEXT_FOUND; - - if (error) - { - if (my_errno == HA_ERR_KEY_NOT_FOUND) - my_errno=HA_ERR_END_OF_FILE; - } - else if (!buf) - { - DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0); - } - else if (!(*info->read_record)(info,info->lastpos,buf)) - { - info->update|= HA_STATE_AKTIV; /* Record is read */ - DBUG_RETURN(0); - } - DBUG_PRINT("error",("Got error: %d, errno: %d",error, my_errno)); - DBUG_RETURN(my_errno); -} /* mi_rnext */ diff --git a/myisam/mi_rnext_same.c b/myisam/mi_rnext_same.c deleted file mode 100644 index 06408f57a3f..00000000000 --- a/myisam/mi_rnext_same.c +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "myisamdef.h" -#include "rt_index.h" - - /* - Read next row with the same key as previous read, but abort if - the key changes. - One may have done a write, update or delete of the previous row. - NOTE! Even if one changes the previous row, the next read is done - based on the position of the last used key! - */ - -int mi_rnext_same(MI_INFO *info, byte *buf) -{ - int error; - uint inx,not_used; - MI_KEYDEF *keyinfo; - DBUG_ENTER("mi_rnext_same"); - - if ((int) (inx=info->lastinx) < 0 || info->lastpos == HA_OFFSET_ERROR) - DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); - keyinfo=info->s->keyinfo+inx; - if (fast_mi_readinfo(info)) - DBUG_RETURN(my_errno); - - if (info->s->concurrent_insert) - rw_rdlock(&info->s->key_root_lock[inx]); - - switch (keyinfo->key_alg) - { -#ifdef HAVE_RTREE_KEYS - case HA_KEY_ALG_RTREE: - if ((error=rtree_find_next(info,inx, - myisam_read_vec[info->last_key_func]))) - { - error=1; - my_errno=HA_ERR_END_OF_FILE; - info->lastpos= HA_OFFSET_ERROR; - break; - } - break; -#endif - case HA_KEY_ALG_BTREE: - default: - if (!(info->update & HA_STATE_RNEXT_SAME)) - { - /* First rnext_same; Store old key */ - memcpy(info->lastkey2,info->lastkey,info->last_rkey_length); - } - for (;;) - { - if ((error=_mi_search_next(info,keyinfo,info->lastkey, - info->lastkey_length,SEARCH_BIGGER, - info->s->state.key_root[inx]))) - break; - if (ha_key_cmp(keyinfo->seg,info->lastkey2,info->lastkey, - info->last_rkey_length, SEARCH_FIND, ¬_used)) - { - error=1; - my_errno=HA_ERR_END_OF_FILE; - info->lastpos= HA_OFFSET_ERROR; - break; - } - /* Skip rows that are inserted by other threads since we got a lock */ - if (info->lastpos < info->state->data_file_length) - break; - } - } - if (info->s->concurrent_insert) - rw_unlock(&info->s->key_root_lock[inx]); - /* Don't clear if database-changed */ - info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - info->update|= HA_STATE_NEXT_FOUND | HA_STATE_RNEXT_SAME; - - if (error) - { - if (my_errno == HA_ERR_KEY_NOT_FOUND) - my_errno=HA_ERR_END_OF_FILE; - } - else if (!buf) - { - DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0); - } - else if (!(*info->read_record)(info,info->lastpos,buf)) - { - info->update|= HA_STATE_AKTIV; /* Record is read */ - DBUG_RETURN(0); - } - DBUG_RETURN(my_errno); -} /* mi_rnext */ diff --git a/myisam/mi_rprev.c b/myisam/mi_rprev.c deleted file mode 100644 index b787210e037..00000000000 --- a/myisam/mi_rprev.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "myisamdef.h" - - /* - Read previous row with the same key as previous read - One may have done a write, update or delete of the previous row. - NOTE! Even if one changes the previous row, the next read is done - based on the position of the last used key! - */ - -int mi_rprev(MI_INFO *info, byte *buf, int inx) -{ - int error,changed; - register uint flag; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("mi_rprev"); - - if ((inx = _mi_check_index(info,inx)) < 0) - DBUG_RETURN(my_errno); - flag=SEARCH_SMALLER; /* Read previous */ - if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_NEXT_FOUND) - flag=0; /* Read last */ - - if (fast_mi_readinfo(info)) - DBUG_RETURN(my_errno); - changed=_mi_test_if_changed(info); - if (share->concurrent_insert) - rw_rdlock(&share->key_root_lock[inx]); - if (!flag) - error=_mi_search_last(info, share->keyinfo+inx, - share->state.key_root[inx]); - else if (!changed) - error=_mi_search_next(info,share->keyinfo+inx,info->lastkey, - info->lastkey_length,flag, - share->state.key_root[inx]); - else - error=_mi_search(info,share->keyinfo+inx,info->lastkey, - USE_WHOLE_KEY, flag, share->state.key_root[inx]); - - if (share->concurrent_insert) - { - if (!error) - { - while (info->lastpos >= info->state->data_file_length) - { - /* Skip rows that are inserted by other threads since we got a lock */ - if ((error=_mi_search_next(info,share->keyinfo+inx,info->lastkey, - info->lastkey_length, - SEARCH_SMALLER, - share->state.key_root[inx]))) - break; - } - } - rw_unlock(&share->key_root_lock[inx]); - } - info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - info->update|= HA_STATE_PREV_FOUND; - if (error) - { - if (my_errno == HA_ERR_KEY_NOT_FOUND) - my_errno=HA_ERR_END_OF_FILE; - } - else if (!buf) - { - DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0); - } - else if (!(*info->read_record)(info,info->lastpos,buf)) - { - info->update|= HA_STATE_AKTIV; /* Record is read */ - DBUG_RETURN(0); - } - DBUG_RETURN(my_errno); -} /* mi_rprev */ diff --git a/myisam/mi_rrnd.c b/myisam/mi_rrnd.c deleted file mode 100644 index f6a2f021662..00000000000 --- a/myisam/mi_rrnd.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Read a record with random-access. The position to the record must - get by MI_INFO. The next record can be read with pos= MI_POS_ERROR */ - - -#include "myisamdef.h" - -/* - Read a row based on position. - If filepos= HA_OFFSET_ERROR then read next row - Return values - Returns one of following values: - 0 = Ok. - HA_ERR_RECORD_DELETED = Record is deleted. - HA_ERR_END_OF_FILE = EOF. -*/ - -int mi_rrnd(MI_INFO *info, byte *buf, register my_off_t filepos) -{ - my_bool skip_deleted_blocks; - DBUG_ENTER("mi_rrnd"); - - skip_deleted_blocks=0; - - if (filepos == HA_OFFSET_ERROR) - { - skip_deleted_blocks=1; - if (info->lastpos == HA_OFFSET_ERROR) /* First read ? */ - filepos= info->s->pack.header_length; /* Read first record */ - else - filepos= info->nextpos; - } - - if (info->once_flags & RRND_PRESERVE_LASTINX) - info->once_flags&= ~RRND_PRESERVE_LASTINX; - else - info->lastinx= -1; /* Can't forward or backward */ - /* Init all but update-flag */ - info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - - if (info->opt_flag & WRITE_CACHE_USED && flush_io_cache(&info->rec_cache)) - DBUG_RETURN(my_errno); - - DBUG_RETURN ((*info->s->read_rnd)(info,buf,filepos,skip_deleted_blocks)); -} diff --git a/myisam/mi_rsame.c b/myisam/mi_rsame.c deleted file mode 100644 index 56c8d1226ca..00000000000 --- a/myisam/mi_rsame.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "myisamdef.h" - - /* - ** Find current row with read on position or read on key - ** If inx >= 0 find record using key - ** Return values: - ** 0 = Ok. - ** HA_ERR_KEY_NOT_FOUND = Row is deleted - ** HA_ERR_END_OF_FILE = End of file - */ - - -int mi_rsame(MI_INFO *info, byte *record, int inx) -{ - DBUG_ENTER("mi_rsame"); - - if (inx != -1 && ! (((ulonglong) 1 << inx) & info->s->state.key_map)) - { - DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); - } - if (info->lastpos == HA_OFFSET_ERROR || info->update & HA_STATE_DELETED) - { - DBUG_RETURN(my_errno=HA_ERR_KEY_NOT_FOUND); /* No current record */ - } - info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - - /* Read row from data file */ - if (fast_mi_readinfo(info)) - DBUG_RETURN(my_errno); - - if (inx >= 0) - { - info->lastinx=inx; - info->lastkey_length=_mi_make_key(info,(uint) inx,info->lastkey,record, - info->lastpos); - if (info->s->concurrent_insert) - rw_rdlock(&info->s->key_root_lock[inx]); - VOID(_mi_search(info,info->s->keyinfo+inx,info->lastkey, USE_WHOLE_KEY, - SEARCH_SAME, - info->s->state.key_root[inx])); - if (info->s->concurrent_insert) - rw_unlock(&info->s->key_root_lock[inx]); - } - - if (!(*info->read_record)(info,info->lastpos,record)) - DBUG_RETURN(0); - if (my_errno == HA_ERR_RECORD_DELETED) - my_errno=HA_ERR_KEY_NOT_FOUND; - DBUG_RETURN(my_errno); -} /* mi_rsame */ diff --git a/myisam/mi_rsamepos.c b/myisam/mi_rsamepos.c deleted file mode 100644 index a1d96fb7104..00000000000 --- a/myisam/mi_rsamepos.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* read record through position and fix key-position */ -/* As mi_rsame but supply a position */ - -#include "myisamdef.h" - - - /* - ** If inx >= 0 update index pointer - ** Returns one of the following values: - ** 0 = Ok. - ** HA_ERR_KEY_NOT_FOUND = Row is deleted - ** HA_ERR_END_OF_FILE = End of file - */ - -int mi_rsame_with_pos(MI_INFO *info, byte *record, int inx, my_off_t filepos) -{ - DBUG_ENTER("mi_rsame_with_pos"); - - if (inx < -1 || ! (((ulonglong) 1 << inx) & info->s->state.key_map)) - { - DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); - } - - info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - if ((*info->s->read_rnd)(info,record,filepos,0)) - { - if (my_errno == HA_ERR_RECORD_DELETED) - my_errno=HA_ERR_KEY_NOT_FOUND; - DBUG_RETURN(my_errno); - } - info->lastpos=filepos; - info->lastinx=inx; - if (inx >= 0) - { - info->lastkey_length=_mi_make_key(info,(uint) inx,info->lastkey,record, - info->lastpos); - info->update|=HA_STATE_KEY_CHANGED; /* Don't use indexposition */ - } - DBUG_RETURN(0); -} /* mi_rsame_pos */ diff --git a/myisam/mi_scan.c b/myisam/mi_scan.c deleted file mode 100644 index 90bc3430ba7..00000000000 --- a/myisam/mi_scan.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Read through all rows sequntially */ - -#include "myisamdef.h" - -int mi_scan_init(register MI_INFO *info) -{ - DBUG_ENTER("mi_scan_init"); - info->nextpos=info->s->pack.header_length; /* Read first record */ - info->lastinx= -1; /* Can't forward or backward */ - if (info->opt_flag & WRITE_CACHE_USED && flush_io_cache(&info->rec_cache)) - DBUG_RETURN(my_errno); - DBUG_RETURN(0); -} - -/* - Read a row based on position. - If filepos= HA_OFFSET_ERROR then read next row - Return values - Returns one of following values: - 0 = Ok. - HA_ERR_END_OF_FILE = EOF. -*/ - -int mi_scan(MI_INFO *info, byte *buf) -{ - DBUG_ENTER("mi_scan"); - /* Init all but update-flag */ - info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - DBUG_RETURN ((*info->s->read_rnd)(info,buf,info->nextpos,1)); -} diff --git a/myisam/mi_search.c b/myisam/mi_search.c deleted file mode 100644 index 0c82a4c4502..00000000000 --- a/myisam/mi_search.c +++ /dev/null @@ -1,1829 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* key handling functions */ - -#include "fulltext.h" -#include "m_ctype.h" - -static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, - uchar *key, uchar *keypos, - uint *return_key_length); - - /* Check index */ - -int _mi_check_index(MI_INFO *info, int inx) -{ - if (inx == -1) /* Use last index */ - inx=info->lastinx; - if (inx < 0 || ! (((ulonglong) 1 << inx) & info->s->state.key_map)) - { - my_errno=HA_ERR_WRONG_INDEX; - return -1; - } - if (info->lastinx != inx) /* Index changed */ - { - info->lastinx = inx; - info->page_changed=1; - info->update= ((info->update & (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED)) | - HA_STATE_NEXT_FOUND | HA_STATE_PREV_FOUND); - } - if (info->opt_flag & WRITE_CACHE_USED && flush_io_cache(&info->rec_cache)) - return(-1); - return(inx); -} /* mi_check_index */ - - - /* - ** Search after row by a key - ** Position to row is stored in info->lastpos - ** Return: -1 if not found - ** 1 if one should continue search on higher level - */ - -int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, - uchar *key, uint key_len, uint nextflag, register my_off_t pos) -{ - my_bool last_key; - int error,flag; - uint nod_flag; - uchar *keypos,*maxpos; - uchar lastkey[MI_MAX_KEY_BUFF],*buff; - DBUG_ENTER("_mi_search"); - DBUG_PRINT("enter",("pos: %lu nextflag: %u lastpos: %lu", - (ulong) pos, nextflag, (ulong) info->lastpos)); - DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_len);); - - if (pos == HA_OFFSET_ERROR) - { - my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */ - info->lastpos= HA_OFFSET_ERROR; - if (!(nextflag & (SEARCH_SMALLER | SEARCH_BIGGER | SEARCH_LAST))) - DBUG_RETURN(-1); /* Not found ; return error */ - DBUG_RETURN(1); /* Search at upper levels */ - } - - if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff, - test(!(nextflag & SEARCH_SAVE_BUFF))))) - goto err; - DBUG_DUMP("page",(byte*) buff,mi_getint(buff)); - - flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag, - &keypos,lastkey, &last_key); - if (flag == MI_FOUND_WRONG_KEY) - DBUG_RETURN(-1); - nod_flag=mi_test_if_nod(buff); - maxpos=buff+mi_getint(buff)-1; - - if (flag) - { - if ((error=_mi_search(info,keyinfo,key,key_len,nextflag, - _mi_kpos(nod_flag,keypos))) <= 0) - DBUG_RETURN(error); - - if (flag >0) - { - if (nextflag & (SEARCH_SMALLER | SEARCH_LAST) && - keypos == buff+2+nod_flag) - DBUG_RETURN(1); /* Bigger than key */ - } - else if (nextflag & SEARCH_BIGGER && keypos >= maxpos) - DBUG_RETURN(1); /* Smaller than key */ - } - else - { - if ((nextflag & SEARCH_FIND) && nod_flag && - ((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME || - key_len != USE_WHOLE_KEY)) - { - if ((error=_mi_search(info,keyinfo,key,key_len,SEARCH_FIND, - _mi_kpos(nod_flag,keypos))) >= 0 || - my_errno != HA_ERR_KEY_NOT_FOUND) - DBUG_RETURN(error); - info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in mem */ - } - } - if (pos != info->last_keypage) - { - uchar *old_buff=buff; - if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff, - test(!(nextflag & SEARCH_SAVE_BUFF))))) - goto err; - keypos=buff+(keypos-old_buff); - maxpos=buff+(maxpos-old_buff); - } - - if ((nextflag & (SEARCH_SMALLER | SEARCH_LAST)) && flag != 0) - { - uint not_used; - if (_mi_get_prev_key(info,keyinfo, buff, info->lastkey, keypos, - &info->lastkey_length)) - goto err; - if (!(nextflag & SEARCH_SMALLER) && - ha_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND, - ¬_used)) - { - my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */ - goto err; - } - } - else - { - info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,lastkey); - if (!info->lastkey_length) - goto err; - memcpy(info->lastkey,lastkey,info->lastkey_length); - } - info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length); - /* Save position for a possible read next / previous */ - info->int_keypos=info->buff+ (keypos-buff); - info->int_maxpos=info->buff+ (maxpos-buff); - info->int_nod_flag=nod_flag; - info->int_keytree_version=keyinfo->version; - info->last_search_keypage=info->last_keypage; - info->page_changed=0; - info->buff_used= (info->buff != buff); /* If we have to reread buff */ - - DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos)); - DBUG_RETURN(0); - -err: - DBUG_PRINT("exit",("Error: %d",my_errno)); - info->lastpos= HA_OFFSET_ERROR; - info->page_changed=1; - DBUG_RETURN (-1); -} /* _mi_search */ - - - /* Search after key in page-block */ - /* If packed key puts smaller or identical key in buff */ - /* ret_pos point to where find or bigger key starts */ - /* ARGSUSED */ - -int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, - uchar *key, uint key_len, uint comp_flag, uchar **ret_pos, - uchar *buff __attribute__((unused)), my_bool *last_key) -{ - reg4 int start,mid,end,save_end; - int flag; - uint totlength,nod_flag,not_used; - DBUG_ENTER("_mi_bin_search"); - - LINT_INIT(flag); - totlength=keyinfo->keylength+(nod_flag=mi_test_if_nod(page)); - start=0; mid=1; - save_end=end=(int) ((mi_getint(page)-2-nod_flag)/totlength-1); - DBUG_PRINT("test",("mi_getint: %d end: %d",mi_getint(page),end)); - page+=2+nod_flag; - - while (start != end) - { - mid= (start+end)/2; - if ((flag=ha_key_cmp(keyinfo->seg,page+(uint) mid*totlength,key,key_len, - comp_flag,¬_used)) - >= 0) - end=mid; - else - start=mid+1; - } - if (mid != start) - flag=ha_key_cmp(keyinfo->seg,page+(uint) start*totlength,key,key_len, - comp_flag,¬_used); - if (flag < 0) - start++; /* point at next, bigger key */ - *ret_pos=page+(uint) start*totlength; - *last_key= end == save_end; - DBUG_PRINT("exit",("flag: %d keypos: %d",flag,start)); - DBUG_RETURN(flag); -} /* _mi_bin_search */ - - - /* Used instead of _mi_bin_search() when key is packed */ - /* Puts smaller or identical key in buff */ - /* Key is searched sequentially */ - -int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, - uchar *key, uint key_len, uint comp_flag, uchar **ret_pos, - uchar *buff, my_bool *last_key) -{ - int flag; - uint nod_flag,length,not_used; - uchar t_buff[MI_MAX_KEY_BUFF],*end; - DBUG_ENTER("_mi_seq_search"); - - LINT_INIT(flag); LINT_INIT(length); - end= page+mi_getint(page); - nod_flag=mi_test_if_nod(page); - page+=2+nod_flag; - *ret_pos=page; - t_buff[0]=0; /* Avoid bugs */ - while (page < end) - { - length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,t_buff); - if (length == 0 || page > end) - { - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - DBUG_PRINT("error",("Found wrong key: length: %u page: %p end: %p", - length, page, end)); - DBUG_RETURN(MI_FOUND_WRONG_KEY); - } - if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag, - ¬_used)) >= 0) - break; -#ifdef EXTRA_DEBUG - DBUG_PRINT("loop",("page: %p key: '%s' flag: %d", page, t_buff, flag)); -#endif - memcpy(buff,t_buff,length); - *ret_pos=page; - } - if (flag == 0) - memcpy(buff,t_buff,length); /* Result is first key */ - *last_key= page == end; - DBUG_PRINT("exit",("flag: %d ret_pos: %p", flag, *ret_pos)); - DBUG_RETURN(flag); -} /* _mi_seq_search */ - - -int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, - uchar *key, uint key_len, uint nextflag, uchar **ret_pos, - uchar *buff, my_bool *last_key) -{ - /* - my_flag is raw comparison result to be changed according to - SEARCH_NO_FIND,SEARCH_LAST and HA_REVERSE_SORT flags. - flag is the value returned by ha_key_cmp and as treated as final - */ - int flag=0, my_flag=-1; - uint nod_flag, length, len, matched, cmplen, kseg_len; - uint prefix_len,suffix_len; - int key_len_skip, seg_len_pack, key_len_left; - uchar *end, *kseg, *vseg; - uchar *sort_order=keyinfo->seg->charset->sort_order; - uchar tt_buff[MI_MAX_KEY_BUFF+2], *t_buff=tt_buff+2; - uchar *saved_from, *saved_to, *saved_vseg; - uint saved_length=0, saved_prefix_len=0; - uint length_pack; - DBUG_ENTER("_mi_prefix_search"); - - LINT_INIT(length); - LINT_INIT(prefix_len); - LINT_INIT(seg_len_pack); - LINT_INIT(saved_from); - LINT_INIT(saved_to); - LINT_INIT(saved_vseg); - - t_buff[0]=0; /* Avoid bugs */ - end= page+mi_getint(page); - nod_flag=mi_test_if_nod(page); - page+=2+nod_flag; - *ret_pos=page; - kseg=key; - - get_key_pack_length(kseg_len,length_pack,kseg); - key_len_skip=length_pack+kseg_len; - key_len_left=(int) key_len- (int) key_len_skip; - cmplen=(key_len_left>=0) ? kseg_len : key_len-length_pack; - DBUG_PRINT("info",("key: '%.*s'",kseg_len,kseg)); - - /* - Keys are compressed the following way: - - If the max length of first key segment <= 127 characters the prefix is - 1 byte else it's 2 byte - - prefix The high bit is set if this is a prefix for the prev key - length Packed length if the previous was a prefix byte - [length] Length character of data - next-key-seg Next key segments - */ - - matched=0; /* how many char's from prefix were alredy matched */ - len=0; /* length of previous key unpacked */ - - while (page < end) - { - uint packed= *page & 128; - - vseg=page; - if (keyinfo->seg->length >= 127) - { - suffix_len=mi_uint2korr(vseg) & 32767; - vseg+=2; - } - else - suffix_len= *vseg++ & 127; - - if (packed) - { - if (suffix_len == 0) /* Same key */ - prefix_len=len; - else - { - prefix_len=suffix_len; - get_key_length(suffix_len,vseg); - } - } - else - prefix_len=0; - - len=prefix_len+suffix_len; - seg_len_pack=get_pack_length(len); - t_buff=tt_buff+3-seg_len_pack; - store_key_length(t_buff,len); - - if (prefix_len > saved_prefix_len) - memcpy(t_buff+seg_len_pack+saved_prefix_len,saved_vseg, - prefix_len-saved_prefix_len); - saved_vseg=vseg; - saved_prefix_len=prefix_len; - - DBUG_PRINT("loop",("page: '%.*s%.*s'",prefix_len,t_buff+seg_len_pack, - suffix_len,vseg)); - { - uchar *from=vseg+suffix_len; - HA_KEYSEG *keyseg; - uint l; - - for (keyseg=keyinfo->seg+1 ; keyseg->type ; keyseg++ ) - { - - if (keyseg->flag & HA_NULL_PART) - { - if (!(*from++)) - continue; - } - if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK)) - { - get_key_length(l,from); - } - else - l=keyseg->length; - - from+=l; - } - from+=keyseg->length; - page=from+nod_flag; - length=from-vseg; - } - - if (page > end) - { - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - DBUG_PRINT("error",("Found wrong key: length: %u page: %p end: %p", - length, page, end)); - DBUG_RETURN(MI_FOUND_WRONG_KEY); - } - - if (matched >= prefix_len) - { - /* We have to compare. But we can still skip part of the key */ - uint left; - uchar *k=kseg+prefix_len; - - left=(len>cmplen) ? cmplen-prefix_len : suffix_len; - - matched=prefix_len+left; - - if (sort_order) - { - for (my_flag=0;left;left--) - if ((my_flag= (int) sort_order[*vseg++] - (int) sort_order[*k++])) - break; - } - else - { - for (my_flag=0;left;left--) - if ((my_flag= (int) *vseg++ - (int) *k++)) - break; - } - - if (my_flag>0) /* mismatch */ - break; - if (my_flag==0) /* match */ - { - /* - ** len cmplen seg_left_len more_segs - ** < matched=len; continue search - ** > = prefix ? found : (matched=len; continue search) - ** > < - ok, found - ** = < - ok, found - ** = = - ok, found - ** = = + next seg - */ - if (len < cmplen) - { - if ((keyinfo->seg->type != HA_KEYTYPE_TEXT && - keyinfo->seg->type != HA_KEYTYPE_VARTEXT1 && - keyinfo->seg->type != HA_KEYTYPE_VARTEXT2)) - my_flag= -1; - else - { - /* We have to compare k and vseg as if they where space extended */ - uchar *end= k+ (cmplen - len); - for ( ; k < end && *k == ' '; k++) ; - if (k == end) - goto cmp_rest; /* should never happen */ - if (*k < (uchar) ' ') - { - my_flag= 1; /* Compared string is smaller */ - break; - } - my_flag= -1; /* Continue searching */ - } - } - else if (len > cmplen) - { - uchar *end; - if ((nextflag & SEARCH_PREFIX) && key_len_left == 0) - goto fix_flag; - - /* We have to compare k and vseg as if they where space extended */ - for (end=vseg + (len-cmplen) ; - vseg < end && *vseg == (uchar) ' '; - vseg++, matched++) ; - DBUG_ASSERT(vseg < end); - - if (*vseg > (uchar) ' ') - { - my_flag= 1; /* Compared string is smaller */ - break; - } - my_flag= -1; /* Continue searching */ - } - else - { - cmp_rest: - if (key_len_left>0) - { - uint not_used; - if ((flag = ha_key_cmp(keyinfo->seg+1,vseg, - k,key_len_left,nextflag,¬_used)) >= 0) - break; - } - else - { - /* - at this line flag==-1 if the following lines were already - visited and 0 otherwise, i.e. flag <=0 here always !!! - */ - fix_flag: - DBUG_ASSERT(flag <= 0); - if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST)) - flag=(nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1; - if (flag>=0) - break; - } - } - } - matched-=left; - } - /* else (matched < prefix_len) ---> do nothing. */ - - memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len); - saved_to=buff+saved_length; - saved_from=saved_vseg; - saved_length=length; - *ret_pos=page; - } - if (my_flag) - flag=(keyinfo->seg->flag & HA_REVERSE_SORT) ? -my_flag : my_flag; - if (flag == 0) - { - memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len); - saved_to=buff+saved_length; - saved_from=saved_vseg; - saved_length=length; - } - if (saved_length) - memcpy(saved_to,saved_from,saved_length); - - *last_key= page == end; - - DBUG_PRINT("exit",("flag: %d ret_pos: %p", flag, *ret_pos)); - DBUG_RETURN(flag); -} /* _mi_prefix_search */ - - - /* Get pos to a key_block */ - -my_off_t _mi_kpos(uint nod_flag, uchar *after_key) -{ - after_key-=nod_flag; - switch (nod_flag) { -#if SIZEOF_OFF_T > 4 - case 7: - return mi_uint7korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH; - case 6: - return mi_uint6korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH; - case 5: - return mi_uint5korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH; -#else - case 7: - after_key++; - case 6: - after_key++; - case 5: - after_key++; -#endif - case 4: - return ((my_off_t) mi_uint4korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH; - case 3: - return ((my_off_t) mi_uint3korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH; - case 2: - return (my_off_t) (mi_uint2korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH); - case 1: - return (uint) (*after_key)*MI_MIN_KEY_BLOCK_LENGTH; - case 0: /* At leaf page */ - default: /* Impossible */ - return(HA_OFFSET_ERROR); - } -} /* _kpos */ - - - /* Save pos to a key_block */ - -void _mi_kpointer(register MI_INFO *info, register uchar *buff, my_off_t pos) -{ - pos/=MI_MIN_KEY_BLOCK_LENGTH; - switch (info->s->base.key_reflength) { -#if SIZEOF_OFF_T > 4 - case 7: mi_int7store(buff,pos); break; - case 6: mi_int6store(buff,pos); break; - case 5: mi_int5store(buff,pos); break; -#else - case 7: *buff++=0; - /* fall trough */ - case 6: *buff++=0; - /* fall trough */ - case 5: *buff++=0; - /* fall trough */ -#endif - case 4: mi_int4store(buff,pos); break; - case 3: mi_int3store(buff,pos); break; - case 2: mi_int2store(buff,(uint) pos); break; - case 1: buff[0]= (uchar) pos; break; - default: abort(); /* impossible */ - } -} /* _mi_kpointer */ - - - /* Calc pos to a data-record from a key */ - - -my_off_t _mi_dpos(MI_INFO *info, uint nod_flag, uchar *after_key) -{ - my_off_t pos; - after_key-=(nod_flag + info->s->rec_reflength); - switch (info->s->rec_reflength) { -#if SIZEOF_OFF_T > 4 - case 8: pos= (my_off_t) mi_uint8korr(after_key); break; - case 7: pos= (my_off_t) mi_uint7korr(after_key); break; - case 6: pos= (my_off_t) mi_uint6korr(after_key); break; - case 5: pos= (my_off_t) mi_uint5korr(after_key); break; -#else - case 8: pos= (my_off_t) mi_uint4korr(after_key+4); break; - case 7: pos= (my_off_t) mi_uint4korr(after_key+3); break; - case 6: pos= (my_off_t) mi_uint4korr(after_key+2); break; - case 5: pos= (my_off_t) mi_uint4korr(after_key+1); break; -#endif - case 4: pos= (my_off_t) mi_uint4korr(after_key); break; - case 3: pos= (my_off_t) mi_uint3korr(after_key); break; - case 2: pos= (my_off_t) mi_uint2korr(after_key); break; - default: - pos=0L; /* Shut compiler up */ - } - return (info->s->options & - (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos : - pos*info->s->base.pack_reclength; -} - - -/* Calc position from a record pointer ( in delete link chain ) */ - -my_off_t _mi_rec_pos(MYISAM_SHARE *s, uchar *ptr) -{ - my_off_t pos; - switch (s->rec_reflength) { -#if SIZEOF_OFF_T > 4 - case 8: - pos= (my_off_t) mi_uint8korr(ptr); - if (pos == HA_OFFSET_ERROR) - return HA_OFFSET_ERROR; /* end of list */ - break; - case 7: - pos= (my_off_t) mi_uint7korr(ptr); - if (pos == (((my_off_t) 1) << 56) -1) - return HA_OFFSET_ERROR; /* end of list */ - break; - case 6: - pos= (my_off_t) mi_uint6korr(ptr); - if (pos == (((my_off_t) 1) << 48) -1) - return HA_OFFSET_ERROR; /* end of list */ - break; - case 5: - pos= (my_off_t) mi_uint5korr(ptr); - if (pos == (((my_off_t) 1) << 40) -1) - return HA_OFFSET_ERROR; /* end of list */ - break; -#else - case 8: - case 7: - case 6: - case 5: - ptr+= (s->rec_reflength-4); - /* fall through */ -#endif - case 4: - pos= (my_off_t) mi_uint4korr(ptr); - if (pos == (my_off_t) (uint32) ~0L) - return HA_OFFSET_ERROR; - break; - case 3: - pos= (my_off_t) mi_uint3korr(ptr); - if (pos == (my_off_t) (1 << 24) -1) - return HA_OFFSET_ERROR; - break; - case 2: - pos= (my_off_t) mi_uint2korr(ptr); - if (pos == (my_off_t) (1 << 16) -1) - return HA_OFFSET_ERROR; - break; - default: abort(); /* Impossible */ - } - return ((s->options & - (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos : - pos*s->base.pack_reclength); -} - - - /* save position to record */ - -void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos) -{ - if (!(info->s->options & - (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) && - pos != HA_OFFSET_ERROR) - pos/=info->s->base.pack_reclength; - - switch (info->s->rec_reflength) { -#if SIZEOF_OFF_T > 4 - case 8: mi_int8store(buff,pos); break; - case 7: mi_int7store(buff,pos); break; - case 6: mi_int6store(buff,pos); break; - case 5: mi_int5store(buff,pos); break; -#else - case 8: *buff++=0; - /* fall trough */ - case 7: *buff++=0; - /* fall trough */ - case 6: *buff++=0; - /* fall trough */ - case 5: *buff++=0; - /* fall trough */ -#endif - case 4: mi_int4store(buff,pos); break; - case 3: mi_int3store(buff,pos); break; - case 2: mi_int2store(buff,(uint) pos); break; - default: abort(); /* Impossible */ - } -} /* _mi_dpointer */ - - - /* Get key from key-block */ - /* page points at previous key; its advanced to point at next key */ - /* key should contain previous key */ - /* Returns length of found key + pointers */ - /* nod_flag is a flag if we are on nod */ - - /* same as _mi_get_key but used with fixed length keys */ - -uint _mi_get_static_key(register MI_KEYDEF *keyinfo, uint nod_flag, - register uchar **page, register uchar *key) -{ - memcpy((byte*) key,(byte*) *page, - (size_t) (keyinfo->keylength+nod_flag)); - *page+=keyinfo->keylength+nod_flag; - return(keyinfo->keylength); -} /* _mi_get_static_key */ - - -/* Key with is packed against previous key or key with a NULL column */ - -uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, - register uchar **page_pos, register uchar *key) -{ - reg1 HA_KEYSEG *keyseg; - uchar *start_key,*page=*page_pos; - uint length; - - start_key=key; - for (keyseg=keyinfo->seg ; keyseg->type ;keyseg++) - { - if (keyseg->flag & HA_PACK_KEY) - { - /* key with length, packed to previous key */ - uchar *start=key; - uint packed= *page & 128,tot_length,rest_length; - if (keyseg->length >= 127) - { - length=mi_uint2korr(page) & 32767; - page+=2; - } - else - length= *page++ & 127; - - if (packed) - { - if (length > (uint) keyseg->length) - { - mi_print_error(keyinfo->share, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - return 0; /* Error */ - } - if (length == 0) /* Same key */ - { - if (keyseg->flag & HA_NULL_PART) - *key++=1; /* Can't be NULL */ - get_key_length(length,key); - key+= length; /* Same diff_key as prev */ - if (length > keyseg->length) - { - DBUG_PRINT("error", - ("Found too long null packed key: %u of %u at %p", - length, keyseg->length, *page_pos)); - DBUG_DUMP("key",(char*) *page_pos,16); - mi_print_error(keyinfo->share, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - return 0; - } - continue; - } - if (keyseg->flag & HA_NULL_PART) - { - key++; /* Skip null marker*/ - start++; - } - - get_key_length(rest_length,page); - tot_length=rest_length+length; - - /* If the stored length has changed, we must move the key */ - if (tot_length >= 255 && *start != 255) - { - /* length prefix changed from a length of one to a length of 3 */ - bmove_upp((char*) key+length+3,(char*) key+length+1,length); - *key=255; - mi_int2store(key+1,tot_length); - key+=3+length; - } - else if (tot_length < 255 && *start == 255) - { - bmove(key+1,key+3,length); - *key=tot_length; - key+=1+length; - } - else - { - store_key_length_inc(key,tot_length); - key+=length; - } - memcpy(key,page,rest_length); - page+=rest_length; - key+=rest_length; - continue; - } - else - { - if (keyseg->flag & HA_NULL_PART) - { - if (!length--) /* Null part */ - { - *key++=0; - continue; - } - *key++=1; /* Not null */ - } - } - if (length > (uint) keyseg->length) - { - DBUG_PRINT("error",("Found too long packed key: %u of %u at %p", - length, keyseg->length, *page_pos)); - DBUG_DUMP("key",(char*) *page_pos,16); - mi_print_error(keyinfo->share, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - return 0; /* Error */ - } - store_key_length_inc(key,length); - } - else - { - if (keyseg->flag & HA_NULL_PART) - { - if (!(*key++ = *page++)) - continue; - } - if (keyseg->flag & - (HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK)) - { - uchar *tmp=page; - get_key_length(length,tmp); - length+=(uint) (tmp-page); - } - else - length=keyseg->length; - } - memcpy((byte*) key,(byte*) page,(size_t) length); - key+=length; - page+=length; - } - length=keyseg->length+nod_flag; - bmove((byte*) key,(byte*) page,length); - *page_pos= page+length; - return ((uint) (key-start_key)+keyseg->length); -} /* _mi_get_pack_key */ - - - -/* key that is packed relatively to previous */ - -uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, - register uchar **page_pos, register uchar *key) -{ - reg1 HA_KEYSEG *keyseg; - uchar *start_key,*page,*page_end,*from,*from_end; - uint length,tmp; - - page= *page_pos; - page_end=page+MI_MAX_KEY_BUFF+1; - start_key=key; - - get_key_length(length,page); - if (length) - { - if (length > keyinfo->maxlength) - { - DBUG_PRINT("error",("Found too long binary packed key: %u of %u at %p", - length, keyinfo->maxlength, *page_pos)); - DBUG_DUMP("key",(char*) *page_pos,16); - mi_print_error(keyinfo->share, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - return 0; /* Wrong key */ - } - from=key; from_end=key+length; - } - else - { - from=page; from_end=page_end; /* Not packed key */ - } - - /* - The trouble is that key is split in two parts: - The first part is in from ...from_end-1. - The second part starts at page - */ - for (keyseg=keyinfo->seg ; keyseg->type ;keyseg++) - { - if (keyseg->flag & HA_NULL_PART) - { - if (from == from_end) { from=page; from_end=page_end; } - if (!(*key++ = *from++)) - continue; /* Null part */ - } - if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK)) - { - /* Get length of dynamic length key part */ - if (from == from_end) { from=page; from_end=page_end; } - if ((length= (*key++ = *from++)) == 255) - { - if (from == from_end) { from=page; from_end=page_end; } - length= (uint) ((*key++ = *from++)) << 8; - if (from == from_end) { from=page; from_end=page_end; } - length+= (uint) ((*key++ = *from++)); - } - } - else - length=keyseg->length; - - if ((tmp=(uint) (from_end-from)) <= length) - { - key+=tmp; /* Use old key */ - length-=tmp; - from=page; from_end=page_end; - } - DBUG_PRINT("info",("key: %p from: %p length: %u", - key, from, length)); - memcpy_overlap((byte*) key, (byte*) from, (size_t) length); - key+=length; - from+=length; - } - length=keyseg->length+nod_flag; - if ((tmp=(uint) (from_end-from)) <= length) - { - memcpy(key+tmp,page,length-tmp); /* Get last part of key */ - *page_pos= page+length-tmp; - } - else - { - if (from_end != page_end) - { - DBUG_PRINT("error",("Error when unpacking key")); - mi_print_error(keyinfo->share, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - return 0; /* Error */ - } - memcpy((byte*) key,(byte*) from,(size_t) length); - *page_pos= from+length; - } - return((uint) (key-start_key)+keyseg->length); -} - - - /* Get key at position without knowledge of previous key */ - /* Returns pointer to next key */ - -uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, - uchar *key, uchar *keypos, uint *return_key_length) -{ - uint nod_flag; - DBUG_ENTER("_mi_get_key"); - - nod_flag=mi_test_if_nod(page); - if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY))) - { - bmove((byte*) key,(byte*) keypos,keyinfo->keylength+nod_flag); - DBUG_RETURN(keypos+keyinfo->keylength+nod_flag); - } - else - { - page+=2+nod_flag; - key[0]=0; /* safety */ - while (page <= keypos) - { - *return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key); - if (*return_key_length == 0) - { - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - DBUG_RETURN(0); - } - } - } - DBUG_PRINT("exit",("page: %p length: %u", page, *return_key_length)); - DBUG_RETURN(page); -} /* _mi_get_key */ - - - /* Get key at position without knowledge of previous key */ - /* Returns 0 if ok */ - -static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, - uchar *key, uchar *keypos, - uint *return_key_length) -{ - uint nod_flag; - DBUG_ENTER("_mi_get_prev_key"); - - nod_flag=mi_test_if_nod(page); - if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY))) - { - *return_key_length=keyinfo->keylength; - bmove((byte*) key,(byte*) keypos- *return_key_length-nod_flag, - *return_key_length); - DBUG_RETURN(0); - } - else - { - page+=2+nod_flag; - key[0]=0; /* safety */ - while (page < keypos) - { - *return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key); - if (*return_key_length == 0) - { - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - DBUG_RETURN(1); - } - } - } - DBUG_RETURN(0); -} /* _mi_get_key */ - - - - /* Get last key from key-page */ - /* Return pointer to where key starts */ - -uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, - uchar *lastkey, uchar *endpos, uint *return_key_length) -{ - uint nod_flag; - uchar *lastpos; - DBUG_ENTER("_mi_get_last_key"); - DBUG_PRINT("enter",("page: %p endpos: %p", page, endpos)); - - nod_flag=mi_test_if_nod(page); - if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY))) - { - lastpos=endpos-keyinfo->keylength-nod_flag; - *return_key_length=keyinfo->keylength; - if (lastpos > page) - bmove((byte*) lastkey,(byte*) lastpos,keyinfo->keylength+nod_flag); - } - else - { - lastpos=(page+=2+nod_flag); - lastkey[0]=0; - while (page < endpos) - { - lastpos=page; - *return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,lastkey); - if (*return_key_length == 0) - { - DBUG_PRINT("error",("Couldn't find last key: page: %p", page)); - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - DBUG_RETURN(0); - } - } - } - DBUG_PRINT("exit",("lastpos: %p length: %u", lastpos, *return_key_length)); - DBUG_RETURN(lastpos); -} /* _mi_get_last_key */ - - - /* Calculate length of key */ - -uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key) -{ - reg1 HA_KEYSEG *keyseg; - uchar *start; - - if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY))) - return (keyinfo->keylength); - - start=key; - for (keyseg=keyinfo->seg ; keyseg->type ; keyseg++) - { - if (keyseg->flag & HA_NULL_PART) - if (!*key++) - continue; - if (keyseg->flag & (HA_SPACE_PACK | HA_BLOB_PART | HA_VAR_LENGTH_PART)) - { - uint length; - get_key_length(length,key); - key+=length; - } - else - key+= keyseg->length; - } - return((uint) (key-start)+keyseg->length); -} /* _mi_keylength */ - - -/* - Calculate length of part key. - - Used in mi_rkey() to find the key found for the key-part that was used. - This is needed in case of multi-byte character sets where we may search - after '0xDF' but find 'ss' -*/ - -uint _mi_keylength_part(MI_KEYDEF *keyinfo, register uchar *key, - HA_KEYSEG *end) -{ - reg1 HA_KEYSEG *keyseg; - uchar *start= key; - - for (keyseg=keyinfo->seg ; keyseg != end ; keyseg++) - { - if (keyseg->flag & HA_NULL_PART) - if (!*key++) - continue; - if (keyseg->flag & (HA_SPACE_PACK | HA_BLOB_PART | HA_VAR_LENGTH_PART)) - { - uint length; - get_key_length(length,key); - key+=length; - } - else - key+= keyseg->length; - } - return (uint) (key-start); -} - - /* Move a key */ - -uchar *_mi_move_key(MI_KEYDEF *keyinfo, uchar *to, uchar *from) -{ - reg1 uint length; - memcpy((byte*) to, (byte*) from, - (size_t) (length=_mi_keylength(keyinfo,from))); - return to+length; -} - - /* Find next/previous record with same key */ - /* This can't be used when database is touched after last read */ - -int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo, - uchar *key, uint key_length, uint nextflag, my_off_t pos) -{ - int error; - uint nod_flag; - uchar lastkey[MI_MAX_KEY_BUFF]; - DBUG_ENTER("_mi_search_next"); - DBUG_PRINT("enter",("nextflag: %u lastpos: %lu int_keypos: %lu", - nextflag, (ulong) info->lastpos, - (ulong) info->int_keypos)); - DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_length);); - - /* Force full read if we are at last key or if we are not on a leaf - and the key tree has changed since we used it last time - Note that even if the key tree has changed since last read, we can use - the last read data from the leaf if we haven't used the buffer for - something else. - */ - - if (((nextflag & SEARCH_BIGGER) && info->int_keypos >= info->int_maxpos) || - info->page_changed || - (info->int_keytree_version != keyinfo->version && - (info->int_nod_flag || info->buff_used))) - DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY, - nextflag | SEARCH_SAVE_BUFF, pos)); - - if (info->buff_used) - { - if (!_mi_fetch_keypage(info,keyinfo,info->last_search_keypage, - DFLT_INIT_HITS,info->buff,0)) - DBUG_RETURN(-1); - info->buff_used=0; - } - - /* Last used buffer is in info->buff */ - nod_flag=mi_test_if_nod(info->buff); - - if (nextflag & SEARCH_BIGGER) /* Next key */ - { - my_off_t tmp_pos=_mi_kpos(nod_flag,info->int_keypos); - if (tmp_pos != HA_OFFSET_ERROR) - { - if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY, - nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0) - DBUG_RETURN(error); - } - memcpy(lastkey,key,key_length); - if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag, - &info->int_keypos,lastkey))) - DBUG_RETURN(-1); - } - else /* Previous key */ - { - uint length; - /* Find start of previous key */ - info->int_keypos=_mi_get_last_key(info,keyinfo,info->buff,lastkey, - info->int_keypos, &length); - if (!info->int_keypos) - DBUG_RETURN(-1); - if (info->int_keypos == info->buff+2) - DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY, - nextflag | SEARCH_SAVE_BUFF, pos)); - if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY, - nextflag | SEARCH_SAVE_BUFF, - _mi_kpos(nod_flag,info->int_keypos))) <= 0) - DBUG_RETURN(error); - - /* QQ: We should be able to optimize away the following call */ - if (! _mi_get_last_key(info,keyinfo,info->buff,lastkey, - info->int_keypos,&info->lastkey_length)) - DBUG_RETURN(-1); - } - memcpy(info->lastkey,lastkey,info->lastkey_length); - info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length); - DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos)); - DBUG_RETURN(0); -} /* _mi_search_next */ - - - /* Search after position for the first row in an index */ - /* This is stored in info->lastpos */ - -int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo, - register my_off_t pos) -{ - uint nod_flag; - uchar *page; - DBUG_ENTER("_mi_search_first"); - - if (pos == HA_OFFSET_ERROR) - { - my_errno=HA_ERR_KEY_NOT_FOUND; - info->lastpos= HA_OFFSET_ERROR; - DBUG_RETURN(-1); - } - - do - { - if (!_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,0)) - { - info->lastpos= HA_OFFSET_ERROR; - DBUG_RETURN(-1); - } - nod_flag=mi_test_if_nod(info->buff); - page=info->buff+2+nod_flag; - } while ((pos=_mi_kpos(nod_flag,page)) != HA_OFFSET_ERROR); - - if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page, - info->lastkey))) - DBUG_RETURN(-1); /* Crashed */ - - info->int_keypos=page; info->int_maxpos=info->buff+mi_getint(info->buff)-1; - info->int_nod_flag=nod_flag; - info->int_keytree_version=keyinfo->version; - info->last_search_keypage=info->last_keypage; - info->page_changed=info->buff_used=0; - info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length); - - DBUG_PRINT("exit",("found key at %lu", (ulong) info->lastpos)); - DBUG_RETURN(0); -} /* _mi_search_first */ - - - /* Search after position for the last row in an index */ - /* This is stored in info->lastpos */ - -int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo, - register my_off_t pos) -{ - uint nod_flag; - uchar *buff,*page; - DBUG_ENTER("_mi_search_last"); - - if (pos == HA_OFFSET_ERROR) - { - my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */ - info->lastpos= HA_OFFSET_ERROR; - DBUG_RETURN(-1); - } - - buff=info->buff; - do - { - if (!_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,buff,0)) - { - info->lastpos= HA_OFFSET_ERROR; - DBUG_RETURN(-1); - } - page= buff+mi_getint(buff); - nod_flag=mi_test_if_nod(buff); - } while ((pos=_mi_kpos(nod_flag,page)) != HA_OFFSET_ERROR); - - if (!_mi_get_last_key(info,keyinfo,buff,info->lastkey,page, - &info->lastkey_length)) - DBUG_RETURN(-1); - info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length); - info->int_keypos=info->int_maxpos=page; - info->int_nod_flag=nod_flag; - info->int_keytree_version=keyinfo->version; - info->last_search_keypage=info->last_keypage; - info->page_changed=info->buff_used=0; - - DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos)); - DBUG_RETURN(0); -} /* _mi_search_last */ - - - -/**************************************************************************** -** -** Functions to store and pack a key in a page -** -** mi_calc_xx_key_length takes the following arguments: -** nod_flag If nod: Length of nod-pointer -** next_key Position to pos after the new key in buffer -** org_key Key that was before the next key in buffer -** prev_key Last key before current key -** key Key that will be stored -** s_temp Information how next key will be packed -****************************************************************************/ - -/* Static length key */ - -int -_mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint nod_flag, - uchar *next_pos __attribute__((unused)), - uchar *org_key __attribute__((unused)), - uchar *prev_key __attribute__((unused)), - uchar *key, MI_KEY_PARAM *s_temp) -{ - s_temp->key=key; - return (int) (s_temp->totlength=keyinfo->keylength+nod_flag); -} - -/* Variable length key */ - -int -_mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint nod_flag, - uchar *next_pos __attribute__((unused)), - uchar *org_key __attribute__((unused)), - uchar *prev_key __attribute__((unused)), - uchar *key, MI_KEY_PARAM *s_temp) -{ - s_temp->key=key; - return (int) (s_temp->totlength=_mi_keylength(keyinfo,key)+nod_flag); -} - -/* - length of key with a variable length first segment which is prefix - compressed (myisamchk reports 'packed + stripped') - - Keys are compressed the following way: - - If the max length of first key segment <= 127 characters the prefix is - 1 byte else it's 2 byte - - prefix byte The high bit is set if this is a prefix for the prev key - length Packed length if the previous was a prefix byte - [length] Length character of data - next-key-seg Next key segments - - If the first segment can have NULL: - The length is 0 for NULLS and 1+length for not null columns. - -*/ - -int -_mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, - uchar *org_key, uchar *prev_key, uchar *key, - MI_KEY_PARAM *s_temp) -{ - reg1 HA_KEYSEG *keyseg; - int length; - uint key_length,ref_length,org_key_length=0, - length_pack,new_key_length,diff_flag,pack_marker; - uchar *start,*end,*key_end,*sort_order; - bool same_length; - - length_pack=s_temp->ref_length=s_temp->n_ref_length=s_temp->n_length=0; - same_length=0; keyseg=keyinfo->seg; - key_length=_mi_keylength(keyinfo,key)+nod_flag; - - sort_order=0; - if ((keyinfo->flag & HA_FULLTEXT) && - ((keyseg->type == HA_KEYTYPE_TEXT) || - (keyseg->type == HA_KEYTYPE_VARTEXT1) || - (keyseg->type == HA_KEYTYPE_VARTEXT2)) && - !use_strnxfrm(keyseg->charset)) - sort_order=keyseg->charset->sort_order; - - /* diff flag contains how many bytes is needed to pack key */ - if (keyseg->length >= 127) - { - diff_flag=2; - pack_marker=32768; - } - else - { - diff_flag= 1; - pack_marker=128; - } - s_temp->pack_marker=pack_marker; - - /* Handle the case that the first part have NULL values */ - if (keyseg->flag & HA_NULL_PART) - { - if (!*key++) - { - s_temp->key=key; - s_temp->ref_length=s_temp->key_length=0; - s_temp->totlength=key_length-1+diff_flag; - s_temp->next_key_pos=0; /* No next key */ - return (s_temp->totlength); - } - s_temp->store_not_null=1; - key_length--; /* We don't store NULL */ - if (prev_key && !*prev_key++) - org_key=prev_key=0; /* Can't pack against prev */ - else if (org_key) - org_key++; /* Skip NULL */ - } - else - s_temp->store_not_null=0; - s_temp->prev_key=org_key; - - /* The key part will start with a packed length */ - - get_key_pack_length(new_key_length,length_pack,key); - end=key_end= key+ new_key_length; - start=key; - - /* Calc how many characters are identical between this and the prev. key */ - if (prev_key) - { - get_key_length(org_key_length,prev_key); - s_temp->prev_key=prev_key; /* Pointer at data */ - /* Don't use key-pack if length == 0 */ - if (new_key_length && new_key_length == org_key_length) - same_length=1; - else if (new_key_length > org_key_length) - end=key + org_key_length; - - if (sort_order) /* SerG */ - { - while (key < end && sort_order[*key] == sort_order[*prev_key]) - { - key++; prev_key++; - } - } - else - { - while (key < end && *key == *prev_key) - { - key++; prev_key++; - } - } - } - - s_temp->key=key; - s_temp->key_length= (uint) (key_end-key); - - if (same_length && key == key_end) - { - /* identical variable length key */ - s_temp->ref_length= pack_marker; - length=(int) key_length-(int) (key_end-start)-length_pack; - length+= diff_flag; - if (next_key) - { /* Can't combine with next */ - s_temp->n_length= *next_key; /* Needed by _mi_store_key */ - next_key=0; - } - } - else - { - if (start != key) - { /* Starts as prev key */ - ref_length= (uint) (key-start); - s_temp->ref_length= ref_length + pack_marker; - length= (int) (key_length - ref_length); - - length-= length_pack; - length+= diff_flag; - length+= ((new_key_length-ref_length) >= 255) ? 3 : 1;/* Rest_of_key */ - } - else - { - s_temp->key_length+=s_temp->store_not_null; /* If null */ - length= key_length - length_pack+ diff_flag; - } - } - s_temp->totlength=(uint) length; - s_temp->prev_length=0; - DBUG_PRINT("test",("tot_length: %u length: %d uniq_key_length: %u", - key_length, length, s_temp->key_length)); - - /* If something after that hasn't length=0, test if we can combine */ - if ((s_temp->next_key_pos=next_key)) - { - uint packed,n_length; - - packed = *next_key & 128; - if (diff_flag == 2) - { - n_length= mi_uint2korr(next_key) & 32767; /* Length of next key */ - next_key+=2; - } - else - n_length= *next_key++ & 127; - if (!packed) - n_length-= s_temp->store_not_null; - - if (n_length || packed) /* Don't pack 0 length keys */ - { - uint next_length_pack, new_ref_length=s_temp->ref_length; - - if (packed) - { - /* If first key and next key is packed (only on delete) */ - if (!prev_key && org_key) - { - get_key_length(org_key_length,org_key); - key=start; - if (sort_order) /* SerG */ - { - while (key < end && sort_order[*key] == sort_order[*org_key]) - { - key++; org_key++; - } - } - else - { - while (key < end && *key == *org_key) - { - key++; org_key++; - } - } - if ((new_ref_length= (uint) (key - start))) - new_ref_length+=pack_marker; - } - - if (!n_length) - { - /* - We put a different key between two identical variable length keys - Extend next key to have same prefix as this key - */ - if (new_ref_length) /* prefix of previus key */ - { /* make next key longer */ - s_temp->part_of_prev_key= new_ref_length; - s_temp->prev_length= org_key_length - - (new_ref_length-pack_marker); - s_temp->n_ref_length= s_temp->n_length= s_temp->prev_length; - n_length= get_pack_length(s_temp->prev_length); - s_temp->prev_key+= (new_ref_length - pack_marker); - length+= s_temp->prev_length + n_length; - } - else - { /* Can't use prev key */ - s_temp->part_of_prev_key=0; - s_temp->prev_length= org_key_length; - s_temp->n_ref_length=s_temp->n_length= org_key_length; - length+= org_key_length; - /* +get_pack_length(org_key_length); */ - } - return (int) length; - } - - ref_length=n_length; - get_key_pack_length(n_length,next_length_pack,next_key); - - /* Test if new keys has fewer characters that match the previous key */ - if (!new_ref_length) - { /* Can't use prev key */ - s_temp->part_of_prev_key= 0; - s_temp->prev_length= ref_length; - s_temp->n_ref_length= s_temp->n_length= n_length+ref_length; - /* s_temp->prev_key+= get_pack_length(org_key_length); */ - return (int) length+ref_length-next_length_pack; - } - if (ref_length+pack_marker > new_ref_length) - { - uint new_pack_length=new_ref_length-pack_marker; - /* We must copy characters from the original key to the next key */ - s_temp->part_of_prev_key= new_ref_length; - s_temp->prev_length= ref_length - new_pack_length; - s_temp->n_ref_length=s_temp->n_length=n_length + s_temp->prev_length; - s_temp->prev_key+= new_pack_length; -/* +get_pack_length(org_key_length); */ - length= length-get_pack_length(ref_length)+ - get_pack_length(new_pack_length); - return (int) length + s_temp->prev_length; - } - } - else - { - /* Next key wasn't a prefix of previous key */ - ref_length=0; - next_length_pack=0; - } - DBUG_PRINT("test",("length: %d next_key: %p", length, next_key)); - - { - uint tmp_length; - key=(start+=ref_length); - if (key+n_length < key_end) /* Normalize length based */ - key_end=key+n_length; - if (sort_order) /* SerG */ - { - while (key < key_end && sort_order[*key] == - sort_order[*next_key]) - { - key++; next_key++; - } - } - else - { - while (key < key_end && *key == *next_key) - { - key++; next_key++; - } - } - if (!(tmp_length=(uint) (key-start))) - { /* Key can't be re-packed */ - s_temp->next_key_pos=0; - return length; - } - ref_length+=tmp_length; - n_length-=tmp_length; - length-=tmp_length+next_length_pack; /* We gained these chars */ - } - if (n_length == 0 && ref_length == new_key_length) - { - s_temp->n_ref_length=pack_marker; /* Same as prev key */ - } - else - { - s_temp->n_ref_length=ref_length | pack_marker; - length+= get_pack_length(n_length); - s_temp->n_length=n_length; - } - } - } - return length; -} - - -/* Length of key which is prefix compressed */ - -int -_mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, - uchar *org_key, uchar *prev_key, uchar *key, - MI_KEY_PARAM *s_temp) -{ - uint length,key_length,ref_length; - - s_temp->totlength=key_length=_mi_keylength(keyinfo,key)+nod_flag; -#ifdef HAVE_purify - s_temp->n_length= s_temp->n_ref_length=0; /* For valgrind */ -#endif - s_temp->key=key; - s_temp->prev_key=org_key; - if (prev_key) /* If not first key in block */ - { - /* pack key against previous key */ - /* - As keys may be identical when running a sort in myisamchk, we - have to guard against the case where keys may be identical - */ - uchar *end; - end=key+key_length; - for ( ; *key == *prev_key && key < end; key++,prev_key++) ; - s_temp->ref_length= ref_length=(uint) (key-s_temp->key); - length=key_length - ref_length + get_pack_length(ref_length); - } - else - { - /* No previous key */ - s_temp->ref_length=ref_length=0; - length=key_length+1; - } - if ((s_temp->next_key_pos=next_key)) /* If another key after */ - { - /* pack key against next key */ - uint next_length,next_length_pack; - get_key_pack_length(next_length,next_length_pack,next_key); - - /* If first key and next key is packed (only on delete) */ - if (!prev_key && org_key && next_length) - { - uchar *end; - for (key= s_temp->key, end=key+next_length ; - *key == *org_key && key < end; - key++,org_key++) ; - ref_length= (uint) (key - s_temp->key); - } - - if (next_length > ref_length) - { - /* We put a key with different case between two keys with the same prefix - Extend next key to have same prefix as - this key */ - s_temp->n_ref_length= ref_length; - s_temp->prev_length= next_length-ref_length; - s_temp->prev_key+= ref_length; - return (int) (length+ s_temp->prev_length - next_length_pack + - get_pack_length(ref_length)); - } - /* Check how many characters are identical to next key */ - key= s_temp->key+next_length; - while (*key++ == *next_key++) ; - if ((ref_length= (uint) (key - s_temp->key)-1) == next_length) - { - s_temp->next_key_pos=0; - return length; /* can't pack next key */ - } - s_temp->prev_length=0; - s_temp->n_ref_length=ref_length; - return (int) (length-(ref_length - next_length) - next_length_pack + - get_pack_length(ref_length)); - } - return (int) length; -} - - -/* -** store a key packed with _mi_calc_xxx_key_length in page-buffert -*/ - -/* store key without compression */ - -void _mi_store_static_key(MI_KEYDEF *keyinfo __attribute__((unused)), - register uchar *key_pos, - register MI_KEY_PARAM *s_temp) -{ - memcpy((byte*) key_pos,(byte*) s_temp->key,(size_t) s_temp->totlength); -} - - -/* store variable length key with prefix compression */ - -#define store_pack_length(test,pos,length) { \ - if (test) { *((pos)++) = (uchar) (length); } else \ - { *((pos)++) = (uchar) ((length) >> 8); *((pos)++) = (uchar) (length); } } - - -void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)), - register uchar *key_pos, - register MI_KEY_PARAM *s_temp) -{ - uint length; - uchar *start; - - start=key_pos; - - if (s_temp->ref_length) - { - /* Packed against previous key */ - store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->ref_length); - /* If not same key after */ - if (s_temp->ref_length != s_temp->pack_marker) - store_key_length_inc(key_pos,s_temp->key_length); - } - else - { - /* Not packed against previous key */ - store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->key_length); - } - bmove((byte*) key_pos,(byte*) s_temp->key, - (length=s_temp->totlength-(uint) (key_pos-start))); - - if (!s_temp->next_key_pos) /* No following key */ - return; - key_pos+=length; - - if (s_temp->prev_length) - { - /* Extend next key because new key didn't have same prefix as prev key */ - if (s_temp->part_of_prev_key) - { - store_pack_length(s_temp->pack_marker == 128,key_pos, - s_temp->part_of_prev_key); - store_key_length_inc(key_pos,s_temp->n_length); - } - else - { - s_temp->n_length+= s_temp->store_not_null; - store_pack_length(s_temp->pack_marker == 128,key_pos, - s_temp->n_length); - } - memcpy(key_pos, s_temp->prev_key, s_temp->prev_length); - } - else if (s_temp->n_ref_length) - { - store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->n_ref_length); - if (s_temp->n_ref_length == s_temp->pack_marker) - return; /* Identical key */ - store_key_length(key_pos,s_temp->n_length); - } - else - { - s_temp->n_length+= s_temp->store_not_null; - store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->n_length); - } -} - - -/* variable length key with prefix compression */ - -void _mi_store_bin_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)), - register uchar *key_pos, - register MI_KEY_PARAM *s_temp) -{ - store_key_length_inc(key_pos,s_temp->ref_length); - memcpy((char*) key_pos,(char*) s_temp->key+s_temp->ref_length, - (size_t) s_temp->totlength-s_temp->ref_length); - - if (s_temp->next_key_pos) - { - key_pos+=(uint) (s_temp->totlength-s_temp->ref_length); - store_key_length_inc(key_pos,s_temp->n_ref_length); - if (s_temp->prev_length) /* If we must extend key */ - { - memcpy(key_pos,s_temp->prev_key,s_temp->prev_length); - } - } -} diff --git a/myisam/mi_static.c b/myisam/mi_static.c deleted file mode 100644 index f41aeff8453..00000000000 --- a/myisam/mi_static.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Static variables for MyISAM library. All definied here for easy making of - a shared library -*/ - -#ifndef _global_h -#include "myisamdef.h" -#endif - -LIST *myisam_open_list=0; -uchar NEAR myisam_file_magic[]= -{ (uchar) 254, (uchar) 254,'\007', '\001', }; -uchar NEAR myisam_pack_file_magic[]= -{ (uchar) 254, (uchar) 254,'\010', '\001', }; -my_string myisam_log_filename=(char*) "myisam.log"; -File myisam_log_file= -1; -uint myisam_quick_table_bits=9; -uint myisam_block_size=MI_KEY_BLOCK_LENGTH; /* Best by test */ -my_bool myisam_flush=0, myisam_delay_key_write=0, myisam_single_user=0; -#if defined(THREAD) && !defined(DONT_USE_RW_LOCKS) -my_bool myisam_concurrent_insert=1; -#else -my_bool myisam_concurrent_insert=0; -#endif -my_off_t myisam_max_extra_temp_length= (my_off_t)MI_MAX_TEMP_LENGTH; -my_off_t myisam_max_temp_length= MAX_FILE_SIZE; -ulong myisam_bulk_insert_tree_size=8192*1024; -ulong myisam_data_pointer_size=4; - -/* - read_vec[] is used for converting between P_READ_KEY.. and SEARCH_ - Position is , == , >= , <= , > , < -*/ - -uint NEAR myisam_read_vec[]= -{ - SEARCH_FIND, SEARCH_FIND | SEARCH_BIGGER, SEARCH_FIND | SEARCH_SMALLER, - SEARCH_NO_FIND | SEARCH_BIGGER, SEARCH_NO_FIND | SEARCH_SMALLER, - SEARCH_FIND | SEARCH_PREFIX, SEARCH_LAST, SEARCH_LAST | SEARCH_SMALLER, - MBR_CONTAIN, MBR_INTERSECT, MBR_WITHIN, MBR_DISJOINT, MBR_EQUAL -}; - -uint NEAR myisam_readnext_vec[]= -{ - SEARCH_BIGGER, SEARCH_BIGGER, SEARCH_SMALLER, SEARCH_BIGGER, SEARCH_SMALLER, - SEARCH_BIGGER, SEARCH_SMALLER, SEARCH_SMALLER -}; diff --git a/myisam/mi_statrec.c b/myisam/mi_statrec.c deleted file mode 100644 index 8f5cde45e24..00000000000 --- a/myisam/mi_statrec.c +++ /dev/null @@ -1,301 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - - /* Functions to handle fixed-length-records */ - -#include "myisamdef.h" - - -int _mi_write_static_record(MI_INFO *info, const byte *record) -{ - uchar temp[8]; /* max pointer length */ - - if (info->s->state.dellink != HA_OFFSET_ERROR) - { - my_off_t filepos=info->s->state.dellink; - info->rec_cache.seek_not_done=1; /* We have done a seek */ - if (my_pread(info->dfile,(char*) &temp[0],info->s->base.rec_reflength, - info->s->state.dellink+1, - MYF(MY_NABP))) - goto err; - info->s->state.dellink= _mi_rec_pos(info->s,temp); - info->state->del--; - info->state->empty-=info->s->base.pack_reclength; - if (my_pwrite(info->dfile, (char*) record, info->s->base.reclength, - filepos, - MYF(MY_NABP))) - goto err; - } - else - { - if (info->state->data_file_length > info->s->base.max_data_file_length- - info->s->base.pack_reclength) - { - my_errno=HA_ERR_RECORD_FILE_FULL; - return(2); - } - if (info->opt_flag & WRITE_CACHE_USED) - { /* Cash in use */ - if (my_b_write(&info->rec_cache, (byte*) record, - info->s->base.reclength)) - goto err; - if (info->s->base.pack_reclength != info->s->base.reclength) - { - uint length=info->s->base.pack_reclength - info->s->base.reclength; - bzero((char*) temp,length); - if (my_b_write(&info->rec_cache, (byte*) temp,length)) - goto err; - } - } - else - { - info->rec_cache.seek_not_done=1; /* We have done a seek */ - if (my_pwrite(info->dfile,(char*) record,info->s->base.reclength, - info->state->data_file_length, - info->s->write_flag)) - goto err; - if (info->s->base.pack_reclength != info->s->base.reclength) - { - uint length=info->s->base.pack_reclength - info->s->base.reclength; - bzero((char*) temp,length); - if (my_pwrite(info->dfile, (byte*) temp,length, - info->state->data_file_length+ - info->s->base.reclength, - info->s->write_flag)) - goto err; - } - } - info->state->data_file_length+=info->s->base.pack_reclength; - info->s->state.split++; - } - return 0; - err: - return 1; -} - -int _mi_update_static_record(MI_INFO *info, my_off_t pos, const byte *record) -{ - info->rec_cache.seek_not_done=1; /* We have done a seek */ - return (my_pwrite(info->dfile, - (char*) record,info->s->base.reclength, - pos, - MYF(MY_NABP)) != 0); -} - - -int _mi_delete_static_record(MI_INFO *info) -{ - uchar temp[9]; /* 1+sizeof(uint32) */ - - info->state->del++; - info->state->empty+=info->s->base.pack_reclength; - temp[0]= '\0'; /* Mark that record is deleted */ - _mi_dpointer(info,temp+1,info->s->state.dellink); - info->s->state.dellink = info->lastpos; - info->rec_cache.seek_not_done=1; - return (my_pwrite(info->dfile,(byte*) temp, 1+info->s->rec_reflength, - info->lastpos, MYF(MY_NABP)) != 0); -} - - -int _mi_cmp_static_record(register MI_INFO *info, register const byte *old) -{ - DBUG_ENTER("_mi_cmp_static_record"); - - /* We are going to do changes; dont let anybody disturb */ - dont_break(); /* Dont allow SIGHUP or SIGINT */ - - if (info->opt_flag & WRITE_CACHE_USED) - { - if (flush_io_cache(&info->rec_cache)) - { - DBUG_RETURN(-1); - } - info->rec_cache.seek_not_done=1; /* We have done a seek */ - } - - if ((info->opt_flag & READ_CHECK_USED)) - { /* If check isn't disabled */ - info->rec_cache.seek_not_done=1; /* We have done a seek */ - if (my_pread(info->dfile, (char*) info->rec_buff, info->s->base.reclength, - info->lastpos, - MYF(MY_NABP))) - DBUG_RETURN(-1); - if (memcmp((byte*) info->rec_buff, (byte*) old, - (uint) info->s->base.reclength)) - { - DBUG_DUMP("read",old,info->s->base.reclength); - DBUG_DUMP("disk",info->rec_buff,info->s->base.reclength); - my_errno=HA_ERR_RECORD_CHANGED; /* Record have changed */ - DBUG_RETURN(1); - } - } - DBUG_RETURN(0); -} - - -int _mi_cmp_static_unique(MI_INFO *info, MI_UNIQUEDEF *def, - const byte *record, my_off_t pos) -{ - DBUG_ENTER("_mi_cmp_static_unique"); - - info->rec_cache.seek_not_done=1; /* We have done a seek */ - if (my_pread(info->dfile, (char*) info->rec_buff, info->s->base.reclength, - pos, MYF(MY_NABP))) - DBUG_RETURN(-1); - DBUG_RETURN(mi_unique_comp(def, record, info->rec_buff, - def->null_are_equal)); -} - - - /* Read a fixed-length-record */ - /* Returns 0 if Ok. */ - /* 1 if record is deleted */ - /* MY_FILE_ERROR on read-error or locking-error */ - -int _mi_read_static_record(register MI_INFO *info, register my_off_t pos, - register byte *record) -{ - int error; - - if (pos != HA_OFFSET_ERROR) - { - if (info->opt_flag & WRITE_CACHE_USED && - info->rec_cache.pos_in_file <= pos && - flush_io_cache(&info->rec_cache)) - return(-1); - info->rec_cache.seek_not_done=1; /* We have done a seek */ - - error=my_pread(info->dfile,(char*) record,info->s->base.reclength, - pos,MYF(MY_NABP)) != 0; - fast_mi_writeinfo(info); - if (! error) - { - if (!*record) - { - my_errno=HA_ERR_RECORD_DELETED; - return(1); /* Record is deleted */ - } - info->update|= HA_STATE_AKTIV; /* Record is read */ - return(0); - } - return(-1); /* Error on read */ - } - fast_mi_writeinfo(info); /* No such record */ - return(-1); -} - - - -int _mi_read_rnd_static_record(MI_INFO *info, byte *buf, - register my_off_t filepos, - my_bool skip_deleted_blocks) -{ - int locked,error,cache_read; - uint cache_length; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("_mi_read_rnd_static_record"); - - cache_read=0; - cache_length=0; - if (info->opt_flag & WRITE_CACHE_USED && - (info->rec_cache.pos_in_file <= filepos || skip_deleted_blocks) && - flush_io_cache(&info->rec_cache)) - DBUG_RETURN(my_errno); - if (info->opt_flag & READ_CACHE_USED) - { /* Cache in use */ - if (filepos == my_b_tell(&info->rec_cache) && - (skip_deleted_blocks || !filepos)) - { - cache_read=1; /* Read record using cache */ - cache_length=(uint) (info->rec_cache.read_end - info->rec_cache.read_pos); - } - else - info->rec_cache.seek_not_done=1; /* Filepos is changed */ - } - locked=0; - if (info->lock_type == F_UNLCK) - { - if (filepos >= info->state->data_file_length) - { /* Test if new records */ - if (_mi_readinfo(info,F_RDLCK,0)) - DBUG_RETURN(my_errno); - locked=1; - } - else - { /* We don't nead new info */ -#ifndef UNSAFE_LOCKING - if ((! cache_read || share->base.reclength > cache_length) && - share->tot_locks == 0) - { /* record not in cache */ - if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF, - MYF(MY_SEEK_NOT_DONE) | info->lock_wait)) - DBUG_RETURN(my_errno); - locked=1; - } -#else - info->tmp_lock_type=F_RDLCK; -#endif - } - } - if (filepos >= info->state->data_file_length) - { - DBUG_PRINT("test",("filepos: %ld (%ld) records: %ld del: %ld", - filepos/share->base.reclength,filepos, - info->state->records, info->state->del)); - fast_mi_writeinfo(info); - DBUG_RETURN(my_errno=HA_ERR_END_OF_FILE); - } - info->lastpos= filepos; - info->nextpos= filepos+share->base.pack_reclength; - - if (! cache_read) /* No cacheing */ - { - if ((error=_mi_read_static_record(info,filepos,buf))) - { - if (error > 0) - error=my_errno=HA_ERR_RECORD_DELETED; - else - error=my_errno; - } - DBUG_RETURN(error); - } - - /* Read record with cacheing */ - error=my_b_read(&info->rec_cache,(byte*) buf,share->base.reclength); - if (info->s->base.pack_reclength != info->s->base.reclength && !error) - { - char tmp[8]; /* Skill fill bytes */ - error=my_b_read(&info->rec_cache,(byte*) tmp, - info->s->base.pack_reclength - info->s->base.reclength); - } - if (locked) - VOID(_mi_writeinfo(info,0)); /* Unlock keyfile */ - if (!error) - { - if (!buf[0]) - { /* Record is removed */ - DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED); - } - /* Found and may be updated */ - info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED; - DBUG_RETURN(0); - } - /* my_errno should be set if rec_cache.error == -1 */ - if (info->rec_cache.error != -1 || my_errno == 0) - my_errno=HA_ERR_WRONG_IN_RECORD; - DBUG_RETURN(my_errno); /* Something wrong (EOF?) */ -} diff --git a/myisam/mi_test1.c b/myisam/mi_test1.c deleted file mode 100644 index aa6cd98ac8e..00000000000 --- a/myisam/mi_test1.c +++ /dev/null @@ -1,674 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Testing of the basic functions of a MyISAM table */ - -#include "myisam.h" -#include <my_getopt.h> -#include <m_string.h> - -#define MAX_REC_LENGTH 1024 - -static void usage(); - -static int rec_pointer_size=0, flags[50]; -static int key_field=FIELD_SKIP_PRESPACE,extra_field=FIELD_SKIP_ENDSPACE; -static int key_type=HA_KEYTYPE_NUM; -static int create_flag=0; - -static uint insert_count, update_count, remove_count; -static uint pack_keys=0, pack_seg=0, key_length; -static uint unique_key=HA_NOSAME; -static my_bool key_cacheing, null_fields, silent, skip_update, opt_unique, - verbose; -static MI_COLUMNDEF recinfo[4]; -static MI_KEYDEF keyinfo[10]; -static HA_KEYSEG keyseg[10]; -static HA_KEYSEG uniqueseg[10]; - -static int run_test(const char *filename); -static void get_options(int argc, char *argv[]); -static void create_key(char *key,uint rownr); -static void create_record(char *record,uint rownr); -static void update_record(char *record); - -int main(int argc,char *argv[]) -{ - MY_INIT(argv[0]); - my_init(); - if (key_cacheing) - init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,IO_SIZE*16,0,0); - get_options(argc,argv); - - exit(run_test("test1")); -} - - -static int run_test(const char *filename) -{ - MI_INFO *file; - int i,j,error,deleted,rec_length,uniques=0; - ha_rows found,row_count; - my_off_t pos; - char record[MAX_REC_LENGTH],key[MAX_REC_LENGTH],read_record[MAX_REC_LENGTH]; - MI_UNIQUEDEF uniquedef; - MI_CREATE_INFO create_info; - - bzero((char*) recinfo,sizeof(recinfo)); - - /* First define 2 columns */ - recinfo[0].type=FIELD_NORMAL; recinfo[0].length=1; /* For NULL bits */ - recinfo[1].type=key_field; - recinfo[1].length= (key_field == FIELD_BLOB ? 4+mi_portable_sizeof_char_ptr : - key_length); - if (key_field == FIELD_VARCHAR) - recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length);; - recinfo[2].type=extra_field; - recinfo[2].length= (extra_field == FIELD_BLOB ? 4 + mi_portable_sizeof_char_ptr : 24); - if (extra_field == FIELD_VARCHAR) - recinfo[2].length+= HA_VARCHAR_PACKLENGTH(recinfo[2].length); - if (opt_unique) - { - recinfo[3].type=FIELD_CHECK; - recinfo[3].length=MI_UNIQUE_HASH_LENGTH; - } - rec_length=recinfo[0].length+recinfo[1].length+recinfo[2].length+ - recinfo[3].length; - - if (key_type == HA_KEYTYPE_VARTEXT1 && - key_length > 255) - key_type= HA_KEYTYPE_VARTEXT2; - - /* Define a key over the first column */ - keyinfo[0].seg=keyseg; - keyinfo[0].keysegs=1; - keyinfo[0].key_alg=HA_KEY_ALG_BTREE; - keyinfo[0].seg[0].type= key_type; - keyinfo[0].seg[0].flag= pack_seg; - keyinfo[0].seg[0].start=1; - keyinfo[0].seg[0].length=key_length; - keyinfo[0].seg[0].null_bit= null_fields ? 2 : 0; - keyinfo[0].seg[0].null_pos=0; - keyinfo[0].seg[0].language= default_charset_info->number; - if (pack_seg & HA_BLOB_PART) - { - keyinfo[0].seg[0].bit_start=4; /* Length of blob length */ - } - keyinfo[0].flag = (uint8) (pack_keys | unique_key); - - bzero((byte*) flags,sizeof(flags)); - if (opt_unique) - { - uint start; - uniques=1; - bzero((char*) &uniquedef,sizeof(uniquedef)); - bzero((char*) uniqueseg,sizeof(uniqueseg)); - uniquedef.seg=uniqueseg; - uniquedef.keysegs=2; - - /* Make a unique over all columns (except first NULL fields) */ - for (i=0, start=1 ; i < 2 ; i++) - { - uniqueseg[i].start=start; - start+=recinfo[i+1].length; - uniqueseg[i].length=recinfo[i+1].length; - uniqueseg[i].language= default_charset_info->number; - } - uniqueseg[0].type= key_type; - uniqueseg[0].null_bit= null_fields ? 2 : 0; - uniqueseg[1].type= HA_KEYTYPE_TEXT; - if (extra_field == FIELD_BLOB) - { - uniqueseg[1].length=0; /* The whole blob */ - uniqueseg[1].bit_start=4; /* long blob */ - uniqueseg[1].flag|= HA_BLOB_PART; - } - else if (extra_field == FIELD_VARCHAR) - uniqueseg[1].flag|= HA_VAR_LENGTH_PART; - } - else - uniques=0; - - if (!silent) - printf("- Creating isam-file\n"); - bzero((char*) &create_info,sizeof(create_info)); - create_info.max_rows=(ulong) (rec_pointer_size ? - (1L << (rec_pointer_size*8))/40 : - 0); - if (mi_create(filename,1,keyinfo,3+opt_unique,recinfo, - uniques, &uniquedef, &create_info, - create_flag)) - goto err; - if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) - goto err; - if (!silent) - printf("- Writing key:s\n"); - - my_errno=0; - row_count=deleted=0; - for (i=49 ; i>=1 ; i-=2 ) - { - if (insert_count-- == 0) { VOID(mi_close(file)) ; exit(0) ; } - j=i%25 +1; - create_record(record,j); - error=mi_write(file,record); - if (!error) - row_count++; - flags[j]=1; - if (verbose || error) - printf("J= %2d mi_write: %d errno: %d\n", j,error,my_errno); - } - - /* Insert 2 rows with null values */ - if (null_fields) - { - create_record(record,0); - error=mi_write(file,record); - if (!error) - row_count++; - if (verbose || error) - printf("J= NULL mi_write: %d errno: %d\n", error,my_errno); - error=mi_write(file,record); - if (!error) - row_count++; - if (verbose || error) - printf("J= NULL mi_write: %d errno: %d\n", error,my_errno); - flags[0]=2; - } - - if (!skip_update) - { - if (opt_unique) - { - if (!silent) - printf("- Checking unique constraint\n"); - create_record(record,j); - if (!mi_write(file,record) || my_errno != HA_ERR_FOUND_DUPP_UNIQUE) - { - printf("unique check failed\n"); - } - } - if (!silent) - printf("- Updating rows\n"); - - /* Update first last row to force extend of file */ - if (mi_rsame(file,read_record,-1)) - { - printf("Can't find last row with mi_rsame\n"); - } - else - { - memcpy(record,read_record,rec_length); - update_record(record); - if (mi_update(file,read_record,record)) - { - printf("Can't update last row: %.*s\n", - keyinfo[0].seg[0].length,read_record+1); - } - } - - /* Read through all rows and update them */ - pos=(my_off_t) 0; - found=0; - while ((error=mi_rrnd(file,read_record,pos)) == 0) - { - if (update_count-- == 0) { VOID(mi_close(file)) ; exit(0) ; } - memcpy(record,read_record,rec_length); - update_record(record); - if (mi_update(file,read_record,record)) - { - printf("Can't update row: %.*s, error: %d\n", - keyinfo[0].seg[0].length,record+1,my_errno); - } - found++; - pos=HA_OFFSET_ERROR; - } - if (found != row_count) - printf("Found %ld of %ld rows\n", found,row_count); - } - - if (!silent) - printf("- Reopening file\n"); - if (mi_close(file)) goto err; - if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) goto err; - if (!skip_update) - { - if (!silent) - printf("- Removing keys\n"); - - for (i=0 ; i <= 10 ; i++) - { - /* testing */ - if (remove_count-- == 0) { VOID(mi_close(file)) ; exit(0) ; } - j=i*2; - if (!flags[j]) - continue; - create_key(key,j); - my_errno=0; - if ((error = mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))) - { - if (verbose || (flags[j] >= 1 || - (error && my_errno != HA_ERR_KEY_NOT_FOUND))) - printf("key: '%.*s' mi_rkey: %3d errno: %3d\n", - (int) key_length,key+test(null_fields),error,my_errno); - } - else - { - error=mi_delete(file,read_record); - if (verbose || error) - printf("key: '%.*s' mi_delete: %3d errno: %3d\n", - (int) key_length, key+test(null_fields), error, my_errno); - if (! error) - { - deleted++; - flags[j]--; - } - } - } - } - if (!silent) - printf("- Reading rows with key\n"); - for (i=0 ; i <= 25 ; i++) - { - create_key(key,i); - my_errno=0; - error=mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT); - if (verbose || - (error == 0 && flags[i] == 0 && unique_key) || - (error && (flags[i] != 0 || my_errno != HA_ERR_KEY_NOT_FOUND))) - { - printf("key: '%.*s' mi_rkey: %3d errno: %3d record: %s\n", - (int) key_length,key+test(null_fields),error,my_errno,record+1); - } - } - - if (!silent) - printf("- Reading rows with position\n"); - for (i=1,found=0 ; i <= 30 ; i++) - { - my_errno=0; - if ((error=mi_rrnd(file,read_record,i == 1 ? 0L : HA_OFFSET_ERROR)) == -1) - { - if (found != row_count-deleted) - printf("Found only %ld of %ld rows\n",found,row_count-deleted); - break; - } - if (!error) - found++; - if (verbose || (error != 0 && error != HA_ERR_RECORD_DELETED && - error != HA_ERR_END_OF_FILE)) - { - printf("pos: %2d mi_rrnd: %3d errno: %3d record: %s\n", - i-1,error,my_errno,read_record+1); - } - } - if (mi_close(file)) goto err; - my_end(MY_CHECK_ERROR); - - return (0); -err: - printf("got error: %3d when using myisam-database\n",my_errno); - return 1; /* skip warning */ -} - - -static void create_key_part(char *key,uint rownr) -{ - if (!unique_key) - rownr&=7; /* Some identical keys */ - if (keyinfo[0].seg[0].type == HA_KEYTYPE_NUM) - { - sprintf(key,"%*d",keyinfo[0].seg[0].length,rownr); - } - else if (keyinfo[0].seg[0].type == HA_KEYTYPE_VARTEXT1 || - keyinfo[0].seg[0].type == HA_KEYTYPE_VARTEXT2) - { /* Alpha record */ - /* Create a key that may be easily packed */ - bfill(key,keyinfo[0].seg[0].length,rownr < 10 ? 'A' : 'B'); - sprintf(key+keyinfo[0].seg[0].length-2,"%-2d",rownr); - if ((rownr & 7) == 0) - { - /* Change the key to force a unpack of the next key */ - bfill(key+3,keyinfo[0].seg[0].length-4,rownr < 10 ? 'a' : 'b'); - } - } - else - { /* Alpha record */ - if (keyinfo[0].seg[0].flag & HA_SPACE_PACK) - sprintf(key,"%-*d",keyinfo[0].seg[0].length,rownr); - else - { - /* Create a key that may be easily packed */ - bfill(key,keyinfo[0].seg[0].length,rownr < 10 ? 'A' : 'B'); - sprintf(key+keyinfo[0].seg[0].length-2,"%-2d",rownr); - if ((rownr & 7) == 0) - { - /* Change the key to force a unpack of the next key */ - key[1]= (rownr < 10 ? 'a' : 'b'); - } - } - } -} - - -static void create_key(char *key,uint rownr) -{ - if (keyinfo[0].seg[0].null_bit) - { - if (rownr == 0) - { - key[0]=1; /* null key */ - key[1]=0; /* Fore easy print of key */ - return; - } - *key++=0; - } - if (keyinfo[0].seg[0].flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART)) - { - uint tmp; - create_key_part(key+2,rownr); - tmp=strlen(key+2); - int2store(key,tmp); - } - else - create_key_part(key,rownr); -} - - -static char blob_key[MAX_REC_LENGTH]; -static char blob_record[MAX_REC_LENGTH+20*20]; - - -static void create_record(char *record,uint rownr) -{ - char *pos; - bzero((char*) record,MAX_REC_LENGTH); - record[0]=1; /* delete marker */ - if (rownr == 0 && keyinfo[0].seg[0].null_bit) - record[0]|=keyinfo[0].seg[0].null_bit; /* Null key */ - - pos=record+1; - if (recinfo[1].type == FIELD_BLOB) - { - uint tmp; - char *ptr; - create_key_part(blob_key,rownr); - tmp=strlen(blob_key); - int4store(pos,tmp); - ptr=blob_key; - memcpy_fixed(pos+4,&ptr,sizeof(char*)); - pos+=recinfo[1].length; - } - else if (recinfo[1].type == FIELD_VARCHAR) - { - uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1); - create_key_part(pos+pack_length,rownr); - tmp= strlen(pos+pack_length); - if (pack_length == 1) - *(uchar*) pos= (uchar) tmp; - else - int2store(pos,tmp); - pos+= recinfo[1].length; - } - else - { - create_key_part(pos,rownr); - pos+=recinfo[1].length; - } - if (recinfo[2].type == FIELD_BLOB) - { - uint tmp; - char *ptr;; - sprintf(blob_record,"... row: %d", rownr); - strappend(blob_record,max(MAX_REC_LENGTH-rownr,10),' '); - tmp=strlen(blob_record); - int4store(pos,tmp); - ptr=blob_record; - memcpy_fixed(pos+4,&ptr,sizeof(char*)); - } - else if (recinfo[2].type == FIELD_VARCHAR) - { - uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1); - sprintf(pos+pack_length, "... row: %d", rownr); - tmp= strlen(pos+pack_length); - if (pack_length == 1) - *(uchar*) pos= (uchar) tmp; - else - int2store(pos,tmp); - } - else - { - sprintf(pos,"... row: %d", rownr); - strappend(pos,recinfo[2].length,' '); - } -} - -/* change row to test re-packing of rows and reallocation of keys */ - -static void update_record(char *record) -{ - char *pos=record+1; - if (recinfo[1].type == FIELD_BLOB) - { - char *column,*ptr; - int length; - length=uint4korr(pos); /* Long blob */ - memcpy_fixed(&column,pos+4,sizeof(char*)); - memcpy(blob_key,column,length); /* Move old key */ - ptr=blob_key; - memcpy_fixed(pos+4,&ptr,sizeof(char*)); /* Store pointer to new key */ - if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM) - my_casedn(default_charset_info,blob_key,length); - pos+=recinfo[1].length; - } - else if (recinfo[1].type == FIELD_VARCHAR) - { - uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1); - uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos); - my_casedn(default_charset_info,pos+pack_length,length); - pos+=recinfo[1].length; - } - else - { - if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM) - my_casedn(default_charset_info,pos,keyinfo[0].seg[0].length); - pos+=recinfo[1].length; - } - - if (recinfo[2].type == FIELD_BLOB) - { - char *column; - int length; - length=uint4korr(pos); - memcpy_fixed(&column,pos+4,sizeof(char*)); - memcpy(blob_record,column,length); - bfill(blob_record+length,20,'.'); /* Make it larger */ - length+=20; - int4store(pos,length); - column=blob_record; - memcpy_fixed(pos+4,&column,sizeof(char*)); - } - else if (recinfo[2].type == FIELD_VARCHAR) - { - /* Second field is longer than 10 characters */ - uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1); - uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos); - bfill(pos+pack_length+length,recinfo[2].length-length-pack_length,'.'); - length=recinfo[2].length-pack_length; - if (pack_length == 1) - *(uchar*) pos= (uchar) length; - else - int2store(pos,length); - } - else - { - bfill(pos+recinfo[2].length-10,10,'.'); - } -} - - -static struct my_option my_long_options[] = -{ - {"checksum", 'c', "Undocumented", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifndef DBUG_OFF - {"debug", '#', "Undocumented", - 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, -#endif - {"delete_rows", 'd', "Undocumented", (gptr*) &remove_count, - (gptr*) &remove_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0}, - {"help", '?', "Display help and exit", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"insert_rows", 'i', "Undocumented", (gptr*) &insert_count, - (gptr*) &insert_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0}, - {"key_alpha", 'a', "Use a key of type HA_KEYTYPE_TEXT", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"key_binary_pack", 'B', "Undocumented", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"key_blob", 'b', "Undocumented", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"key_cache", 'K', "Undocumented", (gptr*) &key_cacheing, - (gptr*) &key_cacheing, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"key_length", 'k', "Undocumented", (gptr*) &key_length, (gptr*) &key_length, - 0, GET_UINT, REQUIRED_ARG, 6, 0, 0, 0, 0, 0}, - {"key_multiple", 'm', "Undocumented", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"key_prefix_pack", 'P', "Undocumented", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"key_space_pack", 'p', "Undocumented", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"key_varchar", 'w', "Test VARCHAR keys", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"null_fields", 'N', "Define fields with NULL", - (gptr*) &null_fields, (gptr*) &null_fields, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, - {"row_fixed_size", 'S', "Undocumented", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"row_pointer_size", 'R', "Undocumented", (gptr*) &rec_pointer_size, - (gptr*) &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"silent", 's', "Undocumented", - (gptr*) &silent, (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"skip_update", 'U', "Undocumented", (gptr*) &skip_update, - (gptr*) &skip_update, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"unique", 'C', "Undocumented", (gptr*) &opt_unique, (gptr*) &opt_unique, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"update_rows", 'u', "Undocumented", (gptr*) &update_count, - (gptr*) &update_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0}, - {"verbose", 'v', "Be more verbose", (gptr*) &verbose, (gptr*) &verbose, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"version", 'V', "Print version number and exit", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} -}; - - -static my_bool -get_one_option(int optid, const struct my_option *opt __attribute__((unused)), - char *argument) -{ - switch(optid) { - case 'a': - key_type= HA_KEYTYPE_TEXT; - break; - case 'c': - create_flag|= HA_CREATE_CHECKSUM; - break; - case 'R': /* Length of record pointer */ - if (rec_pointer_size > 3) - rec_pointer_size=0; - break; - case 'P': - pack_keys= HA_PACK_KEY; /* Use prefix compression */ - break; - case 'B': - pack_keys= HA_BINARY_PACK_KEY; /* Use binary compression */ - break; - case 'S': - if (key_field == FIELD_VARCHAR) - { - create_flag=0; /* Static sized varchar */ - } - else if (key_field != FIELD_BLOB) - { - key_field=FIELD_NORMAL; /* static-size record */ - extra_field=FIELD_NORMAL; - } - break; - case 'p': - pack_keys=HA_PACK_KEY; /* Use prefix + space packing */ - pack_seg=HA_SPACE_PACK; - key_type=HA_KEYTYPE_TEXT; - break; - case 'm': - unique_key=0; - break; - case 'b': - key_field=FIELD_BLOB; /* blob key */ - extra_field= FIELD_BLOB; - pack_seg|= HA_BLOB_PART; - key_type= HA_KEYTYPE_VARTEXT1; - break; - case 'k': - if (key_length < 4 || key_length > MI_MAX_KEY_LENGTH) - { - fprintf(stderr,"Wrong key length\n"); - exit(1); - } - break; - case 'w': - key_field=FIELD_VARCHAR; /* varchar keys */ - extra_field= FIELD_VARCHAR; - key_type= HA_KEYTYPE_VARTEXT1; - pack_seg|= HA_VAR_LENGTH_PART; - create_flag|= HA_PACK_RECORD; - break; - case 'K': /* Use key cacheing */ - key_cacheing=1; - break; - case 'V': - printf("test1 Ver 1.2 \n"); - exit(0); - case '#': - DEBUGGER_ON; - DBUG_PUSH (argument); - break; - case '?': - usage(); - exit(1); - } - return 0; -} - - -/* Read options */ - -static void get_options(int argc, char *argv[]) -{ - int ho_error; - - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) - exit(ho_error); - - return; -} /* get options */ - - -static void usage() -{ - printf("Usage: %s [options]\n\n", my_progname); - my_print_help(my_long_options); - my_print_variables(my_long_options); -} diff --git a/myisam/mi_test2.c b/myisam/mi_test2.c deleted file mode 100644 index 95c8ce56a13..00000000000 --- a/myisam/mi_test2.c +++ /dev/null @@ -1,1048 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Test av isam-databas: stor test */ - -#ifndef USE_MY_FUNC /* We want to be able to dbug this !! */ -#define USE_MY_FUNC -#endif -#ifdef DBUG_OFF -#undef DBUG_OFF -#endif -#ifndef SAFEMALLOC -#define SAFEMALLOC -#endif -#include "myisamdef.h" -#include <m_ctype.h> - -#define STANDARD_LENGTH 37 -#define MYISAM_KEYS 6 -#define MAX_PARTS 4 -#if !defined(MSDOS) && !defined(labs) -#define labs(a) abs(a) -#endif - -static void get_options(int argc, char *argv[]); -static uint rnd(uint max_value); -static void fix_length(byte *record,uint length); -static void put_blob_in_record(char *blob_pos,char **blob_buffer); -static void copy_key(struct st_myisam_info *info,uint inx, - uchar *record,uchar *key); - -static int verbose=0,testflag=0, - first_key=0,async_io=0,key_cacheing=0,write_cacheing=0,locking=0, - rec_pointer_size=0,pack_fields=1,use_log=0,silent=0, - opt_quick_mode=0; -static int pack_seg=HA_SPACE_PACK,pack_type=HA_PACK_KEY,remove_count=-1, - create_flag=0; -static ulong key_cache_size=IO_SIZE*16; -static uint key_cache_block_size= KEY_CACHE_BLOCK_SIZE; - -static uint keys=MYISAM_KEYS,recant=1000; -static uint use_blob=0; -static uint16 key1[1001],key3[5000]; -static char record[300],record2[300],key[100],key2[100], - read_record[300],read_record2[300],read_record3[300]; -static HA_KEYSEG glob_keyseg[MYISAM_KEYS][MAX_PARTS]; - - /* Test program */ - -int main(int argc, char *argv[]) -{ - uint i; - int j,n1,n2,n3,error,k; - uint write_count,update,dupp_keys,opt_delete,start,length,blob_pos, - reclength,ant,found_parts; - my_off_t lastpos; - ha_rows range_records,records; - MI_INFO *file; - MI_KEYDEF keyinfo[10]; - MI_COLUMNDEF recinfo[10]; - MI_ISAMINFO info; - const char *filename; - char *blob_buffer; - MI_CREATE_INFO create_info; - MY_INIT(argv[0]); - - filename= "test2"; - get_options(argc,argv); - if (! async_io) - my_disable_async_io=1; - - reclength=STANDARD_LENGTH+60+(use_blob ? 8 : 0); - blob_pos=STANDARD_LENGTH+60; - keyinfo[0].seg= &glob_keyseg[0][0]; - keyinfo[0].seg[0].start=0; - keyinfo[0].seg[0].length=6; - keyinfo[0].seg[0].type=HA_KEYTYPE_TEXT; - keyinfo[0].seg[0].language= default_charset_info->number; - keyinfo[0].seg[0].flag=(uint8) pack_seg; - keyinfo[0].seg[0].null_bit=0; - keyinfo[0].seg[0].null_pos=0; - keyinfo[0].key_alg=HA_KEY_ALG_BTREE; - keyinfo[0].keysegs=1; - keyinfo[0].flag = pack_type; - keyinfo[1].seg= &glob_keyseg[1][0]; - keyinfo[1].seg[0].start=7; - keyinfo[1].seg[0].length=6; - keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY; - keyinfo[1].seg[0].flag=0; - keyinfo[1].seg[0].null_bit=0; - keyinfo[1].seg[0].null_pos=0; - keyinfo[1].seg[1].start=0; /* two part key */ - keyinfo[1].seg[1].length=6; - keyinfo[1].seg[1].type=HA_KEYTYPE_NUM; - keyinfo[1].seg[1].flag=HA_REVERSE_SORT; - keyinfo[1].seg[1].null_bit=0; - keyinfo[1].seg[1].null_pos=0; - keyinfo[1].key_alg=HA_KEY_ALG_BTREE; - keyinfo[1].keysegs=2; - keyinfo[1].flag =0; - keyinfo[2].seg= &glob_keyseg[2][0]; - keyinfo[2].seg[0].start=12; - keyinfo[2].seg[0].length=8; - keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY; - keyinfo[2].seg[0].flag=HA_REVERSE_SORT; - keyinfo[2].seg[0].null_bit=0; - keyinfo[2].seg[0].null_pos=0; - keyinfo[2].key_alg=HA_KEY_ALG_BTREE; - keyinfo[2].keysegs=1; - keyinfo[2].flag =HA_NOSAME; - keyinfo[3].seg= &glob_keyseg[3][0]; - keyinfo[3].seg[0].start=0; - keyinfo[3].seg[0].length=reclength-(use_blob ? 8 : 0); - keyinfo[3].seg[0].type=HA_KEYTYPE_TEXT; - keyinfo[3].seg[0].language=default_charset_info->number; - keyinfo[3].seg[0].flag=(uint8) pack_seg; - keyinfo[3].seg[0].null_bit=0; - keyinfo[3].seg[0].null_pos=0; - keyinfo[3].key_alg=HA_KEY_ALG_BTREE; - keyinfo[3].keysegs=1; - keyinfo[3].flag = pack_type; - keyinfo[4].seg= &glob_keyseg[4][0]; - keyinfo[4].seg[0].start=0; - keyinfo[4].seg[0].length=5; - keyinfo[4].seg[0].type=HA_KEYTYPE_TEXT; - keyinfo[4].seg[0].language=default_charset_info->number; - keyinfo[4].seg[0].flag=0; - keyinfo[4].seg[0].null_bit=0; - keyinfo[4].seg[0].null_pos=0; - keyinfo[4].key_alg=HA_KEY_ALG_BTREE; - keyinfo[4].keysegs=1; - keyinfo[4].flag = pack_type; - keyinfo[5].seg= &glob_keyseg[5][0]; - keyinfo[5].seg[0].start=0; - keyinfo[5].seg[0].length=4; - keyinfo[5].seg[0].type=HA_KEYTYPE_TEXT; - keyinfo[5].seg[0].language=default_charset_info->number; - keyinfo[5].seg[0].flag=pack_seg; - keyinfo[5].seg[0].null_bit=0; - keyinfo[5].seg[0].null_pos=0; - keyinfo[5].key_alg=HA_KEY_ALG_BTREE; - keyinfo[5].keysegs=1; - keyinfo[5].flag = pack_type; - - recinfo[0].type=pack_fields ? FIELD_SKIP_PRESPACE : 0; - recinfo[0].length=7; - recinfo[0].null_bit=0; - recinfo[0].null_pos=0; - recinfo[1].type=pack_fields ? FIELD_SKIP_PRESPACE : 0; - recinfo[1].length=5; - recinfo[1].null_bit=0; - recinfo[1].null_pos=0; - recinfo[2].type=pack_fields ? FIELD_SKIP_PRESPACE : 0; - recinfo[2].length=9; - recinfo[2].null_bit=0; - recinfo[2].null_pos=0; - recinfo[3].type=FIELD_NORMAL; - recinfo[3].length=STANDARD_LENGTH-7-5-9-4; - recinfo[3].null_bit=0; - recinfo[3].null_pos=0; - recinfo[4].type=pack_fields ? FIELD_SKIP_ZERO : 0; - recinfo[4].length=4; - recinfo[4].null_bit=0; - recinfo[4].null_pos=0; - recinfo[5].type=pack_fields ? FIELD_SKIP_ENDSPACE : 0; - recinfo[5].length=60; - recinfo[5].null_bit=0; - recinfo[5].null_pos=0; - if (use_blob) - { - recinfo[6].type=FIELD_BLOB; - recinfo[6].length=4+mi_portable_sizeof_char_ptr; - recinfo[6].null_bit=0; - recinfo[6].null_pos=0; - } - - write_count=update=dupp_keys=opt_delete=0; - blob_buffer=0; - - for (i=1000 ; i>0 ; i--) key1[i]=0; - for (i=4999 ; i>0 ; i--) key3[i]=0; - - if (!silent) - printf("- Creating isam-file\n"); - /* DBUG_PUSH(""); */ - /* my_delete(filename,MYF(0)); */ /* Remove old locks under gdb */ - file= 0; - bzero((char*) &create_info,sizeof(create_info)); - create_info.max_rows=(ha_rows) (rec_pointer_size ? - (1L << (rec_pointer_size*8))/ - reclength : 0); - create_info.reloc_rows=(ha_rows) 100; - if (mi_create(filename,keys,&keyinfo[first_key], - use_blob ? 7 : 6, &recinfo[0], - 0,(MI_UNIQUEDEF*) 0, - &create_info,create_flag)) - goto err; - if (use_log) - mi_log(1); - if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) - goto err; - if (!silent) - printf("- Writing key:s\n"); - if (key_cacheing) - init_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size,0,0); - if (locking) - mi_lock_database(file,F_WRLCK); - if (write_cacheing) - mi_extra(file,HA_EXTRA_WRITE_CACHE,0); - if (opt_quick_mode) - mi_extra(file,HA_EXTRA_QUICK,0); - - for (i=0 ; i < recant ; i++) - { - n1=rnd(1000); n2=rnd(100); n3=rnd(5000); - sprintf(record,"%6d:%4d:%8d:Pos: %4d ",n1,n2,n3,write_count); - int4store(record+STANDARD_LENGTH-4,(long) i); - fix_length(record,(uint) STANDARD_LENGTH+rnd(60)); - put_blob_in_record(record+blob_pos,&blob_buffer); - DBUG_PRINT("test",("record: %d",i)); - - if (mi_write(file,record)) - { - if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0) - { - printf("Error: %d in write at record: %d\n",my_errno,i); - goto err; - } - if (verbose) printf(" Double key: %d\n",n3); - } - else - { - if (key3[n3] == 1 && first_key <3 && first_key+keys >= 3) - { - printf("Error: Didn't get error when writing second key: '%8d'\n",n3); - goto err; - } - write_count++; key1[n1]++; key3[n3]=1; - } - - /* Check if we can find key without flushing database */ - if (i == recant/2) - { - for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ; - if (!j) - for (j=999 ; j>0 && key1[j] == 0 ; j--) ; - sprintf(key,"%6d",j); - if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) - { - printf("Test in loop: Can't find key: \"%s\"\n",key); - goto err; - } - } - } - if (testflag==1) goto end; - - if (write_cacheing) - { - if (mi_extra(file,HA_EXTRA_NO_CACHE,0)) - { - puts("got error from mi_extra(HA_EXTRA_NO_CACHE)"); - goto end; - } - } - if (key_cacheing) - resize_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size*2,0,0); - - if (!silent) - printf("- Delete\n"); - for (i=0 ; i<recant/10 ; i++) - { - for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ; - if (j != 0) - { - sprintf(key,"%6d",j); - if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) - { - printf("can't find key1: \"%s\"\n",key); - goto err; - } - if (opt_delete == (uint) remove_count) /* While testing */ - goto end; - if (mi_delete(file,read_record)) - { - printf("error: %d; can't delete record: \"%s\"\n", my_errno,read_record); - goto err; - } - opt_delete++; - key1[atoi(read_record+keyinfo[0].seg[0].start)]--; - key3[atoi(read_record+keyinfo[2].seg[0].start)]=0; - } - else - puts("Warning: Skipping delete test because no dupplicate keys"); - } - if (testflag==2) goto end; - - if (!silent) - printf("- Update\n"); - for (i=0 ; i<recant/10 ; i++) - { - n1=rnd(1000); n2=rnd(100); n3=rnd(5000); - sprintf(record2,"%6d:%4d:%8d:XXX: %4d ",n1,n2,n3,update); - int4store(record2+STANDARD_LENGTH-4,(long) i); - fix_length(record2,(uint) STANDARD_LENGTH+rnd(60)); - - for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ; - if (j != 0) - { - sprintf(key,"%6d",j); - if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) - { - printf("can't find key1: \"%s\"\n",key); - goto err; - } - if (use_blob) - { - if (i & 1) - put_blob_in_record(record+blob_pos,&blob_buffer); - else - bmove(record+blob_pos,read_record+blob_pos,8); - } - if (mi_update(file,read_record,record2)) - { - if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0) - { - printf("error: %d; can't update:\nFrom: \"%s\"\nTo: \"%s\"\n", - my_errno,read_record,record2); - goto err; - } - if (verbose) - printf("Double key when tried to update:\nFrom: \"%s\"\nTo: \"%s\"\n",record,record2); - } - else - { - key1[atoi(read_record+keyinfo[0].seg[0].start)]--; - key3[atoi(read_record+keyinfo[2].seg[0].start)]=0; - key1[n1]++; key3[n3]=1; - update++; - } - } - } - if (testflag == 3) - goto end; - - for (i=999, dupp_keys=j=0 ; i>0 ; i--) - { - if (key1[i] > dupp_keys) - { - dupp_keys=key1[i]; j=i; - } - } - sprintf(key,"%6d",j); - start=keyinfo[0].seg[0].start; - length=keyinfo[0].seg[0].length; - if (dupp_keys) - { - if (!silent) - printf("- Same key: first - next -> last - prev -> first\n"); - DBUG_PRINT("progpos",("first - next -> last - prev -> first")); - if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys); - - if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) - goto err; - if (mi_rsame(file,read_record2,-1)) - goto err; - if (memcmp(read_record,read_record2,reclength) != 0) - { - printf("mi_rsame didn't find same record\n"); - goto end; - } - info.recpos=mi_position(file); - if (mi_rfirst(file,read_record2,0) || - mi_rsame_with_pos(file,read_record2,0,info.recpos) || - memcmp(read_record,read_record2,reclength) != 0) - { - printf("mi_rsame_with_pos didn't find same record\n"); - goto end; - } - { - int skr=mi_rnext(file,read_record2,0); - if ((skr && my_errno != HA_ERR_END_OF_FILE) || - mi_rprev(file,read_record2,-1) || - memcmp(read_record,read_record2,reclength) != 0) - { - printf("mi_rsame_with_pos lost position\n"); - goto end; - } - } - ant=1; - while (mi_rnext(file,read_record2,0) == 0 && - memcmp(read_record2+start,key,length) == 0) ant++; - if (ant != dupp_keys) - { - printf("next: Found: %d keys of %d\n",ant,dupp_keys); - goto end; - } - ant=0; - while (mi_rprev(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; - if (ant != dupp_keys) - { - printf("prev: Found: %d records of %d\n",ant,dupp_keys); - goto end; - } - - /* Check of mi_rnext_same */ - if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) - goto err; - ant=1; - while (!mi_rnext_same(file,read_record3) && ant < dupp_keys+10) - ant++; - if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE) - { - printf("mi_rnext_same: Found: %d records of %d\n",ant,dupp_keys); - goto end; - } - } - - if (!silent) - printf("- All keys: first - next -> last - prev -> first\n"); - DBUG_PRINT("progpos",("All keys: first - next -> last - prev -> first")); - ant=1; - if (mi_rfirst(file,read_record,0)) - { - printf("Can't find first record\n"); - goto end; - } - while ((error=mi_rnext(file,read_record3,0)) == 0 && ant < write_count+10) - ant++; - if (ant != write_count - opt_delete || error != HA_ERR_END_OF_FILE) - { - printf("next: I found: %d records of %d (error: %d)\n", - ant, write_count - opt_delete, error); - goto end; - } - if (mi_rlast(file,read_record2,0) || - bcmp(read_record2,read_record3,reclength)) - { - printf("Can't find last record\n"); - DBUG_DUMP("record2",(byte*) read_record2,reclength); - DBUG_DUMP("record3",(byte*) read_record3,reclength); - goto end; - } - ant=1; - while (mi_rprev(file,read_record3,0) == 0 && ant < write_count+10) - ant++; - if (ant != write_count - opt_delete) - { - printf("prev: I found: %d records of %d\n",ant,write_count); - goto end; - } - if (bcmp(read_record,read_record3,reclength)) - { - printf("Can't find first record\n"); - goto end; - } - - if (!silent) - printf("- Test if: Read first - next - prev - prev - next == first\n"); - DBUG_PRINT("progpos",("- Read first - next - prev - prev - next == first")); - if (mi_rfirst(file,read_record,0) || - mi_rnext(file,read_record3,0) || - mi_rprev(file,read_record3,0) || - mi_rprev(file,read_record3,0) == 0 || - mi_rnext(file,read_record3,0)) - goto err; - if (bcmp(read_record,read_record3,reclength) != 0) - printf("Can't find first record\n"); - - if (!silent) - printf("- Test if: Read last - prev - next - next - prev == last\n"); - DBUG_PRINT("progpos",("Read last - prev - next - next - prev == last")); - if (mi_rlast(file,read_record2,0) || - mi_rprev(file,read_record3,0) || - mi_rnext(file,read_record3,0) || - mi_rnext(file,read_record3,0) == 0 || - mi_rprev(file,read_record3,0)) - goto err; - if (bcmp(read_record2,read_record3,reclength)) - printf("Can't find last record\n"); - - if (!silent) - puts("- Test read key-part"); - strmov(key2,key); - for(i=strlen(key2) ; i-- > 1 ;) - { - key2[i]=0; - - /* The following row is just to catch some bugs in the key code */ - bzero((char*) file->lastkey,file->s->base.max_key_length*2); - if (mi_rkey(file,read_record,0,key2,(uint) i,HA_READ_PREFIX)) - goto err; - if (bcmp(read_record+start,key,(uint) i)) - { - puts("Didn't find right record"); - goto end; - } - } - if (dupp_keys > 2) - { - if (!silent) - printf("- Read key (first) - next - delete - next -> last\n"); - DBUG_PRINT("progpos",("first - next - delete - next -> last")); - if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) goto err; - if (mi_rnext(file,read_record3,0)) goto err; - if (mi_delete(file,read_record3)) goto err; - opt_delete++; - ant=1; - while (mi_rnext(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; - if (ant != dupp_keys-1) - { - printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-1); - goto end; - } - } - if (dupp_keys>4) - { - if (!silent) - printf("- Read last of key - prev - delete - prev -> first\n"); - DBUG_PRINT("progpos",("last - prev - delete - prev -> first")); - if (mi_rprev(file,read_record3,0)) goto err; - if (mi_rprev(file,read_record3,0)) goto err; - if (mi_delete(file,read_record3)) goto err; - opt_delete++; - ant=1; - while (mi_rprev(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; - if (ant != dupp_keys-2) - { - printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-2); - goto end; - } - } - if (dupp_keys > 6) - { - if (!silent) - printf("- Read first - delete - next -> last\n"); - DBUG_PRINT("progpos",("first - delete - next -> last")); - if (mi_rkey(file,read_record3,0,key,0,HA_READ_KEY_EXACT)) goto err; - if (mi_delete(file,read_record3)) goto err; - opt_delete++; - ant=1; - if (mi_rnext(file,read_record,0)) - goto err; /* Skall finnas poster */ - while (mi_rnext(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; - if (ant != dupp_keys-3) - { - printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-3); - goto end; - } - - if (!silent) - printf("- Read last - delete - prev -> first\n"); - DBUG_PRINT("progpos",("last - delete - prev -> first")); - if (mi_rprev(file,read_record3,0)) goto err; - if (mi_delete(file,read_record3)) goto err; - opt_delete++; - ant=0; - while (mi_rprev(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; - if (ant != dupp_keys-4) - { - printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-4); - goto end; - } - } - - if (!silent) - puts("- Test if: Read rrnd - same"); - DBUG_PRINT("progpos",("Read rrnd - same")); - for (i=0 ; i < write_count ; i++) - { - if (mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR) == 0) - break; - } - if (i == write_count) - goto err; - - bmove(read_record2,read_record,reclength); - for (i=min(2,keys) ; i-- > 0 ;) - { - if (mi_rsame(file,read_record2,(int) i)) goto err; - if (bcmp(read_record,read_record2,reclength) != 0) - { - printf("is_rsame didn't find same record\n"); - goto end; - } - } - if (!silent) - puts("- Test mi_records_in_range"); - mi_status(file,&info,HA_STATUS_VARIABLE); - for (i=0 ; i < info.keys ; i++) - { - key_range min_key, max_key; - if (mi_rfirst(file,read_record,(int) i) || - mi_rlast(file,read_record2,(int) i)) - goto err; - copy_key(file,(uint) i,(uchar*) read_record,(uchar*) key); - copy_key(file,(uint) i,(uchar*) read_record2,(uchar*) key2); - min_key.key= key; - min_key.length= USE_WHOLE_KEY; - min_key.flag= HA_READ_KEY_EXACT; - max_key.key= key2; - max_key.length= USE_WHOLE_KEY; - max_key.flag= HA_READ_AFTER_KEY; - - range_records= mi_records_in_range(file,(int) i, &min_key, &max_key); - if (range_records < info.records*8/10 || - range_records > info.records*12/10) - { - printf("mi_records_range returned %ld; Should be about %ld\n", - (long) range_records,(long) info.records); - goto end; - } - if (verbose) - { - printf("mi_records_range returned %ld; Exact is %ld (diff: %4.2g %%)\n", - (long) range_records, (long) info.records, - labs((long) range_records - (long) info.records)*100.0/ - info.records); - } - } - for (i=0 ; i < 5 ; i++) - { - for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ; - for (k=rnd(1000)+1 ; k>0 && key1[k] == 0 ; k--) ; - if (j != 0 && k != 0) - { - key_range min_key, max_key; - if (j > k) - swap_variables(int, j, k); - sprintf(key,"%6d",j); - sprintf(key2,"%6d",k); - - min_key.key= key; - min_key.length= USE_WHOLE_KEY; - min_key.flag= HA_READ_AFTER_KEY; - max_key.key= key2; - max_key.length= USE_WHOLE_KEY; - max_key.flag= HA_READ_BEFORE_KEY; - range_records= mi_records_in_range(file, 0, &min_key, &max_key); - records=0; - for (j++ ; j < k ; j++) - records+=key1[j]; - if ((long) range_records < (long) records*7/10-2 || - (long) range_records > (long) records*14/10+2) - { - printf("mi_records_range for key: %d returned %lu; Should be about %lu\n", - i, (ulong) range_records, (ulong) records); - goto end; - } - if (verbose && records) - { - printf("mi_records_range returned %lu; Exact is %lu (diff: %4.2g %%)\n", - (ulong) range_records, (ulong) records, - labs((long) range_records-(long) records)*100.0/records); - - } - } - } - - if (!silent) - printf("- mi_info\n"); - mi_status(file,&info,HA_STATUS_VARIABLE | HA_STATUS_CONST); - if (info.records != write_count-opt_delete || info.deleted > opt_delete + update - || info.keys != keys) - { - puts("Wrong info from mi_info"); - printf("Got: records: %lu delete: %lu i_keys: %d\n", - (ulong) info.records, (ulong) info.deleted, info.keys); - } - if (verbose) - { - char buff[80]; - get_date(buff,3,info.create_time); - printf("info: Created %s\n",buff); - get_date(buff,3,info.check_time); - printf("info: checked %s\n",buff); - get_date(buff,3,info.update_time); - printf("info: Modified %s\n",buff); - } - - mi_panic(HA_PANIC_WRITE); - mi_panic(HA_PANIC_READ); - if (mi_is_changed(file)) - puts("Warning: mi_is_changed reported that datafile was changed"); - - if (!silent) - printf("- mi_extra(CACHE) + mi_rrnd.... + mi_extra(NO_CACHE)\n"); - if (mi_extra(file,HA_EXTRA_RESET,0) || mi_extra(file,HA_EXTRA_CACHE,0)) - { - if (locking || (!use_blob && !pack_fields)) - { - puts("got error from mi_extra(HA_EXTRA_CACHE)"); - goto end; - } - } - ant=0; - while ((error=mi_rrnd(file,record,HA_OFFSET_ERROR)) != HA_ERR_END_OF_FILE && - ant < write_count + 10) - ant+= error ? 0 : 1; - if (ant != write_count-opt_delete) - { - printf("rrnd with cache: I can only find: %d records of %d\n", - ant,write_count-opt_delete); - goto end; - } - if (mi_extra(file,HA_EXTRA_NO_CACHE,0)) - { - puts("got error from mi_extra(HA_EXTRA_NO_CACHE)"); - goto end; - } - - ant=0; - mi_scan_init(file); - while ((error=mi_scan(file,record)) != HA_ERR_END_OF_FILE && - ant < write_count + 10) - ant+= error ? 0 : 1; - if (ant != write_count-opt_delete) - { - printf("scan with cache: I can only find: %d records of %d\n", - ant,write_count-opt_delete); - goto end; - } - - if (testflag == 4) goto end; - - if (!silent) - printf("- Removing keys\n"); - DBUG_PRINT("progpos",("Removing keys")); - lastpos = HA_OFFSET_ERROR; - /* DBUG_POP(); */ - mi_extra(file,HA_EXTRA_RESET,0); - found_parts=0; - while ((error=mi_rrnd(file,read_record,HA_OFFSET_ERROR)) != - HA_ERR_END_OF_FILE) - { - info.recpos=mi_position(file); - if (lastpos >= info.recpos && lastpos != HA_OFFSET_ERROR) - { - printf("mi_rrnd didn't advance filepointer; old: %ld, new: %ld\n", - (long) lastpos, (long) info.recpos); - goto err; - } - lastpos=info.recpos; - if (error == 0) - { - if (opt_delete == (uint) remove_count) /* While testing */ - goto end; - if (mi_rsame(file,read_record,-1)) - { - printf("can't find record %lx\n",(long) info.recpos); - goto err; - } - if (use_blob) - { - ulong blob_length,pos; - uchar *ptr; - longget(blob_length,read_record+blob_pos+4); - ptr=(uchar*) blob_length; - longget(blob_length,read_record+blob_pos); - for (pos=0 ; pos < blob_length ; pos++) - { - if (ptr[pos] != (uchar) (blob_length+pos)) - { - printf("found blob with wrong info at %ld\n",(long) lastpos); - use_blob=0; - break; - } - } - } - if (mi_delete(file,read_record)) - { - printf("can't delete record: %6.6s, delete_count: %d\n", - read_record, opt_delete); - goto err; - } - opt_delete++; - } - else - found_parts++; - } - if (my_errno != HA_ERR_END_OF_FILE && my_errno != HA_ERR_RECORD_DELETED) - printf("error: %d from mi_rrnd\n",my_errno); - if (write_count != opt_delete) - { - printf("Deleted only %d of %d records (%d parts)\n",opt_delete,write_count, - found_parts); - goto err; - } -end: - if (mi_close(file)) - goto err; - mi_panic(HA_PANIC_CLOSE); /* Should close log */ - if (!silent) - { - printf("\nFollowing test have been made:\n"); - printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete); - if (rec_pointer_size) - printf("Record pointer size: %d\n",rec_pointer_size); - printf("myisam_block_size: %u\n", myisam_block_size); - if (key_cacheing) - { - puts("Key cache used"); - printf("key_cache_block_size: %u\n", key_cache_block_size); - if (write_cacheing) - puts("Key cache resized"); - } - if (write_cacheing) - puts("Write cacheing used"); - if (write_cacheing) - puts("quick mode"); - if (async_io && locking) - puts("Asyncron io with locking used"); - else if (locking) - puts("Locking used"); - if (use_blob) - puts("blobs used"); -#if 0 - printf("key cache status: \n\ -blocks used:%10lu\n\ -w_requests: %10lu\n\ -writes: %10lu\n\ -r_requests: %10lu\n\ -reads: %10lu\n", - my_blocks_used, - my_cache_w_requests, my_cache_write, - my_cache_r_requests, my_cache_read); -#endif - } - end_key_cache(dflt_key_cache,1); - if (blob_buffer) - my_free(blob_buffer,MYF(0)); - my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO); - return(0); -err: - printf("got error: %d when using MyISAM-database\n",my_errno); - if (file) - VOID(mi_close(file)); - return(1); -} /* main */ - - - /* l{ser optioner */ - /* OBS! intierar endast DEBUG - ingen debuggning h{r ! */ - -static void get_options(int argc, char **argv) -{ - char *pos,*progname; - DEBUGGER_OFF; - - progname= argv[0]; - - while (--argc >0 && *(pos = *(++argv)) == '-' ) { - switch(*++pos) { - case 'B': - pack_type= HA_BINARY_PACK_KEY; - break; - case 'b': - use_blob=1; - break; - case 'K': /* Use key cacheing */ - key_cacheing=1; - if (*++pos) - key_cache_size=atol(pos); - break; - case 'W': /* Use write cacheing */ - write_cacheing=1; - if (*++pos) - my_default_record_cache_size=atoi(pos); - break; - case 'd': - remove_count= atoi(++pos); - break; - case 'i': - if (*++pos) - srand(atoi(pos)); - break; - case 'l': - use_log=1; - break; - case 'L': - locking=1; - break; - case 'A': /* use asyncron io */ - async_io=1; - if (*++pos) - my_default_record_cache_size=atoi(pos); - break; - case 'v': /* verbose */ - verbose=1; - break; - case 'm': /* records */ - if ((recant=atoi(++pos)) < 10) - { - fprintf(stderr,"record count must be >= 10\n"); - exit(1); - } - break; - case 'e': /* myisam_block_length */ - if ((myisam_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH || - myisam_block_size > MI_MAX_KEY_BLOCK_LENGTH) - { - fprintf(stderr,"Wrong myisam_block_length\n"); - exit(1); - } - myisam_block_size=1 << my_bit_log2(myisam_block_size); - break; - case 'E': /* myisam_block_length */ - if ((key_cache_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH || - key_cache_block_size > MI_MAX_KEY_BLOCK_LENGTH) - { - fprintf(stderr,"Wrong key_cache_block_size\n"); - exit(1); - } - key_cache_block_size=1 << my_bit_log2(key_cache_block_size); - break; - case 'f': - if ((first_key=atoi(++pos)) < 0 || first_key >= MYISAM_KEYS) - first_key=0; - break; - case 'k': - if ((keys=(uint) atoi(++pos)) < 1 || - keys > (uint) (MYISAM_KEYS-first_key)) - keys=MYISAM_KEYS-first_key; - break; - case 'P': - pack_type=0; /* Don't use DIFF_LENGTH */ - pack_seg=0; - break; - case 'R': /* Length of record pointer */ - rec_pointer_size=atoi(++pos); - if (rec_pointer_size > 7) - rec_pointer_size=0; - break; - case 'S': - pack_fields=0; /* Static-length-records */ - break; - case 's': - silent=1; - break; - case 't': - testflag=atoi(++pos); /* testmod */ - break; - case 'q': - opt_quick_mode=1; - break; - case 'c': - create_flag|= HA_CREATE_CHECKSUM; - break; - case 'D': - create_flag|=HA_CREATE_DELAY_KEY_WRITE; - break; - case '?': - case 'I': - case 'V': - printf("%s Ver 1.2 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE); - puts("By Monty, for your professional use\n"); - printf("Usage: %s [-?AbBcDIKLPRqSsVWltv] [-k#] [-f#] [-m#] [-e#] [-E#] [-t#]\n", - progname); - exit(0); - case '#': - DEBUGGER_ON; - DBUG_PUSH (++pos); - break; - default: - printf("Illegal option: '%c'\n",*pos); - break; - } - } - return; -} /* get options */ - - /* Get a random value 0 <= x <= n */ - -static uint rnd(uint max_value) -{ - return (uint) ((rand() & 32767)/32767.0*max_value); -} /* rnd */ - - - /* Create a variable length record */ - -static void fix_length(byte *rec, uint length) -{ - bmove(rec+STANDARD_LENGTH, - "0123456789012345678901234567890123456789012345678901234567890", - length-STANDARD_LENGTH); - strfill(rec+length,STANDARD_LENGTH+60-length,' '); -} /* fix_length */ - - - /* Put maybe a blob in record */ - -static void put_blob_in_record(char *blob_pos, char **blob_buffer) -{ - ulong i,length; - if (use_blob) - { - if (rnd(10) == 0) - { - if (! *blob_buffer && - !(*blob_buffer=my_malloc((uint) use_blob,MYF(MY_WME)))) - { - use_blob=0; - return; - } - length=rnd(use_blob); - for (i=0 ; i < length ; i++) - (*blob_buffer)[i]=(char) (length+i); - int4store(blob_pos,length); - memcpy_fixed(blob_pos+4,(char*) blob_buffer,sizeof(char*)); - } - else - { - int4store(blob_pos,0); - } - } - return; -} - - -static void copy_key(MI_INFO *info,uint inx,uchar *rec,uchar *key_buff) -{ - HA_KEYSEG *keyseg; - - for (keyseg=info->s->keyinfo[inx].seg ; keyseg->type ; keyseg++) - { - memcpy(key_buff,rec+keyseg->start,(size_t) keyseg->length); - key_buff+=keyseg->length; - } - return; -} diff --git a/myisam/mi_test3.c b/myisam/mi_test3.c deleted file mode 100644 index be4277cc65c..00000000000 --- a/myisam/mi_test3.c +++ /dev/null @@ -1,502 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Test av locking */ - -#ifndef __NETWARE__ - -#include "myisam.h" -#include <sys/types.h> -#ifdef HAVE_SYS_WAIT_H -# include <sys/wait.h> -#endif -#ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) -#endif -#ifndef WIFEXITED -# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif - - -#if defined(HAVE_LRAND48) -#define rnd(X) (lrand48() % X) -#define rnd_init(X) srand48(X) -#else -#define rnd(X) (random() % X) -#define rnd_init(X) srandom(X) -#endif - - -const char *filename= "test3"; -uint tests=10,forks=10,key_cacheing=0,use_log=0; - -static void get_options(int argc, char *argv[]); -void start_test(int id); -int test_read(MI_INFO *,int),test_write(MI_INFO *,int,int), - test_update(MI_INFO *,int,int),test_rrnd(MI_INFO *,int); - -struct record { - char id[8]; - char nr[4]; - char text[10]; -} record; - - -int main(int argc,char **argv) -{ - int status,wait_ret; - uint i=0; - MI_KEYDEF keyinfo[10]; - MI_COLUMNDEF recinfo[10]; - HA_KEYSEG keyseg[10][2]; - MY_INIT(argv[0]); - get_options(argc,argv); - - bzero((char*) keyinfo,sizeof(keyinfo)); - bzero((char*) recinfo,sizeof(recinfo)); - bzero((char*) keyseg,sizeof(keyseg)); - keyinfo[0].seg= &keyseg[0][0]; - keyinfo[0].seg[0].start=0; - keyinfo[0].seg[0].length=8; - keyinfo[0].seg[0].type=HA_KEYTYPE_TEXT; - keyinfo[0].seg[0].flag=HA_SPACE_PACK; - keyinfo[0].key_alg=HA_KEY_ALG_BTREE; - keyinfo[0].keysegs=1; - keyinfo[0].flag = (uint8) HA_PACK_KEY; - keyinfo[1].seg= &keyseg[1][0]; - keyinfo[1].seg[0].start=8; - keyinfo[1].seg[0].length=4; /* Long is always 4 in myisam */ - keyinfo[1].seg[0].type=HA_KEYTYPE_LONG_INT; - keyinfo[1].seg[0].flag=0; - keyinfo[1].key_alg=HA_KEY_ALG_BTREE; - keyinfo[1].keysegs=1; - keyinfo[1].flag =HA_NOSAME; - - recinfo[0].type=0; - recinfo[0].length=sizeof(record.id); - recinfo[1].type=0; - recinfo[1].length=sizeof(record.nr); - recinfo[2].type=0; - recinfo[2].length=sizeof(record.text); - - puts("- Creating myisam-file"); - my_delete(filename,MYF(0)); /* Remove old locks under gdb */ - if (mi_create(filename,2,&keyinfo[0],2,&recinfo[0],0,(MI_UNIQUEDEF*) 0, - (MI_CREATE_INFO*) 0,0)) - exit(1); - - rnd_init(0); - printf("- Starting %d processes\n",forks); fflush(stdout); - for (i=0 ; i < forks; i++) - { - if (!fork()) - { - start_test(i+1); - sleep(1); - return 0; - } - VOID(rnd(1)); - } - - for (i=0 ; i < forks ; i++) - while ((wait_ret=wait(&status)) && wait_ret == -1); - return 0; -} - - -static void get_options(int argc, char **argv) -{ - char *pos,*progname; - DEBUGGER_OFF; - - progname= argv[0]; - - while (--argc >0 && *(pos = *(++argv)) == '-' ) { - switch(*++pos) { - case 'l': - use_log=1; - break; - case 'f': - forks=atoi(++pos); - break; - case 't': - tests=atoi(++pos); - break; - case 'K': /* Use key cacheing */ - key_cacheing=1; - break; - case 'A': /* All flags */ - use_log=key_cacheing=1; - break; - case '?': - case 'I': - case 'V': - printf("%s Ver 1.0 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE); - puts("By Monty, for your professional use\n"); - puts("Test av locking with threads\n"); - printf("Usage: %s [-?lKA] [-f#] [-t#]\n",progname); - exit(0); - case '#': - DEBUGGER_ON; - DBUG_PUSH (++pos); - break; - default: - printf("Illegal option: '%c'\n",*pos); - break; - } - } - return; -} - - -void start_test(int id) -{ - uint i; - int error,lock_type; - MI_ISAMINFO isam_info; - MI_INFO *file,*file1,*file2=0,*lock; - - if (use_log) - mi_log(1); - if (!(file1=mi_open(filename,O_RDWR,HA_OPEN_WAIT_IF_LOCKED)) || - !(file2=mi_open(filename,O_RDWR,HA_OPEN_WAIT_IF_LOCKED))) - { - fprintf(stderr,"Can't open isam-file: %s\n",filename); - exit(1); - } - if (key_cacheing && rnd(2) == 0) - init_key_cache(dflt_key_cache, KEY_CACHE_BLOCK_SIZE, 65536L, 0, 0); - printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout); - - for (error=i=0 ; i < tests && !error; i++) - { - file= (rnd(2) == 1) ? file1 : file2; - lock=0 ; lock_type=0; - if (rnd(10) == 0) - { - if (mi_lock_database(lock=(rnd(2) ? file1 : file2), - lock_type=(rnd(2) == 0 ? F_RDLCK : F_WRLCK))) - { - fprintf(stderr,"%2d: start: Can't lock table %d\n",id,my_errno); - error=1; - break; - } - } - switch (rnd(4)) { - case 0: error=test_read(file,id); break; - case 1: error=test_rrnd(file,id); break; - case 2: error=test_write(file,id,lock_type); break; - case 3: error=test_update(file,id,lock_type); break; - } - if (lock) - mi_lock_database(lock,F_UNLCK); - } - if (!error) - { - mi_status(file1,&isam_info,HA_STATUS_VARIABLE); - printf("%2d: End of test. Records: %ld Deleted: %ld\n", - id,(long) isam_info.records, (long) isam_info.deleted); - fflush(stdout); - } - - mi_close(file1); - mi_close(file2); - if (use_log) - mi_log(0); - if (error) - { - printf("%2d: Aborted\n",id); fflush(stdout); - exit(1); - } -} - - -int test_read(MI_INFO *file,int id) -{ - uint i,lock,found,next,prev; - ulong find; - - lock=0; - if (rnd(2) == 0) - { - lock=1; - if (mi_lock_database(file,F_RDLCK)) - { - fprintf(stderr,"%2d: Can't lock table %d\n",id,my_errno); - return 1; - } - } - - found=next=prev=0; - for (i=0 ; i < 100 ; i++) - { - find=rnd(100000); - if (!mi_rkey(file,record.id,1,(byte*) &find, - sizeof(find),HA_READ_KEY_EXACT)) - found++; - else - { - if (my_errno != HA_ERR_KEY_NOT_FOUND) - { - fprintf(stderr,"%2d: Got error %d from read in read\n",id,my_errno); - return 1; - } - else if (!mi_rnext(file,record.id,1)) - next++; - else - { - if (my_errno != HA_ERR_END_OF_FILE) - { - fprintf(stderr,"%2d: Got error %d from rnext in read\n",id,my_errno); - return 1; - } - else if (!mi_rprev(file,record.id,1)) - prev++; - else - { - if (my_errno != HA_ERR_END_OF_FILE) - { - fprintf(stderr,"%2d: Got error %d from rnext in read\n", - id,my_errno); - return 1; - } - } - } - } - } - if (lock) - { - if (mi_lock_database(file,F_UNLCK)) - { - fprintf(stderr,"%2d: Can't unlock table\n",id); - return 1; - } - } - printf("%2d: read: found: %5d next: %5d prev: %5d\n", - id,found,next,prev); - fflush(stdout); - return 0; -} - - -int test_rrnd(MI_INFO *file,int id) -{ - uint count,lock; - - lock=0; - if (rnd(2) == 0) - { - lock=1; - if (mi_lock_database(file,F_RDLCK)) - { - fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno); - mi_close(file); - return 1; - } - if (rnd(2) == 0) - mi_extra(file,HA_EXTRA_CACHE,0); - } - - count=0; - if (mi_rrnd(file,record.id,0L)) - { - if (my_errno == HA_ERR_END_OF_FILE) - goto end; - fprintf(stderr,"%2d: Can't read first record (%d)\n",id,my_errno); - return 1; - } - for (count=1 ; !mi_rrnd(file,record.id,HA_OFFSET_ERROR) ;count++) ; - if (my_errno != HA_ERR_END_OF_FILE) - { - fprintf(stderr,"%2d: Got error %d from rrnd\n",id,my_errno); - return 1; - } - -end: - if (lock) - { - mi_extra(file,HA_EXTRA_NO_CACHE,0); - if (mi_lock_database(file,F_UNLCK)) - { - fprintf(stderr,"%2d: Can't unlock table\n",id); - exit(0); - } - } - printf("%2d: rrnd: %5d\n",id,count); fflush(stdout); - return 0; -} - - -int test_write(MI_INFO *file,int id,int lock_type) -{ - uint i,tries,count,lock; - - lock=0; - if (rnd(2) == 0 || lock_type == F_RDLCK) - { - lock=1; - if (mi_lock_database(file,F_WRLCK)) - { - if (lock_type == F_RDLCK && my_errno == EDEADLK) - { - printf("%2d: write: deadlock\n",id); fflush(stdout); - return 0; - } - fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno); - mi_close(file); - return 1; - } - if (rnd(2) == 0) - mi_extra(file,HA_EXTRA_WRITE_CACHE,0); - } - - sprintf(record.id,"%7d",getpid()); - strnmov(record.text,"Testing...", sizeof(record.text)); - - tries=(uint) rnd(100)+10; - for (i=count=0 ; i < tries ; i++) - { - uint32 tmp=rnd(80000)+20000; - int4store(record.nr,tmp); - if (!mi_write(file,record.id)) - count++; - else - { - if (my_errno != HA_ERR_FOUND_DUPP_KEY) - { - fprintf(stderr,"%2d: Got error %d (errno %d) from write\n",id,my_errno, - errno); - return 1; - } - } - } - if (lock) - { - mi_extra(file,HA_EXTRA_NO_CACHE,0); - if (mi_lock_database(file,F_UNLCK)) - { - fprintf(stderr,"%2d: Can't unlock table\n",id); - exit(0); - } - } - printf("%2d: write: %5d\n",id,count); fflush(stdout); - return 0; -} - - -int test_update(MI_INFO *file,int id,int lock_type) -{ - uint i,lock,found,next,prev,update; - uint32 tmp; - char find[4]; - struct record new_record; - - lock=0; - if (rnd(2) == 0 || lock_type == F_RDLCK) - { - lock=1; - if (mi_lock_database(file,F_WRLCK)) - { - if (lock_type == F_RDLCK && my_errno == EDEADLK) - { - printf("%2d: write: deadlock\n",id); fflush(stdout); - return 0; - } - fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno); - return 1; - } - } - bzero((char*) &new_record,sizeof(new_record)); - strmov(new_record.text,"Updated"); - - found=next=prev=update=0; - for (i=0 ; i < 100 ; i++) - { - tmp=rnd(100000); - int4store(find,tmp); - if (!mi_rkey(file,record.id,1,(byte*) find, - sizeof(find),HA_READ_KEY_EXACT)) - found++; - else - { - if (my_errno != HA_ERR_KEY_NOT_FOUND) - { - fprintf(stderr,"%2d: Got error %d from read in update\n",id,my_errno); - return 1; - } - else if (!mi_rnext(file,record.id,1)) - next++; - else - { - if (my_errno != HA_ERR_END_OF_FILE) - { - fprintf(stderr,"%2d: Got error %d from rnext in update\n", - id,my_errno); - return 1; - } - else if (!mi_rprev(file,record.id,1)) - prev++; - else - { - if (my_errno != HA_ERR_END_OF_FILE) - { - fprintf(stderr,"%2d: Got error %d from rnext in update\n", - id,my_errno); - return 1; - } - continue; - } - } - } - memcpy_fixed(new_record.id,record.id,sizeof(record.id)); - tmp=rnd(20000)+40000; - int4store(new_record.nr,tmp); - if (!mi_update(file,record.id,new_record.id)) - update++; - else - { - if (my_errno != HA_ERR_RECORD_CHANGED && - my_errno != HA_ERR_RECORD_DELETED && - my_errno != HA_ERR_FOUND_DUPP_KEY) - { - fprintf(stderr,"%2d: Got error %d from update\n",id,my_errno); - return 1; - } - } - } - if (lock) - { - if (mi_lock_database(file,F_UNLCK)) - { - fprintf(stderr,"Can't unlock table,id, error%d\n",my_errno); - return 1; - } - } - printf("%2d: update: %5d\n",id,update); fflush(stdout); - return 0; -} - -#else /* __NETWARE__ */ - -#include <stdio.h> - -main() -{ - fprintf(stderr,"this test has not been ported to NetWare\n"); - return 0; -} - -#endif /* __NETWARE__ */ diff --git a/myisam/mi_test_all.res b/myisam/mi_test_all.res deleted file mode 100644 index 16b517d3f76..00000000000 --- a/myisam/mi_test_all.res +++ /dev/null @@ -1,53 +0,0 @@ -myisamchk: MyISAM file test1 -myisamchk: warning: Size of indexfile is: 1024 Should be: 2048 -MyISAM-table 'test1' is usable but should be fixed -mi_test2 -s -L -K -R1 -m2000 ; Should give error 135 -Error: 135 in write at record: 1105 -got error: 135 when using MyISAM-database -myisamchk: MyISAM file test2 -myisamchk: warning: Datafile is almost full, 65532 of 65534 used -MyISAM-table 'test2' is usable but should be fixed -Commands Used count Errors Recover errors -open 1 0 0 -write 50 0 0 -update 5 0 0 -delete 50 0 0 -close 1 0 0 -extra 6 0 0 -Total 113 0 0 -Commands Used count Errors Recover errors -open 2 0 0 -write 100 0 0 -update 10 0 0 -delete 100 0 0 -close 2 0 0 -extra 12 0 0 -Total 226 0 0 - -real 0m0.791s -user 0m0.137s -sys 0m0.117s - -real 0m0.659s -user 0m0.252s -sys 0m0.102s - -real 0m0.571s -user 0m0.188s -sys 0m0.098s - -real 0m1.111s -user 0m0.236s -sys 0m0.037s - -real 0m0.621s -user 0m0.242s -sys 0m0.022s - -real 0m0.698s -user 0m0.248s -sys 0m0.021s - -real 0m0.683s -user 0m0.265s -sys 0m0.079s diff --git a/myisam/mi_test_all.sh b/myisam/mi_test_all.sh deleted file mode 100755 index 07e71d65675..00000000000 --- a/myisam/mi_test_all.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/bin/sh -# -# Execute some simple basic test on MyISAM libary to check if things -# works at all. - -valgrind="valgrind --alignment=8 --leak-check=yes" -silent="-s" - -if test -f mi_test1$MACH ; then suffix=$MACH else suffix=""; fi -mi_test1$suffix $silent -myisamchk$suffix -se test1 -mi_test1$suffix $silent -N -S -myisamchk$suffix -se test1 -mi_test1$suffix $silent -P --checksum -myisamchk$suffix -se test1 -mi_test1$suffix $silent -P -N -S -myisamchk$suffix -se test1 -mi_test1$suffix $silent -B -N -R2 -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -k 480 --unique -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -N -S -R1 -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -p -S -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -p -S -N --unique -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -p -S -N --key_length=127 --checksum -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -p -S -N --key_length=128 -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -p -S --key_length=480 -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -B -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -B --key_length=64 --unique -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -B -k 480 --checksum -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -B -k 480 -N --unique --checksum -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -m -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -m -P --unique --checksum -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -m -P --key_length=480 --key_cache -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -m -p -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -w -S --unique -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -w --key_length=64 --checksum -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -w -N --key_length=480 -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -w -S --key_length=480 --checksum -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -b -N -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -a -b --key_length=480 -myisamchk$suffix -sm test1 -mi_test1$suffix $silent -p -B --key_length=480 -myisamchk$suffix -sm test1 - -mi_test1$suffix $silent --checksum -myisamchk$suffix -se test1 -myisamchk$suffix -rs test1 -myisamchk$suffix -se test1 -myisamchk$suffix -rqs test1 -myisamchk$suffix -se test1 -myisamchk$suffix -rs --correct-checksum test1 -myisamchk$suffix -se test1 -myisamchk$suffix -rqs --correct-checksum test1 -myisamchk$suffix -se test1 -myisamchk$suffix -ros --correct-checksum test1 -myisamchk$suffix -se test1 -myisamchk$suffix -rqos --correct-checksum test1 -myisamchk$suffix -se test1 - -# check of myisampack / myisamchk -myisampack$suffix --force -s test1 -myisamchk$suffix -es test1 -myisamchk$suffix -rqs test1 -myisamchk$suffix -es test1 -myisamchk$suffix -rs test1 -myisamchk$suffix -es test1 -myisamchk$suffix -rus test1 -myisamchk$suffix -es test1 - -mi_test1$suffix $silent --checksum -S -myisamchk$suffix -se test1 -myisamchk$suffix -ros test1 -myisamchk$suffix -rqs test1 -myisamchk$suffix -se test1 - -myisampack$suffix --force -s test1 -myisamchk$suffix -rqs test1 -myisamchk$suffix -es test1 -myisamchk$suffix -rus test1 -myisamchk$suffix -es test1 - -mi_test1$suffix $silent --checksum --unique -myisamchk$suffix -se test1 -mi_test1$suffix $silent --unique -S -myisamchk$suffix -se test1 - - -mi_test1$suffix $silent --key_multiple -N -S -myisamchk$suffix -sm test1 -mi_test1$suffix $silent --key_multiple -a -p --key_length=480 -myisamchk$suffix -sm test1 -mi_test1$suffix $silent --key_multiple -a -B --key_length=480 -myisamchk$suffix -sm test1 -mi_test1$suffix $silent --key_multiple -P -S -myisamchk$suffix -sm test1 - -mi_test2$suffix $silent -L -K -W -P -myisamchk$suffix -sm test2 -mi_test2$suffix $silent -L -K -W -P -A -myisamchk$suffix -sm test2 -mi_test2$suffix $silent -L -K -W -P -S -R1 -m500 -echo "mi_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135" -myisamchk$suffix -sm test2 -mi_test2$suffix $silent -L -K -R1 -m2000 -myisamchk$suffix -sm test2 -mi_test2$suffix $silent -L -K -P -S -R3 -m50 -b1000000 -myisamchk$suffix -sm test2 -mi_test2$suffix $silent -L -B -myisamchk$suffix -sm test2 -mi_test2$suffix $silent -D -B -c -myisamchk$suffix -sm test2 -mi_test2$suffix $silent -m10000 -e8192 -K -myisamchk$suffix -sm test2 -mi_test2$suffix $silent -m10000 -e16384 -E16384 -K -L -myisamchk$suffix -sm test2 - -mi_test2$suffix $silent -L -K -W -P -m50 -l -myisamlog$suffix -mi_test2$suffix $silent -L -K -W -P -m50 -l -b100 -myisamlog$suffix -time mi_test2$suffix $silent -time mi_test2$suffix $silent -K -B -time mi_test2$suffix $silent -L -B -time mi_test2$suffix $silent -L -K -B -time mi_test2$suffix $silent -L -K -W -B -time mi_test2$suffix $silent -L -K -W -S -B -time mi_test2$suffix $silent -D -K -W -S -B diff --git a/myisam/mi_unique.c b/myisam/mi_unique.c deleted file mode 100644 index f2d5f01be25..00000000000 --- a/myisam/mi_unique.c +++ /dev/null @@ -1,217 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Functions to check if a row is unique */ - -#include "myisamdef.h" -#include <m_ctype.h> - -my_bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, byte *record, - ha_checksum unique_hash, my_off_t disk_pos) -{ - my_off_t lastpos=info->lastpos; - MI_KEYDEF *key= &info->s->keyinfo[def->key]; - uchar *key_buff=info->lastkey2; - DBUG_ENTER("mi_check_unique"); - - mi_unique_store(record+key->seg->start, unique_hash); - _mi_make_key(info,def->key,key_buff,record,0); - - if (_mi_search(info,info->s->keyinfo+def->key,key_buff,MI_UNIQUE_HASH_LENGTH, - SEARCH_FIND,info->s->state.key_root[def->key])) - { - info->page_changed=1; /* Can't optimize read next */ - info->lastpos= lastpos; - DBUG_RETURN(0); /* No matching rows */ - } - - for (;;) - { - if (info->lastpos != disk_pos && - !(*info->s->compare_unique)(info,def,record,info->lastpos)) - { - my_errno=HA_ERR_FOUND_DUPP_UNIQUE; - info->errkey= (int) def->key; - info->dupp_key_pos= info->lastpos; - info->page_changed=1; /* Can't optimize read next */ - info->lastpos=lastpos; - DBUG_PRINT("info",("Found duplicate")); - DBUG_RETURN(1); /* Found identical */ - } - if (_mi_search_next(info,info->s->keyinfo+def->key, info->lastkey, - MI_UNIQUE_HASH_LENGTH, SEARCH_BIGGER, - info->s->state.key_root[def->key]) || - bcmp(info->lastkey, key_buff, MI_UNIQUE_HASH_LENGTH)) - { - info->page_changed=1; /* Can't optimize read next */ - info->lastpos=lastpos; - DBUG_RETURN(0); /* end of tree */ - } - } -} - - -/* Calculate a hash for a row */ - -ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record) -{ - const byte *pos, *end; - ha_checksum crc= 0; - ulong seed1=0, seed2= 4; - HA_KEYSEG *keyseg; - - for (keyseg=def->seg ; keyseg < def->end ; keyseg++) - { - enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type; - uint length=keyseg->length; - - if (keyseg->null_bit) - { - if (record[keyseg->null_pos] & keyseg->null_bit) - { - /* - Change crc in a way different from an empty string or 0. - (This is an optimisation; The code will work even if this isn't - done) - */ - crc=((crc << 8) + 511+ - (crc >> (8*sizeof(ha_checksum)-8))); - continue; - } - } - pos= record+keyseg->start; - if (keyseg->flag & HA_VAR_LENGTH_PART) - { - uint pack_length= keyseg->bit_start; - uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos : - uint2korr(pos)); - pos+= pack_length; /* Skip VARCHAR length */ - set_if_smaller(length,tmp_length); - } - else if (keyseg->flag & HA_BLOB_PART) - { - uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos); - memcpy_fixed((byte*) &pos,pos+keyseg->bit_start,sizeof(char*)); - if (!length || length > tmp_length) - length=tmp_length; /* The whole blob */ - } - end= pos+length; - if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT1 || - type == HA_KEYTYPE_VARTEXT2) - { - keyseg->charset->coll->hash_sort(keyseg->charset, - (const uchar*) pos, length, &seed1, - &seed2); - crc^= seed1; - } - else - while (pos != end) - crc=((crc << 8) + - (((uchar) *(uchar*) pos++))) + - (crc >> (8*sizeof(ha_checksum)-8)); - } - return crc; -} - - /* - Returns 0 if both rows have equal unique value - */ - -int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b, - my_bool null_are_equal) -{ - const byte *pos_a, *pos_b, *end; - HA_KEYSEG *keyseg; - - for (keyseg=def->seg ; keyseg < def->end ; keyseg++) - { - enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type; - uint a_length, b_length; - a_length= b_length= keyseg->length; - - /* If part is NULL it's regarded as different */ - if (keyseg->null_bit) - { - uint tmp; - if ((tmp=(a[keyseg->null_pos] & keyseg->null_bit)) != - (uint) (b[keyseg->null_pos] & keyseg->null_bit)) - return 1; - if (tmp) - { - if (!null_are_equal) - return 1; - continue; - } - } - pos_a= a+keyseg->start; - pos_b= b+keyseg->start; - if (keyseg->flag & HA_VAR_LENGTH_PART) - { - uint pack_length= keyseg->bit_start; - if (pack_length == 1) - { - a_length= (uint) *(uchar*) pos_a++; - b_length= (uint) *(uchar*) pos_b++; - } - else - { - a_length= uint2korr(pos_a); - b_length= uint2korr(pos_b); - pos_a+= 2; /* Skip VARCHAR length */ - pos_b+= 2; - } - set_if_smaller(a_length, keyseg->length); /* Safety */ - set_if_smaller(b_length, keyseg->length); /* safety */ - } - else if (keyseg->flag & HA_BLOB_PART) - { - /* Only compare 'length' characters if length != 0 */ - a_length= _mi_calc_blob_length(keyseg->bit_start,pos_a); - b_length= _mi_calc_blob_length(keyseg->bit_start,pos_b); - /* Check that a and b are of equal length */ - if (keyseg->length) - { - /* - This is used in some cases when we are not interested in comparing - the whole length of the blob. - */ - set_if_smaller(a_length, keyseg->length); - set_if_smaller(b_length, keyseg->length); - } - memcpy_fixed((byte*) &pos_a,pos_a+keyseg->bit_start,sizeof(char*)); - memcpy_fixed((byte*) &pos_b,pos_b+keyseg->bit_start,sizeof(char*)); - } - if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT1 || - type == HA_KEYTYPE_VARTEXT2) - { - if (mi_compare_text(keyseg->charset, (uchar *) pos_a, a_length, - (uchar *) pos_b, b_length, 0, 1)) - return 1; - } - else - { - if (a_length != b_length) - return 1; - end= pos_a+a_length; - while (pos_a != end) - { - if (*pos_a++ != *pos_b++) - return 1; - } - } - } - return 0; -} diff --git a/myisam/mi_update.c b/myisam/mi_update.c deleted file mode 100644 index cda60694008..00000000000 --- a/myisam/mi_update.c +++ /dev/null @@ -1,228 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Update an old row in a MyISAM table */ - -#include "fulltext.h" -#include "rt_index.h" - -int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) -{ - int flag,key_changed,save_errno; - reg3 my_off_t pos; - uint i; - uchar old_key[MI_MAX_KEY_BUFF],*new_key; - bool auto_key_changed=0; - ulonglong changed; - MYISAM_SHARE *share=info->s; - ha_checksum old_checksum; - DBUG_ENTER("mi_update"); - LINT_INIT(new_key); - LINT_INIT(changed); - LINT_INIT(old_checksum); - - DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_usage", - mi_print_error(info->s, HA_ERR_CRASHED); - DBUG_RETURN(my_errno= HA_ERR_CRASHED);); - if (!(info->update & HA_STATE_AKTIV)) - { - DBUG_RETURN(my_errno=HA_ERR_KEY_NOT_FOUND); - } - if (share->options & HA_OPTION_READ_ONLY_DATA) - { - DBUG_RETURN(my_errno=EACCES); - } - if (info->state->key_file_length >= share->base.margin_key_file_length) - { - DBUG_RETURN(my_errno=HA_ERR_INDEX_FILE_FULL); - } - pos=info->lastpos; - if (_mi_readinfo(info,F_WRLCK,1)) - DBUG_RETURN(my_errno); - - if (share->calc_checksum) - old_checksum=info->checksum=(*share->calc_checksum)(info,oldrec); - if ((*share->compare_record)(info,oldrec)) - { - save_errno=my_errno; - goto err_end; /* Record has changed */ - } - - - /* Calculate and check all unique constraints */ - key_changed=0; - for (i=0 ; i < share->state.header.uniques ; i++) - { - MI_UNIQUEDEF *def=share->uniqueinfo+i; - if (mi_unique_comp(def, newrec, oldrec,1) && - mi_check_unique(info, def, newrec, mi_unique_hash(def, newrec), - info->lastpos)) - { - save_errno=my_errno; - goto err_end; - } - } - if (_mi_mark_file_changed(info)) - { - save_errno=my_errno; - goto err_end; - } - - /* Check which keys changed from the original row */ - - new_key=info->lastkey2; - changed=0; - for (i=0 ; i < share->base.keys ; i++) - { - if (((ulonglong) 1 << i) & share->state.key_map) - { - if (share->keyinfo[i].flag & HA_FULLTEXT ) - { - if (_mi_ft_cmp(info,i,oldrec, newrec)) - { - if ((int) i == info->lastinx) - { - /* - We are changeing the index we are reading on. Mark that - the index data has changed and we need to do a full search - when doing read-next - */ - key_changed|=HA_STATE_WRITTEN; - } - changed|=((ulonglong) 1 << i); - if (_mi_ft_update(info,i,(char*) old_key,oldrec,newrec,pos)) - goto err; - } - } - else - { - uint new_length=_mi_make_key(info,i,new_key,newrec,pos); - uint old_length=_mi_make_key(info,i,old_key,oldrec,pos); - if (new_length != old_length || - memcmp((byte*) old_key,(byte*) new_key,new_length)) - { - if ((int) i == info->lastinx) - key_changed|=HA_STATE_WRITTEN; /* Mark that keyfile changed */ - changed|=((ulonglong) 1 << i); - share->keyinfo[i].version++; - if (share->keyinfo[i].ck_delete(info,i,old_key,old_length)) goto err; - if (share->keyinfo[i].ck_insert(info,i,new_key,new_length)) goto err; - if (share->base.auto_key == i+1) - auto_key_changed=1; - } - } - } - } - /* - If we are running with external locking, we must update the index file - that something has changed. - */ - if (changed || !my_disable_locking) - key_changed|= HA_STATE_CHANGED; - - if (share->calc_checksum) - { - info->checksum=(*share->calc_checksum)(info,newrec); - /* Store new checksum in index file header */ - key_changed|= HA_STATE_CHANGED; - } - { - /* - Don't update index file if data file is not extended and no status - information changed - */ - MI_STATUS_INFO state; - ha_rows org_split; - my_off_t org_delete_link; - - memcpy((char*) &state, (char*) info->state, sizeof(state)); - org_split= share->state.split; - org_delete_link= share->state.dellink; - if ((*share->update_record)(info,pos,newrec)) - goto err; - if (!key_changed && - (memcmp((char*) &state, (char*) info->state, sizeof(state)) || - org_split != share->state.split || - org_delete_link != share->state.dellink)) - key_changed|= HA_STATE_CHANGED; /* Must update index file */ - } - if (auto_key_changed) - update_auto_increment(info,newrec); - if (share->calc_checksum) - share->state.checksum+=(info->checksum - old_checksum); - - info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV | - key_changed); - myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,0); - VOID(_mi_writeinfo(info,key_changed ? WRITEINFO_UPDATE_KEYFILE : 0)); - allow_break(); /* Allow SIGHUP & SIGINT */ - if (info->invalidator != 0) - { - DBUG_PRINT("info", ("invalidator... '%s' (update)", info->filename)); - (*info->invalidator)(info->filename); - info->invalidator=0; - } - DBUG_RETURN(0); - -err: - DBUG_PRINT("error",("key: %d errno: %d",i,my_errno)); - save_errno=my_errno; - if (changed) - key_changed|= HA_STATE_CHANGED; - if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL) - { - info->errkey= (int) i; - flag=0; - do - { - if (((ulonglong) 1 << i) & changed) - { - if (share->keyinfo[i].flag & HA_FULLTEXT) - { - if ((flag++ && _mi_ft_del(info,i,(char*) new_key,newrec,pos)) || - _mi_ft_add(info,i,(char*) old_key,oldrec,pos)) - break; - } - else - { - uint new_length=_mi_make_key(info,i,new_key,newrec,pos); - uint old_length= _mi_make_key(info,i,old_key,oldrec,pos); - if ((flag++ && _mi_ck_delete(info,i,new_key,new_length)) || - _mi_ck_write(info,i,old_key,old_length)) - break; - } - } - } while (i-- != 0); - } - else - { - mi_print_error(info->s, HA_ERR_CRASHED); - mi_mark_crashed(info); - } - info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_ROW_CHANGED | - key_changed); - - err_end: - myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,my_errno); - VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); - allow_break(); /* Allow SIGHUP & SIGINT */ - if (save_errno == HA_ERR_KEY_NOT_FOUND) - { - mi_print_error(info->s, HA_ERR_CRASHED); - save_errno=HA_ERR_CRASHED; - } - DBUG_RETURN(my_errno=save_errno); -} /* mi_update */ diff --git a/myisam/mi_write.c b/myisam/mi_write.c deleted file mode 100644 index 768258a0c82..00000000000 --- a/myisam/mi_write.c +++ /dev/null @@ -1,1003 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Write a row to a MyISAM table */ - -#include "fulltext.h" -#include "rt_index.h" - -#define MAX_POINTER_LENGTH 8 - - /* Functions declared in this file */ - -static int w_search(MI_INFO *info,MI_KEYDEF *keyinfo, - uint comp_flag, uchar *key, - uint key_length, my_off_t pos, uchar *father_buff, - uchar *father_keypos, my_off_t father_page, - my_bool insert_last); -static int _mi_balance_page(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key, - uchar *curr_buff,uchar *father_buff, - uchar *father_keypos,my_off_t father_page); -static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page, - uchar *key, uint *return_key_length, - uchar **after_key); -int _mi_ck_write_tree(register MI_INFO *info, uint keynr,uchar *key, - uint key_length); -int _mi_ck_write_btree(register MI_INFO *info, uint keynr,uchar *key, - uint key_length); - - /* Write new record to database */ - -int mi_write(MI_INFO *info, byte *record) -{ - MYISAM_SHARE *share=info->s; - uint i; - int save_errno; - my_off_t filepos; - uchar *buff; - my_bool lock_tree= share->concurrent_insert; - DBUG_ENTER("mi_write"); - DBUG_PRINT("enter",("isam: %d data: %d",info->s->kfile,info->dfile)); - - DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_usage", - mi_print_error(info->s, HA_ERR_CRASHED); - DBUG_RETURN(my_errno= HA_ERR_CRASHED);); - if (share->options & HA_OPTION_READ_ONLY_DATA) - { - DBUG_RETURN(my_errno=EACCES); - } - if (_mi_readinfo(info,F_WRLCK,1)) - DBUG_RETURN(my_errno); - dont_break(); /* Dont allow SIGHUP or SIGINT */ -#if !defined(NO_LOCKING) && defined(USE_RECORD_LOCK) - if (!info->locked && my_lock(info->dfile,F_WRLCK,0L,F_TO_EOF, - MYF(MY_SEEK_NOT_DONE) | info->lock_wait)) - goto err; -#endif - filepos= ((share->state.dellink != HA_OFFSET_ERROR) ? - share->state.dellink : - info->state->data_file_length); - - if (share->base.reloc == (ha_rows) 1 && - share->base.records == (ha_rows) 1 && - info->state->records == (ha_rows) 1) - { /* System file */ - my_errno=HA_ERR_RECORD_FILE_FULL; - goto err2; - } - if (info->state->key_file_length >= share->base.margin_key_file_length) - { - my_errno=HA_ERR_INDEX_FILE_FULL; - goto err2; - } - if (_mi_mark_file_changed(info)) - goto err2; - - /* Calculate and check all unique constraints */ - for (i=0 ; i < share->state.header.uniques ; i++) - { - if (mi_check_unique(info,share->uniqueinfo+i,record, - mi_unique_hash(share->uniqueinfo+i,record), - HA_OFFSET_ERROR)) - goto err2; - } - - /* Write all keys to indextree */ - - buff=info->lastkey2; - for (i=0 ; i < share->base.keys ; i++) - { - if (((ulonglong) 1 << i) & share->state.key_map) - { - bool local_lock_tree= (lock_tree && - !(info->bulk_insert && - is_tree_inited(&info->bulk_insert[i]))); - if (local_lock_tree) - { - rw_wrlock(&share->key_root_lock[i]); - share->keyinfo[i].version++; - } - if (share->keyinfo[i].flag & HA_FULLTEXT ) - { - if (_mi_ft_add(info,i,(char*) buff,record,filepos)) - { - if (local_lock_tree) - rw_unlock(&share->key_root_lock[i]); - DBUG_PRINT("error",("Got error: %d on write",my_errno)); - goto err; - } - } - else - { - if (share->keyinfo[i].ck_insert(info,i,buff, - _mi_make_key(info,i,buff,record,filepos))) - { - if (local_lock_tree) - rw_unlock(&share->key_root_lock[i]); - DBUG_PRINT("error",("Got error: %d on write",my_errno)); - goto err; - } - } - if (local_lock_tree) - rw_unlock(&share->key_root_lock[i]); - } - } - if (share->calc_checksum) - info->checksum=(*share->calc_checksum)(info,record); - if (!(info->opt_flag & OPT_NO_ROWS)) - { - if ((*share->write_record)(info,record)) - goto err; - share->state.checksum+=info->checksum; - } - if (share->base.auto_key) - update_auto_increment(info,record); - info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN | - HA_STATE_ROW_CHANGED); - info->state->records++; - info->lastpos=filepos; - myisam_log_record(MI_LOG_WRITE,info,record,filepos,0); - VOID(_mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE)); - if (info->invalidator != 0) - { - DBUG_PRINT("info", ("invalidator... '%s' (update)", info->filename)); - (*info->invalidator)(info->filename); - info->invalidator=0; - } - allow_break(); /* Allow SIGHUP & SIGINT */ - DBUG_RETURN(0); - -err: - save_errno=my_errno; - if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL || - my_errno == HA_ERR_NULL_IN_SPATIAL) - { - if (info->bulk_insert) - { - uint j; - for (j=0 ; j < share->base.keys ; j++) - mi_flush_bulk_insert(info, j); - } - info->errkey= (int) i; - while ( i-- > 0) - { - if (((ulonglong) 1 << i) & share->state.key_map) - { - bool local_lock_tree= (lock_tree && - !(info->bulk_insert && - is_tree_inited(&info->bulk_insert[i]))); - if (local_lock_tree) - rw_wrlock(&share->key_root_lock[i]); - if (share->keyinfo[i].flag & HA_FULLTEXT) - { - if (_mi_ft_del(info,i,(char*) buff,record,filepos)) - { - if (local_lock_tree) - rw_unlock(&share->key_root_lock[i]); - break; - } - } - else - { - uint key_length=_mi_make_key(info,i,buff,record,filepos); - if (_mi_ck_delete(info,i,buff,key_length)) - { - if (local_lock_tree) - rw_unlock(&share->key_root_lock[i]); - break; - } - } - if (local_lock_tree) - rw_unlock(&share->key_root_lock[i]); - } - } - } - else - { - mi_print_error(info->s, HA_ERR_CRASHED); - mi_mark_crashed(info); - } - info->update= (HA_STATE_CHANGED | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED); - my_errno=save_errno; -err2: - save_errno=my_errno; - myisam_log_record(MI_LOG_WRITE,info,record,filepos,my_errno); - VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); - allow_break(); /* Allow SIGHUP & SIGINT */ - DBUG_RETURN(my_errno=save_errno); -} /* mi_write */ - - - /* Write one key to btree */ - -int _mi_ck_write(MI_INFO *info, uint keynr, uchar *key, uint key_length) -{ - DBUG_ENTER("_mi_ck_write"); - - if (info->bulk_insert && is_tree_inited(&info->bulk_insert[keynr])) - { - DBUG_RETURN(_mi_ck_write_tree(info, keynr, key, key_length)); - } - else - { - DBUG_RETURN(_mi_ck_write_btree(info, keynr, key, key_length)); - } -} /* _mi_ck_write */ - - -/********************************************************************** - * Normal insert code * - **********************************************************************/ - -int _mi_ck_write_btree(register MI_INFO *info, uint keynr, uchar *key, - uint key_length) -{ - int error; - uint comp_flag; - MI_KEYDEF *keyinfo=info->s->keyinfo+keynr; - my_off_t *root=&info->s->state.key_root[keynr]; - DBUG_ENTER("_mi_ck_write_btree"); - - if (keyinfo->flag & HA_SORT_ALLOWS_SAME) - comp_flag=SEARCH_BIGGER; /* Put after same key */ - else if (keyinfo->flag & (HA_NOSAME|HA_FULLTEXT)) - { - comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* No duplicates */ - if (keyinfo->flag & HA_NULL_ARE_EQUAL) - comp_flag|= SEARCH_NULL_ARE_EQUAL; - } - else - comp_flag=SEARCH_SAME; /* Keys in rec-pos order */ - - error=_mi_ck_real_write_btree(info, keyinfo, key, key_length, - root, comp_flag); - if (info->ft1_to_ft2) - { - if (!error) - error= _mi_ft_convert_to_ft2(info, keynr, key); - delete_dynamic(info->ft1_to_ft2); - my_free((gptr)info->ft1_to_ft2, MYF(0)); - info->ft1_to_ft2=0; - } - DBUG_RETURN(error); -} /* _mi_ck_write_btree */ - -int _mi_ck_real_write_btree(MI_INFO *info, MI_KEYDEF *keyinfo, - uchar *key, uint key_length, my_off_t *root, uint comp_flag) -{ - int error; - DBUG_ENTER("_mi_ck_real_write_btree"); - /* key_length parameter is used only if comp_flag is SEARCH_FIND */ - if (*root == HA_OFFSET_ERROR || - (error=w_search(info, keyinfo, comp_flag, key, key_length, - *root, (uchar *) 0, (uchar*) 0, - (my_off_t) 0, 1)) > 0) - error=_mi_enlarge_root(info,keyinfo,key,root); - DBUG_RETURN(error); -} /* _mi_ck_real_write_btree */ - - - /* Make a new root with key as only pointer */ - -int _mi_enlarge_root(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, - my_off_t *root) -{ - uint t_length,nod_flag; - MI_KEY_PARAM s_temp; - MYISAM_SHARE *share=info->s; - DBUG_ENTER("_mi_enlarge_root"); - - nod_flag= (*root != HA_OFFSET_ERROR) ? share->base.key_reflength : 0; - _mi_kpointer(info,info->buff+2,*root); /* if nod */ - t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(uchar*) 0, - (uchar*) 0, (uchar*) 0, key,&s_temp); - mi_putint(info->buff,t_length+2+nod_flag,nod_flag); - (*keyinfo->store_key)(keyinfo,info->buff+2+nod_flag,&s_temp); - info->buff_used=info->page_changed=1; /* info->buff is used */ - if ((*root= _mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR || - _mi_write_keypage(info,keyinfo,*root,DFLT_INIT_HITS,info->buff)) - DBUG_RETURN(-1); - DBUG_RETURN(0); -} /* _mi_enlarge_root */ - - - /* - Search after a position for a key and store it there - Returns -1 = error - 0 = ok - 1 = key should be stored in higher tree - */ - -static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, - uint comp_flag, uchar *key, uint key_length, my_off_t page, - uchar *father_buff, uchar *father_keypos, - my_off_t father_page, my_bool insert_last) -{ - int error,flag; - uint nod_flag, search_key_length; - uchar *temp_buff,*keypos; - uchar keybuff[MI_MAX_KEY_BUFF]; - my_bool was_last_key; - my_off_t next_page, dupp_key_pos; - DBUG_ENTER("w_search"); - DBUG_PRINT("enter",("page: %ld",page)); - - search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY; - if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+ - MI_MAX_KEY_BUFF*2))) - DBUG_RETURN(-1); - if (!_mi_fetch_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff,0)) - goto err; - - flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,search_key_length, - comp_flag, &keypos, keybuff, &was_last_key); - nod_flag=mi_test_if_nod(temp_buff); - if (flag == 0) - { - uint tmp_key_length; - /* get position to record with duplicated key */ - tmp_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,keybuff); - if (tmp_key_length) - dupp_key_pos=_mi_dpos(info,0,keybuff+tmp_key_length); - else - dupp_key_pos= HA_OFFSET_ERROR; - - if (keyinfo->flag & HA_FULLTEXT) - { - uint off; - int subkeys; - - get_key_full_length_rdonly(off, keybuff); - subkeys=ft_sintXkorr(keybuff+off); - comp_flag=SEARCH_SAME; - if (subkeys >= 0) - { - /* normal word, one-level tree structure */ - flag=(*keyinfo->bin_search)(info, keyinfo, temp_buff, key, - USE_WHOLE_KEY, comp_flag, - &keypos, keybuff, &was_last_key); - } - else - { - /* popular word. two-level tree. going down */ - my_off_t root=dupp_key_pos; - keyinfo=&info->s->ft2_keyinfo; - get_key_full_length_rdonly(off, key); - key+=off; - keypos-=keyinfo->keylength+nod_flag; /* we'll modify key entry 'in vivo' */ - error=_mi_ck_real_write_btree(info, keyinfo, key, 0, - &root, comp_flag); - _mi_dpointer(info, keypos+HA_FT_WLEN, root); - subkeys--; /* should there be underflow protection ? */ - DBUG_ASSERT(subkeys < 0); - ft_intXstore(keypos, subkeys); - if (!error) - error=_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff); - my_afree((byte*) temp_buff); - DBUG_RETURN(error); - } - } - else /* not HA_FULLTEXT, normal HA_NOSAME key */ - { - info->dupp_key_pos= dupp_key_pos; - my_afree((byte*) temp_buff); - my_errno=HA_ERR_FOUND_DUPP_KEY; - DBUG_RETURN(-1); - } - } - if (flag == MI_FOUND_WRONG_KEY) - DBUG_RETURN(-1); - if (!was_last_key) - insert_last=0; - next_page=_mi_kpos(nod_flag,keypos); - if (next_page == HA_OFFSET_ERROR || - (error=w_search(info, keyinfo, comp_flag, key, key_length, next_page, - temp_buff, keypos, page, insert_last)) >0) - { - error=_mi_insert(info,keyinfo,key,temp_buff,keypos,keybuff,father_buff, - father_keypos,father_page, insert_last); - if (_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff)) - goto err; - } - my_afree((byte*) temp_buff); - DBUG_RETURN(error); -err: - my_afree((byte*) temp_buff); - DBUG_PRINT("exit",("Error: %d",my_errno)); - DBUG_RETURN (-1); -} /* w_search */ - - - /* Insert new key at right of key_pos */ - /* Returns 2 if key contains key to upper level */ - -int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo, - uchar *key, uchar *anc_buff, uchar *key_pos, uchar *key_buff, - uchar *father_buff, uchar *father_key_pos, my_off_t father_page, - my_bool insert_last) -{ - uint a_length,nod_flag; - int t_length; - uchar *endpos, *prev_key; - MI_KEY_PARAM s_temp; - DBUG_ENTER("_mi_insert"); - DBUG_PRINT("enter",("key_pos: %lx",key_pos)); - DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,USE_WHOLE_KEY);); - - nod_flag=mi_test_if_nod(anc_buff); - a_length=mi_getint(anc_buff); - endpos= anc_buff+ a_length; - prev_key=(key_pos == anc_buff+2+nod_flag ? (uchar*) 0 : key_buff); - t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, - (key_pos == endpos ? (uchar*) 0 : key_pos), - prev_key, prev_key, - key,&s_temp); -#ifndef DBUG_OFF - if (key_pos != anc_buff+2+nod_flag && (keyinfo->flag & - (HA_BINARY_PACK_KEY | HA_PACK_KEY))) - { - DBUG_DUMP("prev_key",(byte*) key_buff,_mi_keylength(keyinfo,key_buff)); - } - if (keyinfo->flag & HA_PACK_KEY) - { - DBUG_PRINT("test",("t_length: %d ref_len: %d", - t_length,s_temp.ref_length)); - DBUG_PRINT("test",("n_ref_len: %d n_length: %d key_pos: %lx", - s_temp.n_ref_length,s_temp.n_length,s_temp.key)); - } -#endif - if (t_length > 0) - { - if (t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH) - { - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - DBUG_RETURN(-1); - } - bmove_upp((byte*) endpos+t_length,(byte*) endpos,(uint) (endpos-key_pos)); - } - else - { - if (-t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH) - { - mi_print_error(info->s, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - DBUG_RETURN(-1); - } - bmove(key_pos,key_pos-t_length,(uint) (endpos-key_pos)+t_length); - } - (*keyinfo->store_key)(keyinfo,key_pos,&s_temp); - a_length+=t_length; - mi_putint(anc_buff,a_length,nod_flag); - if (a_length <= keyinfo->block_length) - { - if (keyinfo->block_length - a_length < 32 && - keyinfo->flag & HA_FULLTEXT && key_pos == endpos && - info->s->base.key_reflength <= info->s->base.rec_reflength && - info->s->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) - { - /* - Normal word. One-level tree. Page is almost full. - Let's consider converting. - We'll compare 'key' and the first key at anc_buff - */ - uchar *a=key, *b=anc_buff+2+nod_flag; - uint alen, blen, ft2len=info->s->ft2_keyinfo.keylength; - /* the very first key on the page is always unpacked */ - DBUG_ASSERT((*b & 128) == 0); -#if HA_FT_MAXLEN >= 127 - blen= mi_uint2korr(b); b+=2; -#else - blen= *b++; -#endif - get_key_length(alen,a); - DBUG_ASSERT(info->ft1_to_ft2==0); - if (alen == blen && - mi_compare_text(keyinfo->seg->charset, a, alen, b, blen, 0, 0)==0) - { - /* yup. converting */ - info->ft1_to_ft2=(DYNAMIC_ARRAY *) - my_malloc(sizeof(DYNAMIC_ARRAY), MYF(MY_WME)); - my_init_dynamic_array(info->ft1_to_ft2, ft2len, 300, 50); - - /* - now, adding all keys from the page to dynarray - if the page is a leaf (if not keys will be deleted later) - */ - if (!nod_flag) - { - /* let's leave the first key on the page, though, because - we cannot easily dispatch an empty page here */ - b+=blen+ft2len+2; - for (a=anc_buff+a_length ; b < a ; b+=ft2len+2) - insert_dynamic(info->ft1_to_ft2, (char*) b); - - /* fixing the page's length - it contains only one key now */ - mi_putint(anc_buff,2+blen+ft2len+2,0); - } - /* the rest will be done when we're back from recursion */ - } - } - DBUG_RETURN(0); /* There is room on page */ - } - /* Page is full */ - if (nod_flag) - insert_last=0; - if (!(keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)) && - father_buff && !insert_last) - DBUG_RETURN(_mi_balance_page(info,keyinfo,key,anc_buff,father_buff, - father_key_pos,father_page)); - DBUG_RETURN(_mi_split_page(info,keyinfo,key,anc_buff,key_buff, insert_last)); -} /* _mi_insert */ - - - /* split a full page in two and assign emerging item to key */ - -int _mi_split_page(register MI_INFO *info, register MI_KEYDEF *keyinfo, - uchar *key, uchar *buff, uchar *key_buff, - my_bool insert_last_key) -{ - uint length,a_length,key_ref_length,t_length,nod_flag,key_length; - uchar *key_pos,*pos, *after_key; - my_off_t new_pos; - MI_KEY_PARAM s_temp; - DBUG_ENTER("mi_split_page"); - DBUG_DUMP("buff",(byte*) buff,mi_getint(buff)); - - if (info->s->keyinfo+info->lastinx == keyinfo) - info->page_changed=1; /* Info->buff is used */ - info->buff_used=1; - nod_flag=mi_test_if_nod(buff); - key_ref_length=2+nod_flag; - if (insert_last_key) - key_pos=_mi_find_last_pos(keyinfo,buff,key_buff, &key_length, &after_key); - else - key_pos=_mi_find_half_pos(nod_flag,keyinfo,buff,key_buff, &key_length, - &after_key); - if (!key_pos) - DBUG_RETURN(-1); - - length=(uint) (key_pos-buff); - a_length=mi_getint(buff); - mi_putint(buff,length,nod_flag); - - key_pos=after_key; - if (nod_flag) - { - DBUG_PRINT("test",("Splitting nod")); - pos=key_pos-nod_flag; - memcpy((byte*) info->buff+2,(byte*) pos,(size_t) nod_flag); - } - - /* Move middle item to key and pointer to new page */ - if ((new_pos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR) - DBUG_RETURN(-1); - _mi_kpointer(info,_mi_move_key(keyinfo,key,key_buff),new_pos); - - /* Store new page */ - if (!(*keyinfo->get_key)(keyinfo,nod_flag,&key_pos,key_buff)) - DBUG_RETURN(-1); - - t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(uchar *) 0, - (uchar*) 0, (uchar*) 0, - key_buff, &s_temp); - length=(uint) ((buff+a_length)-key_pos); - memcpy((byte*) info->buff+key_ref_length+t_length,(byte*) key_pos, - (size_t) length); - (*keyinfo->store_key)(keyinfo,info->buff+key_ref_length,&s_temp); - mi_putint(info->buff,length+t_length+key_ref_length,nod_flag); - - if (_mi_write_keypage(info,keyinfo,new_pos,DFLT_INIT_HITS,info->buff)) - DBUG_RETURN(-1); - DBUG_DUMP("key",(byte*) key,_mi_keylength(keyinfo,key)); - DBUG_RETURN(2); /* Middle key up */ -} /* _mi_split_page */ - - - /* - Calculate how to much to move to split a page in two - Returns pointer to start of key. - key will contain the key. - return_key_length will contain the length of key - after_key will contain the position to where the next key starts - */ - -uchar *_mi_find_half_pos(uint nod_flag, MI_KEYDEF *keyinfo, uchar *page, - uchar *key, uint *return_key_length, - uchar **after_key) -{ - uint keys,length,key_ref_length; - uchar *end,*lastpos; - DBUG_ENTER("_mi_find_half_pos"); - - key_ref_length=2+nod_flag; - length=mi_getint(page)-key_ref_length; - page+=key_ref_length; - if (!(keyinfo->flag & - (HA_PACK_KEY | HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY | - HA_BINARY_PACK_KEY))) - { - key_ref_length=keyinfo->keylength+nod_flag; - keys=length/(key_ref_length*2); - *return_key_length=keyinfo->keylength; - end=page+keys*key_ref_length; - *after_key=end+key_ref_length; - memcpy(key,end,key_ref_length); - DBUG_RETURN(end); - } - - end=page+length/2-key_ref_length; /* This is aprox. half */ - *key='\0'; - do - { - lastpos=page; - if (!(length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key))) - DBUG_RETURN(0); - } while (page < end); - *return_key_length=length; - *after_key=page; - DBUG_PRINT("exit",("returns: %lx page: %lx half: %lx",lastpos,page,end)); - DBUG_RETURN(lastpos); -} /* _mi_find_half_pos */ - - - /* - Split buffer at last key - Returns pointer to the start of the key before the last key - key will contain the last key - */ - -static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page, - uchar *key, uint *return_key_length, - uchar **after_key) -{ - uint keys,length,last_length,key_ref_length; - uchar *end,*lastpos,*prevpos; - uchar key_buff[MI_MAX_KEY_BUFF]; - DBUG_ENTER("_mi_find_last_pos"); - - key_ref_length=2; - length=mi_getint(page)-key_ref_length; - page+=key_ref_length; - if (!(keyinfo->flag & - (HA_PACK_KEY | HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY | - HA_BINARY_PACK_KEY))) - { - keys=length/keyinfo->keylength-2; - *return_key_length=length=keyinfo->keylength; - end=page+keys*length; - *after_key=end+length; - memcpy(key,end,length); - DBUG_RETURN(end); - } - - LINT_INIT(prevpos); - LINT_INIT(last_length); - end=page+length-key_ref_length; - *key='\0'; - length=0; - lastpos=page; - while (page < end) - { - prevpos=lastpos; lastpos=page; - last_length=length; - memcpy(key, key_buff, length); /* previous key */ - if (!(length=(*keyinfo->get_key)(keyinfo,0,&page,key_buff))) - { - mi_print_error(keyinfo->share, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - DBUG_RETURN(0); - } - } - *return_key_length=last_length; - *after_key=lastpos; - DBUG_PRINT("exit",("returns: %lx page: %lx end: %lx",prevpos,page,end)); - DBUG_RETURN(prevpos); -} /* _mi_find_last_pos */ - - - /* Balance page with not packed keys with page on right/left */ - /* returns 0 if balance was done */ - -static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo, - uchar *key, uchar *curr_buff, uchar *father_buff, - uchar *father_key_pos, my_off_t father_page) -{ - my_bool right; - uint k_length,father_length,father_keylength,nod_flag,curr_keylength, - right_length,left_length,new_right_length,new_left_length,extra_length, - length,keys; - uchar *pos,*buff,*extra_buff; - my_off_t next_page,new_pos; - byte tmp_part_key[MI_MAX_KEY_BUFF]; - DBUG_ENTER("_mi_balance_page"); - - k_length=keyinfo->keylength; - father_length=mi_getint(father_buff); - father_keylength=k_length+info->s->base.key_reflength; - nod_flag=mi_test_if_nod(curr_buff); - curr_keylength=k_length+nod_flag; - info->page_changed=1; - - if ((father_key_pos != father_buff+father_length && - (info->state->records & 1)) || - father_key_pos == father_buff+2+info->s->base.key_reflength) - { - right=1; - next_page= _mi_kpos(info->s->base.key_reflength, - father_key_pos+father_keylength); - buff=info->buff; - DBUG_PRINT("test",("use right page: %lu",next_page)); - } - else - { - right=0; - father_key_pos-=father_keylength; - next_page= _mi_kpos(info->s->base.key_reflength,father_key_pos); - /* Fix that curr_buff is to left */ - buff=curr_buff; curr_buff=info->buff; - DBUG_PRINT("test",("use left page: %lu",next_page)); - } /* father_key_pos ptr to parting key */ - - if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff,0)) - goto err; - DBUG_DUMP("next",(byte*) info->buff,mi_getint(info->buff)); - - /* Test if there is room to share keys */ - - left_length=mi_getint(curr_buff); - right_length=mi_getint(buff); - keys=(left_length+right_length-4-nod_flag*2)/curr_keylength; - - if ((right ? right_length : left_length) + curr_keylength <= - keyinfo->block_length) - { /* Merge buffs */ - new_left_length=2+nod_flag+(keys/2)*curr_keylength; - new_right_length=2+nod_flag+((keys+1)/2)*curr_keylength; - mi_putint(curr_buff,new_left_length,nod_flag); - mi_putint(buff,new_right_length,nod_flag); - - if (left_length < new_left_length) - { /* Move keys buff -> leaf */ - pos=curr_buff+left_length; - memcpy((byte*) pos,(byte*) father_key_pos, (size_t) k_length); - memcpy((byte*) pos+k_length, (byte*) buff+2, - (size_t) (length=new_left_length - left_length - k_length)); - pos=buff+2+length; - memcpy((byte*) father_key_pos,(byte*) pos,(size_t) k_length); - bmove((byte*) buff+2,(byte*) pos+k_length,new_right_length); - } - else - { /* Move keys -> buff */ - - bmove_upp((byte*) buff+new_right_length,(byte*) buff+right_length, - right_length-2); - length=new_right_length-right_length-k_length; - memcpy((byte*) buff+2+length,father_key_pos,(size_t) k_length); - pos=curr_buff+new_left_length; - memcpy((byte*) father_key_pos,(byte*) pos,(size_t) k_length); - memcpy((byte*) buff+2,(byte*) pos+k_length,(size_t) length); - } - - if (_mi_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff) || - _mi_write_keypage(info,keyinfo,father_page,DFLT_INIT_HITS,father_buff)) - goto err; - DBUG_RETURN(0); - } - - /* curr_buff[] and buff[] are full, lets split and make new nod */ - - extra_buff=info->buff+info->s->base.max_key_block_length; - new_left_length=new_right_length=2+nod_flag+(keys+1)/3*curr_keylength; - if (keys == 5) /* Too few keys to balance */ - new_left_length-=curr_keylength; - extra_length=nod_flag+left_length+right_length- - new_left_length-new_right_length-curr_keylength; - DBUG_PRINT("info",("left_length: %d right_length: %d new_left_length: %d new_right_length: %d extra_length: %d", - left_length, right_length, - new_left_length, new_right_length, - extra_length)); - mi_putint(curr_buff,new_left_length,nod_flag); - mi_putint(buff,new_right_length,nod_flag); - mi_putint(extra_buff,extra_length+2,nod_flag); - - /* move first largest keys to new page */ - pos=buff+right_length-extra_length; - memcpy((byte*) extra_buff+2,pos,(size_t) extra_length); - /* Save new parting key */ - memcpy(tmp_part_key, pos-k_length,k_length); - /* Make place for new keys */ - bmove_upp((byte*) buff+new_right_length,(byte*) pos-k_length, - right_length-extra_length-k_length-2); - /* Copy keys from left page */ - pos= curr_buff+new_left_length; - memcpy((byte*) buff+2,(byte*) pos+k_length, - (size_t) (length=left_length-new_left_length-k_length)); - /* Copy old parting key */ - memcpy((byte*) buff+2+length,father_key_pos,(size_t) k_length); - - /* Move new parting keys up to caller */ - memcpy((byte*) (right ? key : father_key_pos),pos,(size_t) k_length); - memcpy((byte*) (right ? father_key_pos : key),tmp_part_key, k_length); - - if ((new_pos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR) - goto err; - _mi_kpointer(info,key+k_length,new_pos); - if (_mi_write_keypage(info,keyinfo,(right ? new_pos : next_page), - DFLT_INIT_HITS,info->buff) || - _mi_write_keypage(info,keyinfo,(right ? next_page : new_pos), - DFLT_INIT_HITS,extra_buff)) - goto err; - - DBUG_RETURN(1); /* Middle key up */ - -err: - DBUG_RETURN(-1); -} /* _mi_balance_page */ - -/********************************************************************** - * Bulk insert code * - **********************************************************************/ - -typedef struct { - MI_INFO *info; - uint keynr; -} bulk_insert_param; - -int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key, - uint key_length) -{ - int error; - DBUG_ENTER("_mi_ck_write_tree"); - - error= tree_insert(&info->bulk_insert[keynr], key, - key_length + info->s->rec_reflength, - info->bulk_insert[keynr].custom_arg) ? 0 : HA_ERR_OUT_OF_MEM ; - - DBUG_RETURN(error); -} /* _mi_ck_write_tree */ - - -/* typeof(_mi_keys_compare)=qsort_cmp2 */ - -static int keys_compare(bulk_insert_param *param, uchar *key1, uchar *key2) -{ - uint not_used; - return ha_key_cmp(param->info->s->keyinfo[param->keynr].seg, - key1, key2, USE_WHOLE_KEY, SEARCH_SAME, - ¬_used); -} - - -static int keys_free(uchar *key, TREE_FREE mode, bulk_insert_param *param) -{ - /* - Probably I can use info->lastkey here, but I'm not sure, - and to be safe I'd better use local lastkey. - */ - uchar lastkey[MI_MAX_KEY_BUFF]; - uint keylen; - MI_KEYDEF *keyinfo; - - switch (mode) { - case free_init: - if (param->info->s->concurrent_insert) - { - rw_wrlock(¶m->info->s->key_root_lock[param->keynr]); - param->info->s->keyinfo[param->keynr].version++; - } - return 0; - case free_free: - keyinfo=param->info->s->keyinfo+param->keynr; - keylen=_mi_keylength(keyinfo, key); - memcpy(lastkey, key, keylen); - return _mi_ck_write_btree(param->info,param->keynr,lastkey, - keylen - param->info->s->rec_reflength); - case free_end: - if (param->info->s->concurrent_insert) - rw_unlock(¶m->info->s->key_root_lock[param->keynr]); - return 0; - } - return -1; -} - - -int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows) -{ - MYISAM_SHARE *share=info->s; - MI_KEYDEF *key=share->keyinfo; - bulk_insert_param *params; - uint i, num_keys, total_keylength; - ulonglong key_map=0; - DBUG_ENTER("_mi_init_bulk_insert"); - DBUG_PRINT("enter",("cache_size: %lu", cache_size)); - - DBUG_ASSERT(!info->bulk_insert && - (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT)); - - for (i=total_keylength=num_keys=0 ; i < share->base.keys ; i++) - { - if (!(key[i].flag & HA_NOSAME) && share->base.auto_key != i+1 - && test(share->state.key_map & ((ulonglong) 1 << i))) - { - num_keys++; - key_map |=((ulonglong) 1 << i); - total_keylength+=key[i].maxlength+TREE_ELEMENT_EXTRA_SIZE; - } - } - - if (num_keys==0 || - num_keys * MI_MIN_SIZE_BULK_INSERT_TREE > cache_size) - DBUG_RETURN(0); - - if (rows && rows*total_keylength < cache_size) - cache_size=rows; - else - cache_size/=total_keylength*16; - - info->bulk_insert=(TREE *) - my_malloc((sizeof(TREE)*share->base.keys+ - sizeof(bulk_insert_param)*num_keys),MYF(0)); - - if (!info->bulk_insert) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - - params=(bulk_insert_param *)(info->bulk_insert+share->base.keys); - for (i=0 ; i < share->base.keys ; i++) - { - if (test(key_map & ((ulonglong) 1 << i))) - { - params->info=info; - params->keynr=i; - /* Only allocate a 16'th of the buffer at a time */ - init_tree(&info->bulk_insert[i], - cache_size * key[i].maxlength, - cache_size * key[i].maxlength, 0, - (qsort_cmp2)keys_compare, 0, - (tree_element_free) keys_free, (void *)params++); - } - else - info->bulk_insert[i].root=0; - } - - DBUG_RETURN(0); -} - -void mi_flush_bulk_insert(MI_INFO *info, uint inx) -{ - if (info->bulk_insert) - { - if (is_tree_inited(&info->bulk_insert[inx])) - reset_tree(&info->bulk_insert[inx]); - } -} - -void mi_end_bulk_insert(MI_INFO *info) -{ - if (info->bulk_insert) - { - uint i; - for (i=0 ; i < info->s->base.keys ; i++) - { - if (is_tree_inited(& info->bulk_insert[i])) - { - delete_tree(& info->bulk_insert[i]); - } - } - my_free((void *)info->bulk_insert, MYF(0)); - info->bulk_insert=0; - } -} diff --git a/myisam/myisam_ftdump.c b/myisam/myisam_ftdump.c deleted file mode 100644 index 28aac0a8ecf..00000000000 --- a/myisam/myisam_ftdump.c +++ /dev/null @@ -1,277 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Sergei A. Golubchik, who has a shared copyright to this code - added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */ - -#include "ftdefs.h" -#include <my_getopt.h> - -static void usage(); -static void complain(int val); -static my_bool get_one_option(int, const struct my_option *, char *); - -static int count=0, stats=0, dump=0, lstats=0; -static my_bool verbose; -static char *query=NULL; -static uint lengths[256]; - -#define MAX_LEN (HA_FT_MAXBYTELEN+10) -#define HOW_OFTEN_TO_WRITE 10000 - -static struct my_option my_long_options[] = -{ - {"dump", 'd', "Dump index (incl. data offsets and word weights).", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"stats", 's', "Report global stats.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"verbose", 'v', "Be verbose.", - (gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"count", 'c', "Calculate per-word stats (counts and global weights).", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"length", 'l', "Report length distribution.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"help", 'h', "Display help and exit.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"help", '?', "Synonym for -h.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} -}; - - -int main(int argc,char *argv[]) -{ - int error=0, subkeys; - uint keylen, keylen2=0, inx, doc_cnt=0; - float weight= 1.0; - double gws, min_gws=0, avg_gws=0; - MI_INFO *info; - char buf[MAX_LEN], buf2[MAX_LEN], buf_maxlen[MAX_LEN], buf_min_gws[MAX_LEN]; - ulong total=0, maxlen=0, uniq=0, max_doc_cnt=0; - struct { MI_INFO *info; } aio0, *aio=&aio0; /* for GWS_IN_USE */ - - MY_INIT(argv[0]); - if ((error= handle_options(&argc, &argv, my_long_options, get_one_option))) - exit(error); - if (count || dump) - verbose=0; - if (!count && !dump && !lstats && !query) - stats=1; - - if (verbose) - setbuf(stdout,NULL); - - if (argc < 2) - usage(); - - { - char *end; - inx= (uint) strtoll(argv[1], &end, 10); - if (*end) - usage(); - } - - init_key_cache(dflt_key_cache,MI_KEY_BLOCK_LENGTH,USE_BUFFER_INIT, 0, 0); - - if (!(info=mi_open(argv[0],2,HA_OPEN_ABORT_IF_LOCKED))) - { - error=my_errno; - goto err; - } - - *buf2=0; - aio->info=info; - - if ((inx >= info->s->base.keys) || - !(info->s->keyinfo[inx].flag & HA_FULLTEXT)) - { - printf("Key %d in table %s is not a FULLTEXT key\n", inx, info->filename); - goto err; - } - - mi_lock_database(info, F_EXTRA_LCK); - - info->lastpos= HA_OFFSET_ERROR; - info->update|= HA_STATE_PREV_FOUND; - - while (!(error=mi_rnext(info,NULL,inx))) - { - keylen=*(info->lastkey); - - subkeys=ft_sintXkorr(info->lastkey+keylen+1); - if (subkeys >= 0) - weight=*(float*)&subkeys; - -#ifdef HAVE_SNPRINTF - snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey+1); -#else - sprintf(buf,"%.*s",(int) keylen,info->lastkey+1); -#endif - my_casedn_str(default_charset_info,buf); - total++; - lengths[keylen]++; - - if (count || stats) - { - doc_cnt++; - if (strcmp(buf, buf2)) - { - if (*buf2) - { - uniq++; - avg_gws+=gws=GWS_IN_USE; - if (count) - printf("%9u %20.7f %s\n",doc_cnt,gws,buf2); - if (maxlen<keylen2) - { - maxlen=keylen2; - strmov(buf_maxlen, buf2); - } - if (max_doc_cnt < doc_cnt) - { - max_doc_cnt=doc_cnt; - strmov(buf_min_gws, buf2); - min_gws=gws; - } - } - strmov(buf2, buf); - keylen2=keylen; - doc_cnt=0; - } - } - if (dump) - { - if (subkeys>=0) - printf("%9lx %20.7f %s\n", (long) info->lastpos,weight,buf); - else - printf("%9lx => %17d %s\n",(long) info->lastpos,-subkeys,buf); - } - if (verbose && (total%HOW_OFTEN_TO_WRITE)==0) - printf("%10ld\r",total); - } - mi_lock_database(info, F_UNLCK); - - if (count || stats) - { - doc_cnt++; - if (*buf2) - { - uniq++; - avg_gws+=gws=GWS_IN_USE; - if (count) - printf("%9u %20.7f %s\n",doc_cnt,gws,buf2); - if (maxlen<keylen2) - { - maxlen=keylen2; - strmov(buf_maxlen, buf2); - } - if (max_doc_cnt < doc_cnt) - { - max_doc_cnt=doc_cnt; - strmov(buf_min_gws, buf2); - min_gws=gws; - } - } - } - - if (stats) - { - count=0; - for (inx=0;inx<256;inx++) - { - count+=lengths[inx]; - if ((ulong) count >= total/2) - break; - } - printf("Total rows: %lu\nTotal words: %lu\n" - "Unique words: %lu\nLongest word: %lu chars (%s)\n" - "Median length: %u\n" - "Average global weight: %f\n" - "Most common word: %lu times, weight: %f (%s)\n", - (long) info->state->records, total, uniq, maxlen, buf_maxlen, - inx, avg_gws/uniq, max_doc_cnt, min_gws, buf_min_gws); - } - if (lstats) - { - count=0; - for (inx=0; inx<256; inx++) - { - count+=lengths[inx]; - if (count && lengths[inx]) - printf("%3u: %10lu %5.2f%% %20lu %4.1f%%\n", inx, - (ulong) lengths[inx],100.0*lengths[inx]/total,(ulong) count, - 100.0*count/total); - } - } - -err: - if (error && error != HA_ERR_END_OF_FILE) - printf("got error %d\n",my_errno); - if (info) - mi_close(info); - return 0; -} - - -static my_bool -get_one_option(int optid, const struct my_option *opt __attribute__((unused)), - char *argument __attribute__((unused))) -{ - switch(optid) { - case 'd': - dump=1; - complain(count || query); - break; - case 's': - stats=1; - complain(query!=0); - break; - case 'c': - count= 1; - complain(dump || query); - break; - case 'l': - lstats=1; - complain(query!=0); - break; - case '?': - case 'h': - usage(); - } - return 0; -} - -#include <help_start.h> - -static void usage() -{ - printf("Use: myisam_ftdump <table_name> <index_num>\n"); - my_print_help(my_long_options); - my_print_variables(my_long_options); - NETWARE_SET_SCREEN_MODE(1); - exit(1); -} - -#include <help_end.h> - -static void complain(int val) /* Kinda assert :-) */ -{ - if (val) - { - printf("You cannot use these options together!\n"); - exit(1); - } -} diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c deleted file mode 100644 index 519e123e9da..00000000000 --- a/myisam/myisamchk.c +++ /dev/null @@ -1,1771 +0,0 @@ -/* Copyright (C) 2000-2003 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Describe, check and repair of MyISAM tables */ - -#include "fulltext.h" - -#include <m_ctype.h> -#include <stdarg.h> -#include <my_getopt.h> -#ifdef HAVE_SYS_VADVICE_H -#include <sys/vadvise.h> -#endif -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif -SET_STACK_SIZE(9000) /* Minimum stack size for program */ - -#ifndef USE_RAID -#define my_raid_create(A,B,C,D,E,F,G) my_create(A,B,C,G) -#define my_raid_delete(A,B,C) my_delete(A,B) -#endif - -#ifdef OS2 -#define _sanity(a,b) -#endif - -static uint decode_bits; -static char **default_argv; -static const char *load_default_groups[]= { "myisamchk", 0 }; -static const char *set_collation_name, *opt_tmpdir; -static CHARSET_INFO *set_collation; -static long opt_myisam_block_size; -static long opt_key_cache_block_size; -static const char *my_progname_short; -static int stopwords_inited= 0; -static MY_TMPDIR myisamchk_tmpdir; - -static const char *type_names[]= -{ "impossible","char","binary", "short", "long", "float", - "double","number","unsigned short", - "unsigned long","longlong","ulonglong","int24", - "uint24","int8","varchar", "varbin","?", - "?"}; - -static const char *prefix_packed_txt="packed ", - *bin_packed_txt="prefix ", - *diff_txt="stripped ", - *null_txt="NULL", - *blob_txt="BLOB "; - -static const char *field_pack[]= -{"","no endspace", "no prespace", - "no zeros", "blob", "constant", "table-lockup", - "always zero","varchar","unique-hash","?","?"}; - - -static void get_options(int *argc,char * * *argv); -static void print_version(void); -static void usage(void); -static int myisamchk(MI_CHECK *param, char *filename); -static void descript(MI_CHECK *param, register MI_INFO *info, my_string name); -static int mi_sort_records(MI_CHECK *param, register MI_INFO *info, - my_string name, uint sort_key, - my_bool write_info, my_bool update_index); -static int sort_record_index(MI_SORT_PARAM *sort_param, MI_INFO *info, - MI_KEYDEF *keyinfo, - my_off_t page,uchar *buff,uint sortkey, - File new_file, my_bool update_index); - -MI_CHECK check_param; - - /* Main program */ - -int main(int argc, char **argv) -{ - int error; - MY_INIT(argv[0]); - my_progname_short= my_progname+dirname_length(my_progname); - -#ifdef __EMX__ - _wildcard (&argc, &argv); -#endif - - myisamchk_init(&check_param); - check_param.opt_lock_memory=1; /* Lock memory if possible */ - check_param.using_global_keycache = 0; - get_options(&argc,(char***) &argv); - myisam_quick_table_bits=decode_bits; - error=0; - while (--argc >= 0) - { - int new_error=myisamchk(&check_param, *(argv++)); - if ((check_param.testflag & T_REP_ANY) != T_REP) - check_param.testflag&= ~T_REP; - VOID(fflush(stdout)); - VOID(fflush(stderr)); - if ((check_param.error_printed | check_param.warning_printed) && - (check_param.testflag & T_FORCE_CREATE) && - (!(check_param.testflag & (T_REP | T_REP_BY_SORT | T_SORT_RECORDS | - T_SORT_INDEX)))) - { - uint old_testflag=check_param.testflag; - if (!(check_param.testflag & T_REP)) - check_param.testflag|= T_REP_BY_SORT; - check_param.testflag&= ~T_EXTEND; /* Don't needed */ - error|=myisamchk(&check_param, argv[-1]); - check_param.testflag= old_testflag; - VOID(fflush(stdout)); - VOID(fflush(stderr)); - } - else - error|=new_error; - if (argc && (!(check_param.testflag & T_SILENT) || check_param.testflag & T_INFO)) - { - puts("\n---------\n"); - VOID(fflush(stdout)); - } - } - if (check_param.total_files > 1) - { /* Only if descript */ - char buff[22],buff2[22]; - if (!(check_param.testflag & T_SILENT) || check_param.testflag & T_INFO) - puts("\n---------\n"); - printf("\nTotal of all %d MyISAM-files:\nData records: %9s Deleted blocks: %9s\n",check_param.total_files,llstr(check_param.total_records,buff), - llstr(check_param.total_deleted,buff2)); - } - free_defaults(default_argv); - free_tmpdir(&myisamchk_tmpdir); - ft_free_stopwords(); - my_end(check_param.testflag & T_INFO ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR); - exit(error); -#ifndef _lint - return 0; /* No compiler warning */ -#endif -} /* main */ - -enum options_mc { - OPT_CHARSETS_DIR=256, OPT_SET_COLLATION,OPT_START_CHECK_POS, - OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE, - OPT_KEY_CACHE_BLOCK_SIZE, OPT_MYISAM_BLOCK_SIZE, - OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE, - OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN, - OPT_FT_MAX_WORD_LEN, OPT_FT_STOPWORD_FILE, - OPT_MAX_RECORD_LENGTH -}; - -static struct my_option my_long_options[] = -{ - {"analyze", 'a', - "Analyze distribution of keys. Will make some joins in MySQL faster. You can check the calculated distribution.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"block-search", 'b', - "No help available.", - 0, 0, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"backup", 'B', - "Make a backup of the .MYD file as 'filename-time.BAK'.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory where character sets are.", - (gptr*) &charsets_dir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"check", 'c', - "Check table for errors.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"check-only-changed", 'C', - "Check only tables that have changed since last check. It also applies to other requested actions (e.g. --analyze will be ignored if the table is already analyzed).", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"correct-checksum", OPT_CORRECT_CHECKSUM, - "Correct checksum information for table.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifndef DBUG_OFF - {"debug", '#', - "Output debug log. Often this is 'd:t:o,filename'.", - 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, -#endif - {"description", 'd', - "Prints some information about table.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"data-file-length", 'D', - "Max length of data file (when recreating data-file when it's full).", - (gptr*) &check_param.max_data_file_length, - (gptr*) &check_param.max_data_file_length, - 0, GET_LL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"extend-check", 'e', - "If used when checking a table, ensure that the table is 100 percent consistent, which will take a long time. If used when repairing a table, try to recover every possible row from the data file. Normally this will also find a lot of garbage rows; Don't use this option with repair if you are not totally desperate.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"fast", 'F', - "Check only tables that haven't been closed properly. It also applies to other requested actions (e.g. --analyze will be ignored if the table is already analyzed).", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"force", 'f', - "Restart with -r if there are any errors in the table. States will be updated as with --update-state.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"HELP", 'H', - "Display this help and exit.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"help", '?', - "Display this help and exit.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"information", 'i', - "Print statistics information about table that is checked.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"keys-used", 'k', - "Tell MyISAM to update only some specific keys. # is a bit mask of which keys to use. This can be used to get faster inserts.", - (gptr*) &check_param.keys_in_use, - (gptr*) &check_param.keys_in_use, - 0, GET_ULL, REQUIRED_ARG, -1, 0, 0, 0, 0, 0}, - {"max-record-length", OPT_MAX_RECORD_LENGTH, - "Skip rows bigger than this if myisamchk can't allocate memory to hold it", - (gptr*) &check_param.max_record_length, - (gptr*) &check_param.max_record_length, - 0, GET_ULL, REQUIRED_ARG, LONGLONG_MAX, 0, LONGLONG_MAX, 0, 0, 0}, - {"medium-check", 'm', - "Faster than extend-check, but only finds 99.99% of all errors. Should be good enough for most cases.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"quick", 'q', "Faster repair by not modifying the data file.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"read-only", 'T', - "Don't mark table as checked.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"recover", 'r', - "Can fix almost anything except unique keys that aren't unique.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"parallel-recover", 'p', - "Same as '-r' but creates all the keys in parallel.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"safe-recover", 'o', - "Uses old recovery method; Slower than '-r' but can handle a couple of cases where '-r' reports that it can't fix the data file.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"sort-recover", 'n', - "Force recovering with sorting even if the temporary file was very big.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef DEBUG - {"start-check-pos", OPT_START_CHECK_POS, - "No help available.", - 0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, -#endif - {"set-auto-increment", 'A', - "Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.", - (gptr*) &check_param.auto_increment_value, - (gptr*) &check_param.auto_increment_value, - 0, GET_ULL, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"set-collation", OPT_SET_COLLATION, - "Change the collation used by the index", - (gptr*) &set_collation_name, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"set-variable", 'O', - "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.", - 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"silent", 's', - "Only print errors. One can use two -s to make myisamchk very silent.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"sort-index", 'S', - "Sort index blocks. This speeds up 'read-next' in applications.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"sort-records", 'R', - "Sort records according to an index. This makes your data much more localized and may speed up things. (It may be VERY slow to do a sort the first time!)", - (gptr*) &check_param.opt_sort_key, - (gptr*) &check_param.opt_sort_key, - 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"tmpdir", 't', - "Path for temporary files.", - (gptr*) &opt_tmpdir, - 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"update-state", 'U', - "Mark tables as crashed if any errors were found.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"unpack", 'u', - "Unpack file packed with myisampack.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"verbose", 'v', - "Print more information. This can be used with --description and --check. Use many -v for more verbosity!", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"version", 'V', - "Print version and exit.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"wait", 'w', - "Wait if table is locked.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - { "key_buffer_size", OPT_KEY_BUFFER_SIZE, "", - (gptr*) &check_param.use_buffers, (gptr*) &check_param.use_buffers, 0, - GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD, - (long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0}, - { "key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE, "", - (gptr*) &opt_key_cache_block_size, - (gptr*) &opt_key_cache_block_size, 0, - GET_LONG, REQUIRED_ARG, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, - MI_MAX_KEY_BLOCK_LENGTH, 0, MI_MIN_KEY_BLOCK_LENGTH, 0}, - { "myisam_block_size", OPT_MYISAM_BLOCK_SIZE, "", - (gptr*) &opt_myisam_block_size, (gptr*) &opt_myisam_block_size, 0, - GET_LONG, REQUIRED_ARG, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, - MI_MAX_KEY_BLOCK_LENGTH, 0, MI_MIN_KEY_BLOCK_LENGTH, 0}, - { "read_buffer_size", OPT_READ_BUFFER_SIZE, "", - (gptr*) &check_param.read_buffer_length, - (gptr*) &check_param.read_buffer_length, 0, GET_ULONG, REQUIRED_ARG, - (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, - (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, - { "write_buffer_size", OPT_WRITE_BUFFER_SIZE, "", - (gptr*) &check_param.write_buffer_length, - (gptr*) &check_param.write_buffer_length, 0, GET_ULONG, REQUIRED_ARG, - (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, - (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, - { "sort_buffer_size", OPT_SORT_BUFFER_SIZE, "", - (gptr*) &check_param.sort_buffer_length, - (gptr*) &check_param.sort_buffer_length, 0, GET_ULONG, REQUIRED_ARG, - (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), - (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, - { "sort_key_blocks", OPT_SORT_KEY_BLOCKS, "", - (gptr*) &check_param.sort_key_blocks, - (gptr*) &check_param.sort_key_blocks, 0, GET_ULONG, REQUIRED_ARG, - BUFFERS_WHEN_SORTING, 4L, 100L, 0L, 1L, 0}, - { "decode_bits", OPT_DECODE_BITS, "", (gptr*) &decode_bits, - (gptr*) &decode_bits, 0, GET_UINT, REQUIRED_ARG, 9L, 4L, 17L, 0L, 1L, 0}, - { "ft_min_word_len", OPT_FT_MIN_WORD_LEN, "", (gptr*) &ft_min_word_len, - (gptr*) &ft_min_word_len, 0, GET_ULONG, REQUIRED_ARG, 4, 1, HA_FT_MAXCHARLEN, - 0, 1, 0}, - { "ft_max_word_len", OPT_FT_MAX_WORD_LEN, "", (gptr*) &ft_max_word_len, - (gptr*) &ft_max_word_len, 0, GET_ULONG, REQUIRED_ARG, HA_FT_MAXCHARLEN, 10, - HA_FT_MAXCHARLEN, 0, 1, 0}, - { "ft_stopword_file", OPT_FT_STOPWORD_FILE, - "Use stopwords from this file instead of built-in list.", - (gptr*) &ft_stopword_file, (gptr*) &ft_stopword_file, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} -}; - - -#include <help_start.h> - -static void print_version(void) -{ - printf("%s Ver 2.7 for %s at %s\n", my_progname, SYSTEM_TYPE, - MACHINE_TYPE); - NETWARE_SET_SCREEN_MODE(1); -} - - -static void usage(void) -{ - print_version(); - puts("By Monty, for your professional use"); - puts("This software comes with NO WARRANTY: see the PUBLIC for details.\n"); - puts("Description, check and repair of MyISAM tables."); - puts("Used without options all tables on the command will be checked for errors"); - printf("Usage: %s [OPTIONS] tables[.MYI]\n", my_progname_short); - printf("\nGlobal options:\n"); -#ifndef DBUG_OFF - printf("\ - -#, --debug=... Output debug log. Often this is 'd:t:o,filename'.\n"); -#endif - printf("\ - -?, --help Display this help and exit.\n\ - -O, --set-variable var=option.\n\ - Change the value of a variable. Please note that\n\ - this option is deprecated; you can set variables\n\ - directly with '--variable-name=value'.\n\ - -t, --tmpdir=path Path for temporary files. Multiple paths can be\n\ - specified, separated by "); -#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__) - printf("semicolon (;)"); -#else - printf("colon (:)"); -#endif - printf(", they will be used\n\ - in a round-robin fashion.\n\ - -s, --silent Only print errors. One can use two -s to make\n\ - myisamchk very silent.\n\ - -v, --verbose Print more information. This can be used with\n\ - --description and --check. Use many -v for more verbosity.\n\ - -V, --version Print version and exit.\n\ - -w, --wait Wait if table is locked.\n\n"); -#ifdef DEBUG - puts(" --start-check-pos=# Start reading file at given offset.\n"); -#endif - - puts("Check options (check is the default action for myisamchk):\n\ - -c, --check Check table for errors.\n\ - -e, --extend-check Check the table VERY throughly. Only use this in\n\ - extreme cases as myisamchk should normally be able to\n\ - find out if the table is ok even without this switch.\n\ - -F, --fast Check only tables that haven't been closed properly.\n\ - -C, --check-only-changed\n\ - Check only tables that have changed since last check.\n\ - -f, --force Restart with '-r' if there are any errors in the table.\n\ - States will be updated as with '--update-state'.\n\ - -i, --information Print statistics information about table that is checked.\n\ - -m, --medium-check Faster than extend-check, but only finds 99.99% of\n\ - all errors. Should be good enough for most cases.\n\ - -U --update-state Mark tables as crashed if you find any errors.\n\ - -T, --read-only Don't mark table as checked.\n"); - - puts("Repair options (When using '-r' or '-o'):\n\ - -B, --backup Make a backup of the .MYD file as 'filename-time.BAK'.\n\ - --correct-checksum Correct checksum information for table.\n\ - -D, --data-file-length=# Max length of data file (when recreating data\n\ - file when it's full).\n\ - -e, --extend-check Try to recover every possible row from the data file\n\ - Normally this will also find a lot of garbage rows;\n\ - Don't use this option if you are not totally desperate.\n\ - -f, --force Overwrite old temporary files.\n\ - -k, --keys-used=# Tell MyISAM to update only some specific keys. # is a\n\ - bit mask of which keys to use. This can be used to\n\ - get faster inserts.\n\ - --max-record-length=#\n\ - Skip rows bigger than this if myisamchk can't allocate\n\ - memory to hold it.\n\ - -r, --recover Can fix almost anything except unique keys that aren't\n\ - unique.\n\ - -n, --sort-recover Forces recovering with sorting even if the temporary\n\ - file would be very big.\n\ - -p, --parallel-recover\n\ - Uses the same technique as '-r' and '-n', but creates\n\ - all the keys in parallel, in different threads.\n\ - -o, --safe-recover Uses old recovery method; Slower than '-r' but can\n\ - handle a couple of cases where '-r' reports that it\n\ - can't fix the data file.\n\ - --character-sets-dir=...\n\ - Directory where character sets are.\n\ - --set-collation=name\n\ - Change the collation used by the index.\n\ - -q, --quick Faster repair by not modifying the data file.\n\ - One can give a second '-q' to force myisamchk to\n\ - modify the original datafile in case of duplicate keys.\n\ - NOTE: Tables where the data file is currupted can't be\n\ - fixed with this option.\n\ - -u, --unpack Unpack file packed with myisampack.\n\ -"); - - puts("Other actions:\n\ - -a, --analyze Analyze distribution of keys. Will make some joins in\n\ - MySQL faster. You can check the calculated distribution\n\ - by using '--description --verbose table_name'.\n\ - -d, --description Prints some information about table.\n\ - -A, --set-auto-increment[=value]\n\ - Force auto_increment to start at this or higher value\n\ - If no value is given, then sets the next auto_increment\n\ - value to the highest used value for the auto key + 1.\n\ - -S, --sort-index Sort index blocks. This speeds up 'read-next' in\n\ - applications.\n\ - -R, --sort-records=#\n\ - Sort records according to an index. This makes your\n\ - data much more localized and may speed up things\n\ - (It may be VERY slow to do a sort the first time!).\n\ - -b, --block-search=#\n\ - Find a record, a block at given offset belongs to."); - - print_defaults("my", load_default_groups); - my_print_variables(my_long_options); -} - -#include <help_end.h> - - /* Read options */ - -static my_bool -get_one_option(int optid, - const struct my_option *opt __attribute__((unused)), - char *argument) -{ - switch (optid) { - case 'a': - if (argument == disabled_my_option) - check_param.testflag&= ~T_STATISTICS; - else - check_param.testflag|= T_STATISTICS; - break; - case 'A': - if (argument) - check_param.auto_increment_value= strtoull(argument, NULL, 0); - else - check_param.auto_increment_value= 0; /* Set to max used value */ - check_param.testflag|= T_AUTO_INC; - break; - case 'b': - check_param.search_after_block= strtoul(argument, NULL, 10); - break; - case 'B': - if (argument == disabled_my_option) - check_param.testflag&= ~T_BACKUP_DATA; - else - check_param.testflag|= T_BACKUP_DATA; - break; - case 'c': - if (argument == disabled_my_option) - check_param.testflag&= ~T_CHECK; - else - check_param.testflag|= T_CHECK; - break; - case 'C': - if (argument == disabled_my_option) - check_param.testflag&= ~(T_CHECK | T_CHECK_ONLY_CHANGED); - else - check_param.testflag|= T_CHECK | T_CHECK_ONLY_CHANGED; - break; - case 'D': - check_param.max_data_file_length=strtoll(argument, NULL, 10); - break; - case 's': /* silent */ - if (argument == disabled_my_option) - check_param.testflag&= ~(T_SILENT | T_VERY_SILENT); - else - { - if (check_param.testflag & T_SILENT) - check_param.testflag|= T_VERY_SILENT; - check_param.testflag|= T_SILENT; - check_param.testflag&= ~T_WRITE_LOOP; - } - break; - case 'w': - if (argument == disabled_my_option) - check_param.testflag&= ~T_WAIT_FOREVER; - else - check_param.testflag|= T_WAIT_FOREVER; - break; - case 'd': /* description if isam-file */ - if (argument == disabled_my_option) - check_param.testflag&= ~T_DESCRIPT; - else - check_param.testflag|= T_DESCRIPT; - break; - case 'e': /* extend check */ - if (argument == disabled_my_option) - check_param.testflag&= ~T_EXTEND; - else - check_param.testflag|= T_EXTEND; - break; - case 'i': - if (argument == disabled_my_option) - check_param.testflag&= ~T_INFO; - else - check_param.testflag|= T_INFO; - break; - case 'f': - if (argument == disabled_my_option) - { - check_param.tmpfile_createflag= O_RDWR | O_TRUNC | O_EXCL; - check_param.testflag&= ~(T_FORCE_CREATE | T_UPDATE_STATE); - } - else - { - check_param.tmpfile_createflag= O_RDWR | O_TRUNC; - check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE; - } - break; - case 'F': - if (argument == disabled_my_option) - check_param.testflag&= ~T_FAST; - else - check_param.testflag|= T_FAST; - break; - case 'k': - check_param.keys_in_use= (ulonglong) strtoll(argument, NULL, 10); - break; - case 'm': - if (argument == disabled_my_option) - check_param.testflag&= ~T_MEDIUM; - else - check_param.testflag|= T_MEDIUM; /* Medium check */ - break; - case 'r': /* Repair table */ - check_param.testflag&= ~T_REP_ANY; - if (argument != disabled_my_option) - check_param.testflag|= T_REP_BY_SORT; - break; - case 'p': - check_param.testflag&= ~T_REP_ANY; - if (argument != disabled_my_option) - check_param.testflag|= T_REP_PARALLEL; - break; - case 'o': - check_param.testflag&= ~T_REP_ANY; - check_param.force_sort= 0; - if (argument != disabled_my_option) - { - check_param.testflag|= T_REP; - my_disable_async_io= 1; /* More safety */ - } - break; - case 'n': - check_param.testflag&= ~T_REP_ANY; - if (argument == disabled_my_option) - check_param.force_sort= 0; - else - { - check_param.testflag|= T_REP_BY_SORT; - check_param.force_sort= 1; - } - break; - case 'q': - if (argument == disabled_my_option) - check_param.testflag&= ~(T_QUICK | T_FORCE_UNIQUENESS); - else - check_param.testflag|= - (check_param.testflag & T_QUICK) ? T_FORCE_UNIQUENESS : T_QUICK; - break; - case 'u': - if (argument == disabled_my_option) - check_param.testflag&= ~(T_UNPACK | T_REP_BY_SORT); - else - check_param.testflag|= T_UNPACK | T_REP_BY_SORT; - break; - case 'v': /* Verbose */ - if (argument == disabled_my_option) - { - check_param.testflag&= ~T_VERBOSE; - check_param.verbose=0; - } - else - { - check_param.testflag|= T_VERBOSE; - check_param.verbose++; - } - break; - case 'R': /* Sort records */ - if (argument == disabled_my_option) - check_param.testflag&= ~T_SORT_RECORDS; - else - { - check_param.testflag|= T_SORT_RECORDS; - check_param.opt_sort_key= (uint) atoi(argument) - 1; - if (check_param.opt_sort_key >= MI_MAX_KEY) - { - fprintf(stderr, - "The value of the sort key is bigger than max key: %d.\n", - MI_MAX_KEY); - exit(1); - } - } - break; - case 'S': /* Sort index */ - if (argument == disabled_my_option) - check_param.testflag&= ~T_SORT_INDEX; - else - check_param.testflag|= T_SORT_INDEX; - break; - case 'T': - if (argument == disabled_my_option) - check_param.testflag&= ~T_READONLY; - else - check_param.testflag|= T_READONLY; - break; - case 'U': - if (argument == disabled_my_option) - check_param.testflag&= ~T_UPDATE_STATE; - else - check_param.testflag|= T_UPDATE_STATE; - break; - case '#': - if (argument == disabled_my_option) - { - DBUG_POP(); - } - else - { - DBUG_PUSH(argument ? argument : "d:t:o,/tmp/myisamchk.trace"); - } - break; - case 'V': - print_version(); - exit(0); - case OPT_CORRECT_CHECKSUM: - if (argument == disabled_my_option) - check_param.testflag&= ~T_CALC_CHECKSUM; - else - check_param.testflag|= T_CALC_CHECKSUM; - break; -#ifdef DEBUG /* Only useful if debugging */ - case OPT_START_CHECK_POS: - check_param.start_check_pos= strtoull(argument, NULL, 0); - break; -#endif - case 'H': - my_print_help(my_long_options); - exit(0); - case '?': - usage(); - exit(0); - } - return 0; -} - - -static void get_options(register int *argc,register char ***argv) -{ - int ho_error; - - load_defaults("my", load_default_groups, argc, argv); - default_argv= *argv; - if (isatty(fileno(stdout))) - check_param.testflag|=T_WRITE_LOOP; - - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) - exit(ho_error); - - /* If using repair, then update checksum if one uses --update-state */ - if ((check_param.testflag & T_UPDATE_STATE) && - (check_param.testflag & T_REP_ANY)) - check_param.testflag|= T_CALC_CHECKSUM; - - if (*argc == 0) - { - usage(); - exit(-1); - } - - if ((check_param.testflag & T_UNPACK) && - (check_param.testflag & (T_QUICK | T_SORT_RECORDS))) - { - VOID(fprintf(stderr, - "%s: --unpack can't be used with --quick or --sort-records\n", - my_progname_short)); - exit(1); - } - if ((check_param.testflag & T_READONLY) && - (check_param.testflag & - (T_REP_ANY | T_STATISTICS | T_AUTO_INC | - T_SORT_RECORDS | T_SORT_INDEX | T_FORCE_CREATE))) - { - VOID(fprintf(stderr, - "%s: Can't use --readonly when repairing or sorting\n", - my_progname_short)); - exit(1); - } - - if (init_tmpdir(&myisamchk_tmpdir, opt_tmpdir)) - exit(1); - - check_param.tmpdir=&myisamchk_tmpdir; - check_param.key_cache_block_size= opt_key_cache_block_size; - - if (set_collation_name) - if (!(set_collation= get_charset_by_name(set_collation_name, - MYF(MY_WME)))) - exit(1); - - myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size); - return; -} /* get options */ - - - /* Check table */ - -static int myisamchk(MI_CHECK *param, my_string filename) -{ - int error,lock_type,recreate; - int rep_quick= param->testflag & (T_QUICK | T_FORCE_UNIQUENESS); - uint raid_chunks; - MI_INFO *info; - File datafile; - char llbuff[22],llbuff2[22]; - my_bool state_updated=0; - MYISAM_SHARE *share; - DBUG_ENTER("myisamchk"); - - param->out_flag=error=param->warning_printed=param->error_printed= - recreate=0; - datafile=0; - param->isam_file_name=filename; /* For error messages */ - if (!(info=mi_open(filename, - (param->testflag & (T_DESCRIPT | T_READONLY)) ? - O_RDONLY : O_RDWR, - HA_OPEN_FOR_REPAIR | - ((param->testflag & T_WAIT_FOREVER) ? - HA_OPEN_WAIT_IF_LOCKED : - (param->testflag & T_DESCRIPT) ? - HA_OPEN_IGNORE_IF_LOCKED : HA_OPEN_ABORT_IF_LOCKED)))) - { - /* Avoid twice printing of isam file name */ - param->error_printed=1; - switch (my_errno) { - case HA_ERR_CRASHED: - mi_check_print_error(param,"'%s' doesn't have a correct index definition. You need to recreate it before you can do a repair",filename); - break; - case HA_ERR_NOT_A_TABLE: - mi_check_print_error(param,"'%s' is not a MyISAM-table",filename); - break; - case HA_ERR_CRASHED_ON_USAGE: - mi_check_print_error(param,"'%s' is marked as crashed",filename); - break; - case HA_ERR_CRASHED_ON_REPAIR: - mi_check_print_error(param,"'%s' is marked as crashed after last repair",filename); - break; - case HA_ERR_OLD_FILE: - mi_check_print_error(param,"'%s' is a old type of MyISAM-table", filename); - break; - case HA_ERR_END_OF_FILE: - mi_check_print_error(param,"Couldn't read complete header from '%s'", filename); - break; - case EAGAIN: - mi_check_print_error(param,"'%s' is locked. Use -w to wait until unlocked",filename); - break; - case ENOENT: - mi_check_print_error(param,"File '%s' doesn't exist",filename); - break; - case EACCES: - mi_check_print_error(param,"You don't have permission to use '%s'",filename); - break; - default: - mi_check_print_error(param,"%d when opening MyISAM-table '%s'", - my_errno,filename); - break; - } - DBUG_RETURN(1); - } - share=info->s; - share->options&= ~HA_OPTION_READ_ONLY_DATA; /* We are modifing it */ - share->tot_locks-= share->r_locks; - share->r_locks=0; - raid_chunks=share->base.raid_chunks; - - /* - Skip the checking of the file if: - We are using --fast and the table is closed properly - We are using --check-only-changed-tables and the table hasn't changed - */ - if (param->testflag & (T_FAST | T_CHECK_ONLY_CHANGED)) - { - my_bool need_to_check= mi_is_crashed(info) || share->state.open_count != 0; - - if ((param->testflag & (T_REP_ANY | T_SORT_RECORDS)) && - ((share->state.changed & (STATE_CHANGED | STATE_CRASHED | - STATE_CRASHED_ON_REPAIR) || - !(param->testflag & T_CHECK_ONLY_CHANGED)))) - need_to_check=1; - - if (info->s->base.keys && info->state->records) - { - if ((param->testflag & T_STATISTICS) && - (share->state.changed & STATE_NOT_ANALYZED)) - need_to_check=1; - if ((param->testflag & T_SORT_INDEX) && - (share->state.changed & STATE_NOT_SORTED_PAGES)) - need_to_check=1; - if ((param->testflag & T_REP_BY_SORT) && - (share->state.changed & STATE_NOT_OPTIMIZED_KEYS)) - need_to_check=1; - } - if ((param->testflag & T_CHECK_ONLY_CHANGED) && - (share->state.changed & (STATE_CHANGED | STATE_CRASHED | - STATE_CRASHED_ON_REPAIR))) - need_to_check=1; - if (!need_to_check) - { - if (!(param->testflag & T_SILENT) || param->testflag & T_INFO) - printf("MyISAM file: %s is already checked\n",filename); - if (mi_close(info)) - { - mi_check_print_error(param,"%d when closing MyISAM-table '%s'", - my_errno,filename); - DBUG_RETURN(1); - } - DBUG_RETURN(0); - } - } - if ((param->testflag & (T_REP_ANY | T_STATISTICS | - T_SORT_RECORDS | T_SORT_INDEX)) && - (((param->testflag & T_UNPACK) && - share->data_file_type == COMPRESSED_RECORD) || - mi_uint2korr(share->state.header.state_info_length) != - MI_STATE_INFO_SIZE || - mi_uint2korr(share->state.header.base_info_length) != - MI_BASE_INFO_SIZE || - ((param->keys_in_use & ~share->state.key_map) & - (((ulonglong) 1L << share->base.keys)-1)) || - test_if_almost_full(info) || - info->s->state.header.file_version[3] != myisam_file_magic[3] || - (set_collation && - set_collation->number != share->state.header.language) || - myisam_block_size != MI_KEY_BLOCK_LENGTH)) - { - if (set_collation) - param->language= set_collation->number; - if (recreate_table(param, &info,filename)) - { - VOID(fprintf(stderr, - "MyISAM-table '%s' is not fixed because of errors\n", - filename)); - return(-1); - } - recreate=1; - if (!(param->testflag & T_REP_ANY)) - { - param->testflag|=T_REP_BY_SORT; /* if only STATISTICS */ - if (!(param->testflag & T_SILENT)) - printf("- '%s' has old table-format. Recreating index\n",filename); - rep_quick|=T_QUICK; - } - share=info->s; - share->tot_locks-= share->r_locks; - share->r_locks=0; - } - - if (param->testflag & T_DESCRIPT) - { - param->total_files++; - param->total_records+=info->state->records; - param->total_deleted+=info->state->del; - descript(param, info, filename); - } - else - { - if (!stopwords_inited++) - ft_init_stopwords(); - - if (!(param->testflag & T_READONLY)) - lock_type = F_WRLCK; /* table is changed */ - else - lock_type= F_RDLCK; - if (info->lock_type == F_RDLCK) - info->lock_type=F_UNLCK; /* Read only table */ - if (_mi_readinfo(info,lock_type,0)) - { - mi_check_print_error(param,"Can't lock indexfile of '%s', error: %d", - filename,my_errno); - param->error_printed=0; - goto end2; - } - /* - _mi_readinfo() has locked the table. - We mark the table as locked (without doing file locks) to be able to - use functions that only works on locked tables (like row caching). - */ - mi_lock_database(info, F_EXTRA_LCK); - datafile=info->dfile; - - if (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX)) - { - if (param->testflag & T_REP_ANY) - { - ulonglong tmp=share->state.key_map; - share->state.key_map= (((ulonglong) 1 << share->base.keys)-1) - & param->keys_in_use; - if (tmp != share->state.key_map) - info->update|=HA_STATE_CHANGED; - } - if (rep_quick && chk_del(param, info, param->testflag & ~T_VERBOSE)) - { - if (param->testflag & T_FORCE_CREATE) - { - rep_quick=0; - mi_check_print_info(param,"Creating new data file\n"); - } - else - { - error=1; - mi_check_print_error(param, - "Quick-recover aborted; Run recovery without switch 'q'"); - } - } - if (!error) - { - if ((param->testflag & (T_REP_BY_SORT | T_REP_PARALLEL)) && - (share->state.key_map || - (rep_quick && !param->keys_in_use && !recreate)) && - mi_test_if_sort_rep(info, info->state->records, - info->s->state.key_map, - param->force_sort)) - { - if (param->testflag & T_REP_BY_SORT) - error=mi_repair_by_sort(param,info,filename,rep_quick); - else - error=mi_repair_parallel(param,info,filename,rep_quick); - state_updated=1; - } - else if (param->testflag & T_REP_ANY) - error=mi_repair(param, info,filename,rep_quick); - } - if (!error && param->testflag & T_SORT_RECORDS) - { - /* - The data file is nowadays reopened in the repair code so we should - soon remove the following reopen-code - */ -#ifndef TO_BE_REMOVED - if (param->out_flag & O_NEW_DATA) - { /* Change temp file to org file */ - VOID(my_close(info->dfile,MYF(MY_WME))); /* Close new file */ - error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT, - raid_chunks, - MYF(0)); - if (mi_open_datafile(info,info->s, -1)) - error=1; - param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */ - param->read_cache.file=info->dfile; - } -#endif - if (! error) - { - uint key; - /* - We can't update the index in mi_sort_records if we have a - prefix compressed or fulltext index - */ - my_bool update_index=1; - for (key=0 ; key < share->base.keys; key++) - if (share->keyinfo[key].flag & (HA_BINARY_PACK_KEY|HA_FULLTEXT)) - update_index=0; - - error=mi_sort_records(param,info,filename,param->opt_sort_key, - /* what is the following parameter for ? */ - (my_bool) !(param->testflag & T_REP), - update_index); - datafile=info->dfile; /* This is now locked */ - if (!error && !update_index) - { - if (param->verbose) - puts("Table had a compressed index; We must now recreate the index"); - error=mi_repair_by_sort(param,info,filename,1); - } - } - } - if (!error && param->testflag & T_SORT_INDEX) - error=mi_sort_index(param,info,filename); - if (!error) - share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED | - STATE_CRASHED_ON_REPAIR); - else - mi_mark_crashed(info); - } - else if ((param->testflag & T_CHECK) || !(param->testflag & T_AUTO_INC)) - { - if (!(param->testflag & T_SILENT) || param->testflag & T_INFO) - printf("Checking MyISAM file: %s\n",filename); - if (!(param->testflag & T_SILENT)) - printf("Data records: %7s Deleted blocks: %7s\n", - llstr(info->state->records,llbuff), - llstr(info->state->del,llbuff2)); - error =chk_status(param,info); - share->state.key_map &=param->keys_in_use; - error =chk_size(param,info); - if (!error || !(param->testflag & (T_FAST | T_FORCE_CREATE))) - error|=chk_del(param, info,param->testflag); - if ((!error || (!(param->testflag & (T_FAST | T_FORCE_CREATE)) && - !param->start_check_pos))) - { - error|=chk_key(param, info); - if (!error && (param->testflag & (T_STATISTICS | T_AUTO_INC))) - error=update_state_info(param, info, - ((param->testflag & T_STATISTICS) ? - UPDATE_STAT : 0) | - ((param->testflag & T_AUTO_INC) ? - UPDATE_AUTO_INC : 0)); - } - if ((!rep_quick && !error) || - !(param->testflag & (T_FAST | T_FORCE_CREATE))) - { - if (param->testflag & (T_EXTEND | T_MEDIUM)) - VOID(init_key_cache(dflt_key_cache,opt_key_cache_block_size, - param->use_buffers, 0, 0)); - VOID(init_io_cache(¶m->read_cache,datafile, - (uint) param->read_buffer_length, - READ_CACHE, - (param->start_check_pos ? - param->start_check_pos : - share->pack.header_length), - 1, - MYF(MY_WME))); - lock_memory(param); - if ((info->s->options & (HA_OPTION_PACK_RECORD | - HA_OPTION_COMPRESS_RECORD)) || - (param->testflag & (T_EXTEND | T_MEDIUM))) - error|=chk_data_link(param, info, param->testflag & T_EXTEND); - error|=flush_blocks(param, share->key_cache, share->kfile); - VOID(end_io_cache(¶m->read_cache)); - } - if (!error) - { - if ((share->state.changed & STATE_CHANGED) && - (param->testflag & T_UPDATE_STATE)) - info->update|=HA_STATE_CHANGED | HA_STATE_ROW_CHANGED; - share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED | - STATE_CRASHED_ON_REPAIR); - } - else if (!mi_is_crashed(info) && - (param->testflag & T_UPDATE_STATE)) - { /* Mark crashed */ - mi_mark_crashed(info); - info->update|=HA_STATE_CHANGED | HA_STATE_ROW_CHANGED; - } - } - } - if ((param->testflag & T_AUTO_INC) || - ((param->testflag & T_REP_ANY) && info->s->base.auto_key)) - update_auto_increment_key(param, info, - (my_bool) !test(param->testflag & T_AUTO_INC)); - - if (!(param->testflag & T_DESCRIPT)) - { - if (info->update & HA_STATE_CHANGED && ! (param->testflag & T_READONLY)) - error|=update_state_info(param, info, - UPDATE_OPEN_COUNT | - (((param->testflag & T_REP_ANY) ? - UPDATE_TIME : 0) | - (state_updated ? UPDATE_STAT : 0) | - ((param->testflag & T_SORT_RECORDS) ? - UPDATE_SORT : 0))); - VOID(lock_file(param, share->kfile,0L,F_UNLCK,"indexfile",filename)); - info->update&= ~HA_STATE_CHANGED; - } - mi_lock_database(info, F_UNLCK); -end2: - if (mi_close(info)) - { - mi_check_print_error(param,"%d when closing MyISAM-table '%s'",my_errno,filename); - DBUG_RETURN(1); - } - if (error == 0) - { - if (param->out_flag & O_NEW_DATA) - error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT, - raid_chunks, - ((param->testflag & T_BACKUP_DATA) ? - MYF(MY_REDEL_MAKE_BACKUP) : MYF(0))); - if (param->out_flag & O_NEW_INDEX) - error|=change_to_newfile(filename,MI_NAME_IEXT,INDEX_TMP_EXT,0, - MYF(0)); - } - VOID(fflush(stdout)); VOID(fflush(stderr)); - if (param->error_printed) - { - if (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX)) - { - VOID(fprintf(stderr, - "MyISAM-table '%s' is not fixed because of errors\n", - filename)); - if (param->testflag & T_REP_ANY) - VOID(fprintf(stderr, - "Try fixing it by using the --safe-recover (-o), the --force (-f) option or by not using the --quick (-q) flag\n")); - } - else if (!(param->error_printed & 2) && - !(param->testflag & T_FORCE_CREATE)) - VOID(fprintf(stderr, - "MyISAM-table '%s' is corrupted\nFix it using switch \"-r\" or \"-o\"\n", - filename)); - } - else if (param->warning_printed && - ! (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX | - T_FORCE_CREATE))) - VOID(fprintf(stderr, "MyISAM-table '%s' is usable but should be fixed\n", - filename)); - VOID(fflush(stderr)); - DBUG_RETURN(error); -} /* myisamchk */ - - - /* Write info about table */ - -static void descript(MI_CHECK *param, register MI_INFO *info, my_string name) -{ - uint key,keyseg_nr,field,start; - reg3 MI_KEYDEF *keyinfo; - reg2 HA_KEYSEG *keyseg; - reg4 const char *text; - char buff[160],length[10],*pos,*end; - enum en_fieldtype type; - MYISAM_SHARE *share=info->s; - char llbuff[22],llbuff2[22]; - DBUG_ENTER("describe"); - - printf("\nMyISAM file: %s\n",name); - fputs("Record format: ",stdout); - if (share->options & HA_OPTION_COMPRESS_RECORD) - puts("Compressed"); - else if (share->options & HA_OPTION_PACK_RECORD) - puts("Packed"); - else - puts("Fixed length"); - printf("Character set: %s (%d)\n", - get_charset_name(share->state.header.language), - share->state.header.language); - - if (param->testflag & T_VERBOSE) - { - printf("File-version: %d\n", - (int) share->state.header.file_version[3]); - if (share->state.create_time) - { - get_date(buff,1,share->state.create_time); - printf("Creation time: %s\n",buff); - } - if (share->state.check_time) - { - get_date(buff,1,share->state.check_time); - printf("Recover time: %s\n",buff); - } - pos=buff; - if (share->state.changed & STATE_CRASHED) - strmov(buff,"crashed"); - else - { - if (share->state.open_count) - pos=strmov(pos,"open,"); - if (share->state.changed & STATE_CHANGED) - pos=strmov(pos,"changed,"); - else - pos=strmov(pos,"checked,"); - if (!(share->state.changed & STATE_NOT_ANALYZED)) - pos=strmov(pos,"analyzed,"); - if (!(share->state.changed & STATE_NOT_OPTIMIZED_KEYS)) - pos=strmov(pos,"optimized keys,"); - if (!(share->state.changed & STATE_NOT_SORTED_PAGES)) - pos=strmov(pos,"sorted index pages,"); - pos[-1]=0; /* Remove extra ',' */ - } - printf("Status: %s\n",buff); - if (share->base.auto_key) - { - printf("Auto increment key: %13d Last value: %13s\n", - share->base.auto_key, - llstr(share->state.auto_increment,llbuff)); - } - if (share->base.raid_type) - { - printf("RAID: Type: %u Chunks: %u Chunksize: %lu\n", - share->base.raid_type, - share->base.raid_chunks, - share->base.raid_chunksize); - } - if (share->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) - printf("Checksum: %23s\n",llstr(info->s->state.checksum,llbuff)); -; - if (share->options & HA_OPTION_DELAY_KEY_WRITE) - printf("Keys are only flushed at close\n"); - - } - printf("Data records: %13s Deleted blocks: %13s\n", - llstr(info->state->records,llbuff),llstr(info->state->del,llbuff2)); - if (param->testflag & T_SILENT) - DBUG_VOID_RETURN; /* This is enough */ - - if (param->testflag & T_VERBOSE) - { -#ifdef USE_RELOC - printf("Init-relocation: %13s\n",llstr(share->base.reloc,llbuff)); -#endif - printf("Datafile parts: %13s Deleted data: %13s\n", - llstr(share->state.split,llbuff), - llstr(info->state->empty,llbuff2)); - printf("Datafile pointer (bytes):%9d Keyfile pointer (bytes):%9d\n", - share->rec_reflength,share->base.key_reflength); - printf("Datafile length: %13s Keyfile length: %13s\n", - llstr(info->state->data_file_length,llbuff), - llstr(info->state->key_file_length,llbuff2)); - - if (info->s->base.reloc == 1L && info->s->base.records == 1L) - puts("This is a one-record table"); - else - { - if (share->base.max_data_file_length != HA_OFFSET_ERROR || - share->base.max_key_file_length != HA_OFFSET_ERROR) - printf("Max datafile length: %13s Max keyfile length: %13s\n", - llstr(share->base.max_data_file_length-1,llbuff), - llstr(share->base.max_key_file_length-1,llbuff2)); - } - } - - printf("Recordlength: %13d\n",(int) share->base.pack_reclength); - if (share->state.key_map != (((ulonglong) 1 << share->base.keys) -1)) - { - longlong2str(share->state.key_map,buff,2); - printf("Using only keys '%s' of %d possibly keys\n", - buff, share->base.keys); - } - puts("\ntable description:"); - printf("Key Start Len Index Type"); - if (param->testflag & T_VERBOSE) - printf(" Rec/key Root Blocksize"); - VOID(putchar('\n')); - - for (key=keyseg_nr=0, keyinfo= &share->keyinfo[0] ; - key < share->base.keys; - key++,keyinfo++) - { - keyseg=keyinfo->seg; - if (keyinfo->flag & HA_NOSAME) text="unique "; - else if (keyinfo->flag & HA_FULLTEXT) text="fulltext "; - else text="multip."; - - pos=buff; - if (keyseg->flag & HA_REVERSE_SORT) - *pos++ = '-'; - pos=strmov(pos,type_names[keyseg->type]); - *pos++ = ' '; - *pos=0; - if (keyinfo->flag & HA_PACK_KEY) - pos=strmov(pos,prefix_packed_txt); - if (keyinfo->flag & HA_BINARY_PACK_KEY) - pos=strmov(pos,bin_packed_txt); - if (keyseg->flag & HA_SPACE_PACK) - pos=strmov(pos,diff_txt); - if (keyseg->flag & HA_BLOB_PART) - pos=strmov(pos,blob_txt); - if (keyseg->flag & HA_NULL_PART) - pos=strmov(pos,null_txt); - *pos=0; - - printf("%-4d%-6ld%-3d %-8s%-21s", - key+1,(long) keyseg->start+1,keyseg->length,text,buff); - if (share->state.key_root[key] != HA_OFFSET_ERROR) - llstr(share->state.key_root[key],buff); - else - buff[0]=0; - if (param->testflag & T_VERBOSE) - printf("%11lu %12s %10d", - share->state.rec_per_key_part[keyseg_nr++], - buff,keyinfo->block_length); - VOID(putchar('\n')); - while ((++keyseg)->type != HA_KEYTYPE_END) - { - pos=buff; - if (keyseg->flag & HA_REVERSE_SORT) - *pos++ = '-'; - pos=strmov(pos,type_names[keyseg->type]); - *pos++= ' '; - if (keyseg->flag & HA_SPACE_PACK) - pos=strmov(pos,diff_txt); - if (keyseg->flag & HA_BLOB_PART) - pos=strmov(pos,blob_txt); - if (keyseg->flag & HA_NULL_PART) - pos=strmov(pos,null_txt); - *pos=0; - printf(" %-6ld%-3d %-21s", - (long) keyseg->start+1,keyseg->length,buff); - if (param->testflag & T_VERBOSE) - printf("%11lu", share->state.rec_per_key_part[keyseg_nr++]); - VOID(putchar('\n')); - } - keyseg++; - } - if (share->state.header.uniques) - { - MI_UNIQUEDEF *uniqueinfo; - puts("\nUnique Key Start Len Nullpos Nullbit Type"); - for (key=0,uniqueinfo= &share->uniqueinfo[0] ; - key < share->state.header.uniques; key++, uniqueinfo++) - { - my_bool new_row=0; - char null_bit[8],null_pos[8]; - printf("%-8d%-5d",key+1,uniqueinfo->key+1); - for (keyseg=uniqueinfo->seg ; keyseg->type != HA_KEYTYPE_END ; keyseg++) - { - if (new_row) - fputs(" ",stdout); - null_bit[0]=null_pos[0]=0; - if (keyseg->null_bit) - { - sprintf(null_bit,"%d",keyseg->null_bit); - sprintf(null_pos,"%ld",(long) keyseg->null_pos+1); - } - printf("%-7ld%-5d%-9s%-10s%-30s\n", - (long) keyseg->start+1,keyseg->length, - null_pos,null_bit, - type_names[keyseg->type]); - new_row=1; - } - } - } - if (param->verbose > 1) - { - char null_bit[8],null_pos[8]; - printf("\nField Start Length Nullpos Nullbit Type"); - if (share->options & HA_OPTION_COMPRESS_RECORD) - printf(" Huff tree Bits"); - VOID(putchar('\n')); - start=1; - for (field=0 ; field < share->base.fields ; field++) - { - if (share->options & HA_OPTION_COMPRESS_RECORD) - type=share->rec[field].base_type; - else - type=(enum en_fieldtype) share->rec[field].type; - end=strmov(buff,field_pack[type]); - if (share->options & HA_OPTION_COMPRESS_RECORD) - { - if (share->rec[field].pack_type & PACK_TYPE_SELECTED) - end=strmov(end,", not_always"); - if (share->rec[field].pack_type & PACK_TYPE_SPACE_FIELDS) - end=strmov(end,", no empty"); - if (share->rec[field].pack_type & PACK_TYPE_ZERO_FILL) - { - sprintf(end,", zerofill(%d)",share->rec[field].space_length_bits); - end=strend(end); - } - } - if (buff[0] == ',') - strmov(buff,buff+2); - int10_to_str((long) share->rec[field].length,length,10); - null_bit[0]=null_pos[0]=0; - if (share->rec[field].null_bit) - { - sprintf(null_bit,"%d",share->rec[field].null_bit); - sprintf(null_pos,"%d",share->rec[field].null_pos+1); - } - printf("%-6d%-6d%-7s%-8s%-8s%-35s",field+1,start,length, - null_pos, null_bit, buff); - if (share->options & HA_OPTION_COMPRESS_RECORD) - { - if (share->rec[field].huff_tree) - printf("%3d %2d", - (uint) (share->rec[field].huff_tree-share->decode_trees)+1, - share->rec[field].huff_tree->quick_table_bits); - } - VOID(putchar('\n')); - start+=share->rec[field].length; - } - } - DBUG_VOID_RETURN; -} /* describe */ - - - /* Sort records according to one key */ - -static int mi_sort_records(MI_CHECK *param, - register MI_INFO *info, my_string name, - uint sort_key, - my_bool write_info, - my_bool update_index) -{ - int got_error; - uint key; - MI_KEYDEF *keyinfo; - File new_file; - uchar *temp_buff; - ha_rows old_record_count; - MYISAM_SHARE *share=info->s; - char llbuff[22],llbuff2[22]; - SORT_INFO sort_info; - MI_SORT_PARAM sort_param; - DBUG_ENTER("sort_records"); - - bzero((char*)&sort_info,sizeof(sort_info)); - bzero((char*)&sort_param,sizeof(sort_param)); - sort_param.sort_info=&sort_info; - sort_info.param=param; - keyinfo= &share->keyinfo[sort_key]; - got_error=1; - temp_buff=0; - new_file= -1; - - if (!(((ulonglong) 1 << sort_key) & share->state.key_map)) - { - mi_check_print_warning(param, - "Can't sort table '%s' on key %d; No such key", - name,sort_key+1); - param->error_printed=0; - DBUG_RETURN(0); /* Nothing to do */ - } - if (keyinfo->flag & HA_FULLTEXT) - { - mi_check_print_warning(param,"Can't sort table '%s' on FULLTEXT key %d", - name,sort_key+1); - param->error_printed=0; - DBUG_RETURN(0); /* Nothing to do */ - } - if (share->data_file_type == COMPRESSED_RECORD) - { - mi_check_print_warning(param,"Can't sort read-only table '%s'", name); - param->error_printed=0; - DBUG_RETURN(0); /* Nothing to do */ - } - if (!(param->testflag & T_SILENT)) - { - printf("- Sorting records for MyISAM-table '%s'\n",name); - if (write_info) - printf("Data records: %9s Deleted: %9s\n", - llstr(info->state->records,llbuff), - llstr(info->state->del,llbuff2)); - } - if (share->state.key_root[sort_key] == HA_OFFSET_ERROR) - DBUG_RETURN(0); /* Nothing to do */ - - init_key_cache(dflt_key_cache, opt_key_cache_block_size, param->use_buffers, - 0, 0); - if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length, - WRITE_CACHE,share->pack.header_length,1, - MYF(MY_WME | MY_WAIT_IF_FULL))) - goto err; - info->opt_flag|=WRITE_CACHE_USED; - - if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length))) - { - mi_check_print_error(param,"Not enough memory for key block"); - goto err; - } - if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength, - MYF(0)))) - { - mi_check_print_error(param,"Not enough memory for record"); - goto err; - } - fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32); - new_file=my_raid_create(fn_format(param->temp_filename, - param->temp_filename,"", - DATA_TMP_EXT,2+4), - 0,param->tmpfile_createflag, - share->base.raid_type, - share->base.raid_chunks, - share->base.raid_chunksize, - MYF(0)); - if (new_file < 0) - { - mi_check_print_error(param,"Can't create new tempfile: '%s'", - param->temp_filename); - goto err; - } - if (share->pack.header_length) - if (filecopy(param,new_file,info->dfile,0L,share->pack.header_length, - "datafile-header")) - goto err; - info->rec_cache.file=new_file; /* Use this file for cacheing*/ - - lock_memory(param); - for (key=0 ; key < share->base.keys ; key++) - share->keyinfo[key].flag|= HA_SORT_ALLOWS_SAME; - - if (my_pread(share->kfile,(byte*) temp_buff, - (uint) keyinfo->block_length, - share->state.key_root[sort_key], - MYF(MY_NABP+MY_WME))) - { - mi_check_print_error(param,"Can't read indexpage from filepos: %s", - (ulong) share->state.key_root[sort_key]); - goto err; - } - - /* Setup param for sort_write_record */ - sort_info.info=info; - sort_info.new_data_file_type=share->data_file_type; - sort_param.fix_datafile=1; - sort_param.master=1; - sort_param.filepos=share->pack.header_length; - old_record_count=info->state->records; - info->state->records=0; - if (sort_info.new_data_file_type != COMPRESSED_RECORD) - share->state.checksum=0; - - if (sort_record_index(&sort_param,info,keyinfo,share->state.key_root[sort_key], - temp_buff, sort_key,new_file,update_index) || - write_data_suffix(&sort_info,1) || - flush_io_cache(&info->rec_cache)) - goto err; - - if (info->state->records != old_record_count) - { - mi_check_print_error(param,"found %s of %s records", - llstr(info->state->records,llbuff), - llstr(old_record_count,llbuff2)); - goto err; - } - - VOID(my_close(info->dfile,MYF(MY_WME))); - param->out_flag|=O_NEW_DATA; /* Data in new file */ - info->dfile=new_file; /* Use new datafile */ - info->state->del=0; - info->state->empty=0; - share->state.dellink= HA_OFFSET_ERROR; - info->state->data_file_length=sort_param.filepos; - share->state.split=info->state->records; /* Only hole records */ - share->state.version=(ulong) time((time_t*) 0); - - info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - - if (param->testflag & T_WRITE_LOOP) - { - VOID(fputs(" \r",stdout)); VOID(fflush(stdout)); - } - got_error=0; - -err: - if (got_error && new_file >= 0) - { - VOID(end_io_cache(&info->rec_cache)); - (void) my_close(new_file,MYF(MY_WME)); - (void) my_raid_delete(param->temp_filename, share->base.raid_chunks, - MYF(MY_WME)); - } - if (temp_buff) - { - my_afree((gptr) temp_buff); - } - my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR)); - info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); - VOID(end_io_cache(&info->rec_cache)); - my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR)); - sort_info.buff=0; - share->state.sortkey=sort_key; - DBUG_RETURN(flush_blocks(param, share->key_cache, share->kfile) | - got_error); -} /* sort_records */ - - - /* Sort records recursive using one index */ - -static int sort_record_index(MI_SORT_PARAM *sort_param,MI_INFO *info, - MI_KEYDEF *keyinfo, - my_off_t page, uchar *buff, uint sort_key, - File new_file,my_bool update_index) -{ - uint nod_flag,used_length,key_length; - uchar *temp_buff,*keypos,*endpos; - my_off_t next_page,rec_pos; - uchar lastkey[MI_MAX_KEY_BUFF]; - char llbuff[22]; - SORT_INFO *sort_info= sort_param->sort_info; - MI_CHECK *param=sort_info->param; - DBUG_ENTER("sort_record_index"); - - nod_flag=mi_test_if_nod(buff); - temp_buff=0; - - if (nod_flag) - { - if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length))) - { - mi_check_print_error(param,"Not Enough memory"); - DBUG_RETURN(-1); - } - } - used_length=mi_getint(buff); - keypos=buff+2+nod_flag; - endpos=buff+used_length; - for ( ;; ) - { - _sanity(__FILE__,__LINE__); - if (nod_flag) - { - next_page=_mi_kpos(nod_flag,keypos); - if (my_pread(info->s->kfile,(byte*) temp_buff, - (uint) keyinfo->block_length, next_page, - MYF(MY_NABP+MY_WME))) - { - mi_check_print_error(param,"Can't read keys from filepos: %s", - llstr(next_page,llbuff)); - goto err; - } - if (sort_record_index(sort_param, info,keyinfo,next_page,temp_buff,sort_key, - new_file, update_index)) - goto err; - } - _sanity(__FILE__,__LINE__); - if (keypos >= endpos || - (key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,lastkey)) - == 0) - break; - rec_pos= _mi_dpos(info,0,lastkey+key_length); - - if ((*info->s->read_rnd)(info,sort_param->record,rec_pos,0)) - { - mi_check_print_error(param,"%d when reading datafile",my_errno); - goto err; - } - if (rec_pos != sort_param->filepos && update_index) - { - _mi_dpointer(info,keypos-nod_flag-info->s->rec_reflength, - sort_param->filepos); - if (movepoint(info,sort_param->record,rec_pos,sort_param->filepos, - sort_key)) - { - mi_check_print_error(param,"%d when updating key-pointers",my_errno); - goto err; - } - } - if (sort_write_record(sort_param)) - goto err; - } - /* Clear end of block to get better compression if the table is backuped */ - bzero((byte*) buff+used_length,keyinfo->block_length-used_length); - if (my_pwrite(info->s->kfile,(byte*) buff,(uint) keyinfo->block_length, - page,param->myf_rw)) - { - mi_check_print_error(param,"%d when updating keyblock",my_errno); - goto err; - } - if (temp_buff) - my_afree((gptr) temp_buff); - DBUG_RETURN(0); -err: - if (temp_buff) - my_afree((gptr) temp_buff); - DBUG_RETURN(1); -} /* sort_record_index */ - - - -/* - Check if myisamchk was killed by a signal - This is overloaded by other programs that want to be able to abort - sorting -*/ - -static int not_killed= 0; - -volatile int *killed_ptr(MI_CHECK *param __attribute__((unused))) -{ - return ¬_killed; /* always NULL */ -} - - /* print warnings and errors */ - /* VARARGS */ - -void mi_check_print_info(MI_CHECK *param __attribute__((unused)), - const char *fmt,...) -{ - va_list args; - - va_start(args,fmt); - VOID(vfprintf(stdout, fmt, args)); - VOID(fputc('\n',stdout)); - va_end(args); -} - -/* VARARGS */ - -void mi_check_print_warning(MI_CHECK *param, const char *fmt,...) -{ - va_list args; - DBUG_ENTER("mi_check_print_warning"); - - fflush(stdout); - if (!param->warning_printed && !param->error_printed) - { - if (param->testflag & T_SILENT) - fprintf(stderr,"%s: MyISAM file %s\n",my_progname_short, - param->isam_file_name); - param->out_flag|= O_DATA_LOST; - } - param->warning_printed=1; - va_start(args,fmt); - fprintf(stderr,"%s: warning: ",my_progname_short); - VOID(vfprintf(stderr, fmt, args)); - VOID(fputc('\n',stderr)); - fflush(stderr); - va_end(args); - DBUG_VOID_RETURN; -} - -/* VARARGS */ - -void mi_check_print_error(MI_CHECK *param, const char *fmt,...) -{ - va_list args; - DBUG_ENTER("mi_check_print_error"); - DBUG_PRINT("enter",("format: %s",fmt)); - - fflush(stdout); - if (!param->warning_printed && !param->error_printed) - { - if (param->testflag & T_SILENT) - fprintf(stderr,"%s: MyISAM file %s\n",my_progname_short,param->isam_file_name); - param->out_flag|= O_DATA_LOST; - } - param->error_printed|=1; - va_start(args,fmt); - fprintf(stderr,"%s: error: ",my_progname_short); - VOID(vfprintf(stderr, fmt, args)); - VOID(fputc('\n',stderr)); - fflush(stderr); - va_end(args); - DBUG_VOID_RETURN; -} diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h deleted file mode 100644 index b66d7e71a05..00000000000 --- a/myisam/myisamdef.h +++ /dev/null @@ -1,736 +0,0 @@ -/* Copyright (C) 2000,2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* This file is included by all internal myisam files */ - -#include "myisam.h" /* Structs & some defines */ -#include "myisampack.h" /* packing of keys */ -#include <my_tree.h> -#ifdef THREAD -#include <my_pthread.h> -#include <thr_lock.h> -#else -#include <my_no_pthread.h> -#endif - -#if defined(my_write) && !defined(MAP_TO_USE_RAID) -#undef my_write /* undef map from my_nosys; We need test-if-disk full */ -#endif - -typedef struct st_mi_status_info -{ - ha_rows records; /* Rows in table */ - ha_rows del; /* Removed rows */ - my_off_t empty; /* lost space in datafile */ - my_off_t key_empty; /* lost space in indexfile */ - my_off_t key_file_length; - my_off_t data_file_length; -} MI_STATUS_INFO; - -typedef struct st_mi_state_info -{ - struct { /* Fileheader */ - uchar file_version[4]; - uchar options[2]; - uchar header_length[2]; - uchar state_info_length[2]; - uchar base_info_length[2]; - uchar base_pos[2]; - uchar key_parts[2]; /* Key parts */ - uchar unique_key_parts[2]; /* Key parts + unique parts */ - uchar keys; /* number of keys in file */ - uchar uniques; /* number of UNIQUE definitions */ - uchar language; /* Language for indexes */ - uchar max_block_size; /* max keyblock size */ - uchar fulltext_keys; - uchar not_used; /* To align to 8 */ - } header; - - MI_STATUS_INFO state; - ha_rows split; /* number of split blocks */ - my_off_t dellink; /* Link to next removed block */ - ulonglong auto_increment; - ulong process; /* process that updated table last */ - ulong unique; /* Unique number for this process */ - ulong update_count; /* Updated for each write lock */ - ulong status; - ulong *rec_per_key_part; - my_off_t *key_root; /* Start of key trees */ - my_off_t *key_del; /* delete links for trees */ - my_off_t rec_per_key_rows; /* Rows when calculating rec_per_key */ - - ulong sec_index_changed; /* Updated when new sec_index */ - ulong sec_index_used; /* which extra index are in use */ - ulonglong key_map; /* Which keys are in use */ - ha_checksum checksum; - ulong version; /* timestamp of create */ - time_t create_time; /* Time when created database */ - time_t recover_time; /* Time for last recover */ - time_t check_time; /* Time for last check */ - uint sortkey; /* sorted by this key (not used) */ - uint open_count; - uint8 changed; /* Changed since myisamchk */ - - /* the following isn't saved on disk */ - uint state_diff_length; /* Should be 0 */ - uint state_length; /* Length of state header in file */ - ulong *key_info; -} MI_STATE_INFO; - -#define MI_STATE_INFO_SIZE (24+14*8+7*4+2*2+8) -#define MI_STATE_KEY_SIZE 8 -#define MI_STATE_KEYBLOCK_SIZE 8 -#define MI_STATE_KEYSEG_SIZE 4 -#define MI_STATE_EXTRA_SIZE ((MI_MAX_KEY+MI_MAX_KEY_BLOCK_SIZE)*MI_STATE_KEY_SIZE + MI_MAX_KEY*MI_MAX_KEY_SEG*MI_STATE_KEYSEG_SIZE) -#define MI_KEYDEF_SIZE (2+ 5*2) -#define MI_UNIQUEDEF_SIZE (2+1+1) -#define HA_KEYSEG_SIZE (6+ 2*2 + 4*2) -#define MI_COLUMNDEF_SIZE (2*3+1) -#define MI_BASE_INFO_SIZE (5*8 + 8*4 + 4 + 4*2 + 16) -#define MI_INDEX_BLOCK_MARGIN 16 /* Safety margin for .MYI tables */ - -typedef struct st_mi_base_info -{ - my_off_t keystart; /* Start of keys */ - my_off_t max_data_file_length; - my_off_t max_key_file_length; - my_off_t margin_key_file_length; - ha_rows records,reloc; /* Create information */ - ulong mean_row_length; /* Create information */ - ulong reclength; /* length of unpacked record */ - ulong pack_reclength; /* Length of full packed rec. */ - ulong min_pack_length; - ulong max_pack_length; /* Max possibly length of packed rec.*/ - ulong min_block_length; - ulong fields, /* fields in table */ - pack_fields; /* packed fields in table */ - uint rec_reflength; /* = 2-8 */ - uint key_reflength; /* = 2-8 */ - uint keys; /* same as in state.header */ - uint auto_key; /* Which key-1 is a auto key */ - uint blobs; /* Number of blobs */ - uint pack_bits; /* Length of packed bits */ - uint max_key_block_length; /* Max block length */ - uint max_key_length; /* Max key length */ - /* Extra allocation when using dynamic record format */ - uint extra_alloc_bytes; - uint extra_alloc_procent; - /* Info about raid */ - uint raid_type,raid_chunks; - ulong raid_chunksize; - /* The following are from the header */ - uint key_parts,all_key_parts; -} MI_BASE_INFO; - - - /* Structs used intern in database */ - -typedef struct st_mi_blob /* Info of record */ -{ - ulong offset; /* Offset to blob in record */ - uint pack_length; /* Type of packed length */ - ulong length; /* Calc:ed for each record */ -} MI_BLOB; - - -typedef struct st_mi_isam_pack { - ulong header_length; - uint ref_length; -} MI_PACK; - - -typedef struct st_mi_isam_share { /* Shared between opens */ - MI_STATE_INFO state; - MI_BASE_INFO base; - MI_KEYDEF ft2_keyinfo; /* Second-level ft-key definition */ - MI_KEYDEF *keyinfo; /* Key definitions */ - MI_UNIQUEDEF *uniqueinfo; /* unique definitions */ - HA_KEYSEG *keyparts; /* key part info */ - MI_COLUMNDEF *rec; /* Pointer to field information */ - MI_PACK pack; /* Data about packed records */ - MI_BLOB *blobs; /* Pointer to blobs */ - char *unique_file_name; /* realpath() of index file */ - char *data_file_name, /* Resolved path names from symlinks */ - *index_file_name; - byte *file_map; /* mem-map of file if possible */ - KEY_CACHE *key_cache; /* ref to the current key cache */ - MI_DECODE_TREE *decode_trees; - uint16 *decode_tables; - int (*read_record)(struct st_myisam_info*, my_off_t, byte*); - int (*write_record)(struct st_myisam_info*, const byte*); - int (*update_record)(struct st_myisam_info*, my_off_t, const byte*); - int (*delete_record)(struct st_myisam_info*); - int (*read_rnd)(struct st_myisam_info*, byte*, my_off_t, my_bool); - int (*compare_record)(struct st_myisam_info*, const byte *); - ha_checksum (*calc_checksum)(struct st_myisam_info*, const byte *); - int (*compare_unique)(struct st_myisam_info*, MI_UNIQUEDEF *, - const byte *record, my_off_t pos); - invalidator_by_filename invalidator; /* query cache invalidator */ - ulong this_process; /* processid */ - ulong last_process; /* For table-change-check */ - ulong last_version; /* Version on start */ - ulong options; /* Options used */ - ulong min_pack_length; /* Theese are used by packed data */ - ulong max_pack_length; - ulong state_diff_length; - uint rec_reflength; /* rec_reflength in use now */ - uint unique_name_length; - File kfile; /* Shared keyfile */ - File data_file; /* Shared data file */ - int mode; /* mode of file on open */ - uint reopen; /* How many times reopened */ - uint w_locks,r_locks,tot_locks; /* Number of read/write locks */ - uint blocksize; /* blocksize of keyfile */ - myf write_flag; - enum data_file_type data_file_type; - my_bool changed, /* If changed since lock */ - global_changed, /* If changed since open */ - not_flushed, - temporary,delay_key_write, - concurrent_insert; -#ifdef THREAD - THR_LOCK lock; - pthread_mutex_t intern_lock; /* Locking for use with _locking */ - rw_lock_t *key_root_lock; -#endif -} MYISAM_SHARE; - - -typedef uint mi_bit_type; - -typedef struct st_mi_bit_buff { /* Used for packing of record */ - mi_bit_type current_byte; - uint bits; - uchar *pos,*end,*blob_pos,*blob_end; - uint error; -} MI_BIT_BUFF; - -struct st_myisam_info { - MYISAM_SHARE *s; /* Shared between open:s */ - MI_STATUS_INFO *state,save_state; - MI_BLOB *blobs; /* Pointer to blobs */ - MI_BIT_BUFF bit_buff; - /* accumulate indexfile changes between write's */ - TREE *bulk_insert; - DYNAMIC_ARRAY *ft1_to_ft2; /* used only in ft1->ft2 conversion */ - char *filename; /* parameter to open filename */ - uchar *buff, /* Temp area for key */ - *lastkey,*lastkey2; /* Last used search key */ - uchar *first_mbr_key; /* Searhed spatial key */ - byte *rec_buff; /* Tempbuff for recordpack */ - uchar *int_keypos, /* Save position for next/previous */ - *int_maxpos; /* -""- */ - uint int_nod_flag; /* -""- */ - uint32 int_keytree_version; /* -""- */ - int (*read_record)(struct st_myisam_info*, my_off_t, byte*); - invalidator_by_filename invalidator; /* query cache invalidator */ - ulong this_unique; /* uniq filenumber or thread */ - ulong last_unique; /* last unique number */ - ulong this_loop; /* counter for this open */ - ulong last_loop; /* last used counter */ - my_off_t lastpos, /* Last record position */ - nextpos; /* Position to next record */ - my_off_t save_lastpos; - my_off_t pos; /* Intern variable */ - my_off_t last_keypage; /* Last key page read */ - my_off_t last_search_keypage; /* Last keypage when searching */ - my_off_t dupp_key_pos; - ha_checksum checksum; - /* QQ: the folloing two xxx_length fields should be removed, - as they are not compatible with parallel repair */ - ulong packed_length,blob_length; /* Length of found, packed record */ - int dfile; /* The datafile */ - uint opt_flag; /* Optim. for space/speed */ - uint update; /* If file changed since open */ - int lastinx; /* Last used index */ - uint lastkey_length; /* Length of key in lastkey */ - uint last_rkey_length; /* Last length in mi_rkey() */ - enum ha_rkey_function last_key_func; /* CONTAIN, OVERLAP, etc */ - uint save_lastkey_length; - int errkey; /* Got last error on this key */ - int lock_type; /* How database was locked */ - int tmp_lock_type; /* When locked by readinfo */ - uint data_changed; /* Somebody has changed data */ - uint save_update; /* When using KEY_READ */ - int save_lastinx; - LIST open_list; - IO_CACHE rec_cache; /* When cacheing records */ - uint preload_buff_size; /* When preloading indexes */ - myf lock_wait; /* is 0 or MY_DONT_WAIT */ - my_bool was_locked; /* Was locked in panic */ - my_bool quick_mode; - my_bool page_changed; /* If info->buff can't be used for rnext */ - my_bool buff_used; /* If info->buff has to be reread for rnext */ - my_bool once_flags; /* For MYISAMMRG */ -#ifdef THREAD - THR_LOCK_DATA lock; -#endif - uchar *rtree_recursion_state; /* For RTREE */ - int rtree_recursion_depth; -}; - -typedef struct st_buffpek { - my_off_t file_pos; /* Where we are in the sort file */ - uchar *base,*key; /* Key pointers */ - ha_rows count; /* Number of rows in table */ - ulong mem_count; /* numbers of keys in memory */ - ulong max_keys; /* Max keys in buffert */ -} BUFFPEK; - -typedef struct st_mi_sort_param -{ - pthread_t thr; - IO_CACHE read_cache, tempfile, tempfile_for_exceptions; - DYNAMIC_ARRAY buffpek; - ulonglong unique[MI_MAX_KEY_SEG+1]; - my_off_t pos,max_pos,filepos,start_recpos; - uint key, key_length,real_key_length,sortbuff_size; - uint maxbuffers, keys, find_length, sort_keys_length; - my_bool fix_datafile, master; - MI_KEYDEF *keyinfo; - HA_KEYSEG *seg; - SORT_INFO *sort_info; - uchar **sort_keys; - byte *rec_buff; - void *wordlist, *wordptr; - char *record; - MY_TMPDIR *tmpdir; - int (*key_cmp)(struct st_mi_sort_param *, const void *, const void *); - int (*key_read)(struct st_mi_sort_param *,void *); - int (*key_write)(struct st_mi_sort_param *, const void *); - void (*lock_in_memory)(MI_CHECK *); - NEAR int (*write_keys)(struct st_mi_sort_param *, register uchar **, - uint , struct st_buffpek *, IO_CACHE *); - NEAR uint (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint); - NEAR int (*write_key)(struct st_mi_sort_param *, IO_CACHE *,char *, - uint, uint); -} MI_SORT_PARAM; - /* Some defines used by isam-funktions */ - -#define USE_WHOLE_KEY MI_MAX_KEY_BUFF*2 /* Use whole key in _mi_search() */ -#define F_EXTRA_LCK -1 - - /* bits in opt_flag */ -#define MEMMAP_USED 32 -#define REMEMBER_OLD_POS 64 - -#define WRITEINFO_UPDATE_KEYFILE 1 -#define WRITEINFO_NO_UNLOCK 2 - - /* once_flags */ -#define USE_PACKED_KEYS 1 -#define RRND_PRESERVE_LASTINX 2 - - /* bits in state.changed */ - -#define STATE_CHANGED 1 -#define STATE_CRASHED 2 -#define STATE_CRASHED_ON_REPAIR 4 -#define STATE_NOT_ANALYZED 8 -#define STATE_NOT_OPTIMIZED_KEYS 16 -#define STATE_NOT_SORTED_PAGES 32 - - /* options to mi_read_cache */ - -#define READING_NEXT 1 -#define READING_HEADER 2 - -#define mi_getint(x) ((uint) mi_uint2korr(x) & 32767) -#define mi_putint(x,y,nod) { uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y);\ - mi_int2store(x,boh); } -#define mi_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0) -#define mi_mark_crashed(x) (x)->s->state.changed|=STATE_CRASHED -#define mi_mark_crashed_on_repair(x) { (x)->s->state.changed|=STATE_CRASHED|STATE_CRASHED_ON_REPAIR ; (x)->update|= HA_STATE_CHANGED; } -#define mi_is_crashed(x) ((x)->s->state.changed & STATE_CRASHED) -#define mi_is_crashed_on_repair(x) ((x)->s->state.changed & STATE_CRASHED_ON_REPAIR) -#define mi_print_error(SHARE, ERRNO) \ - mi_report_error((ERRNO), (SHARE)->index_file_name) - -/* Functions to store length of space packed keys, VARCHAR or BLOB keys */ - -#define store_key_length_inc(key,length) \ -{ if ((length) < 255) \ - { *(key)++=(length); } \ - else \ - { *(key)=255; mi_int2store((key)+1,(length)); (key)+=3; } \ -} - -#define store_key_length(key,length) \ -{ if ((length) < 255) \ - { *(key)=(length); } \ - else \ - { *(key)=255; mi_int2store((key)+1,(length)); } \ -} - -#define get_key_full_length(length,key) \ -{ if ((uchar) *(key) != 255) \ - length= ((uint) (uchar) *((key)++))+1; \ - else \ - { length=mi_uint2korr((key)+1)+3; (key)+=3; } \ -} - -#define get_key_full_length_rdonly(length,key) \ -{ if ((uchar) *(key) != 255) \ - length= ((uint) (uchar) *((key)))+1; \ - else \ - { length=mi_uint2korr((key)+1)+3; } \ -} - -#define get_pack_length(length) ((length) >= 255 ? 3 : 1) - -#define MI_MIN_BLOCK_LENGTH 20 /* Because of delete-link */ -#define MI_EXTEND_BLOCK_LENGTH 20 /* Don't use to small record-blocks */ -#define MI_SPLIT_LENGTH ((MI_EXTEND_BLOCK_LENGTH+4)*2) -#define MI_MAX_DYN_BLOCK_HEADER 20 /* Max prefix of record-block */ -#define MI_BLOCK_INFO_HEADER_LENGTH 20 -#define MI_DYN_DELETE_BLOCK_HEADER 20 /* length of delete-block-header */ -#define MI_DYN_MAX_BLOCK_LENGTH ((1L << 24)-4L) -#define MI_DYN_MAX_ROW_LENGTH (MI_DYN_MAX_BLOCK_LENGTH - MI_SPLIT_LENGTH) -#define MI_DYN_ALIGN_SIZE 4 /* Align blocks on this */ -#define MI_MAX_DYN_HEADER_BYTE 13 /* max header byte for dynamic rows */ -#define MI_MAX_BLOCK_LENGTH ((((ulong) 1 << 24)-1) & (~ (ulong) (MI_DYN_ALIGN_SIZE-1))) -#define MI_REC_BUFF_OFFSET ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER+sizeof(uint32)) - -#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for file */ - -#define PACK_TYPE_SELECTED 1 /* Bits in field->pack_type */ -#define PACK_TYPE_SPACE_FIELDS 2 -#define PACK_TYPE_ZERO_FILL 4 -#define MI_FOUND_WRONG_KEY 32738 /* Impossible value from ha_key_cmp */ - -#define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_MIN_KEY_BLOCK_LENGTH) -#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) (((((key_length)+(data_pointer)+(key_pointer))*4+(key_pointer)+2)/myisam_block_size+1)*myisam_block_size) -#define MI_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */ -#define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */ - -#define MI_MIN_SIZE_BULK_INSERT_TREE 16384 /* this is per key */ -#define MI_MIN_ROWS_TO_USE_BULK_INSERT 100 -#define MI_MIN_ROWS_TO_DISABLE_INDEXES 100 -#define MI_MIN_ROWS_TO_USE_WRITE_CACHE 10 - -/* The UNIQUE check is done with a hashed long key */ - -#define MI_UNIQUE_HASH_TYPE HA_KEYTYPE_ULONG_INT -#define mi_unique_store(A,B) mi_int4store((A),(B)) - -#ifdef THREAD -extern pthread_mutex_t THR_LOCK_myisam; -#endif -#if !defined(THREAD) || defined(DONT_USE_RW_LOCKS) -#define rw_wrlock(A) {} -#define rw_rdlock(A) {} -#define rw_unlock(A) {} -#endif - - /* Some extern variables */ - -extern LIST *myisam_open_list; -extern uchar NEAR myisam_file_magic[],NEAR myisam_pack_file_magic[]; -extern uint NEAR myisam_read_vec[],NEAR myisam_readnext_vec[]; -extern uint myisam_quick_table_bits; -extern File myisam_log_file; -extern ulong myisam_pid; - - /* This is used by _mi_calc_xxx_key_length och _mi_store_key */ - -typedef struct st_mi_s_param -{ - uint ref_length,key_length, - n_ref_length, - n_length, - totlength, - part_of_prev_key,prev_length,pack_marker; - uchar *key, *prev_key,*next_key_pos; - bool store_not_null; -} MI_KEY_PARAM; - - /* Prototypes for intern functions */ - -extern int _mi_read_dynamic_record(MI_INFO *info,my_off_t filepos,byte *buf); -extern int _mi_write_dynamic_record(MI_INFO*, const byte*); -extern int _mi_update_dynamic_record(MI_INFO*, my_off_t, const byte*); -extern int _mi_delete_dynamic_record(MI_INFO *info); -extern int _mi_cmp_dynamic_record(MI_INFO *info,const byte *record); -extern int _mi_read_rnd_dynamic_record(MI_INFO *, byte *,my_off_t, my_bool); -extern int _mi_write_blob_record(MI_INFO*, const byte*); -extern int _mi_update_blob_record(MI_INFO*, my_off_t, const byte*); -extern int _mi_read_static_record(MI_INFO *info, my_off_t filepos,byte *buf); -extern int _mi_write_static_record(MI_INFO*, const byte*); -extern int _mi_update_static_record(MI_INFO*, my_off_t, const byte*); -extern int _mi_delete_static_record(MI_INFO *info); -extern int _mi_cmp_static_record(MI_INFO *info,const byte *record); -extern int _mi_read_rnd_static_record(MI_INFO*, byte *,my_off_t, my_bool); -extern int _mi_ck_write(MI_INFO *info,uint keynr,uchar *key,uint length); -extern int _mi_ck_real_write_btree(MI_INFO *info, MI_KEYDEF *keyinfo, - uchar *key, uint key_length, - my_off_t *root, uint comp_flag); -extern int _mi_enlarge_root(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key, my_off_t *root); -extern int _mi_insert(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key, - uchar *anc_buff,uchar *key_pos,uchar *key_buff, - uchar *father_buff, uchar *father_keypos, - my_off_t father_page, my_bool insert_last); -extern int _mi_split_page(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key, - uchar *buff,uchar *key_buff, my_bool insert_last); -extern uchar *_mi_find_half_pos(uint nod_flag,MI_KEYDEF *keyinfo,uchar *page, - uchar *key,uint *return_key_length, - uchar **after_key); -extern int _mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint nod_flag, - uchar *key_pos, uchar *org_key, - uchar *key_buff, - uchar *key, MI_KEY_PARAM *s_temp); -extern int _mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint nod_flag, - uchar *key_pos, uchar *org_key, - uchar *key_buff, - uchar *key, MI_KEY_PARAM *s_temp); -extern int _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag, - uchar *key_pos, uchar *org_key, - uchar *prev_key, - uchar *key, MI_KEY_PARAM *s_temp); -extern int _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag, - uchar *key_pos,uchar *org_key, - uchar *prev_key, - uchar *key, MI_KEY_PARAM *s_temp); -void _mi_store_static_key(MI_KEYDEF *keyinfo, uchar *key_pos, - MI_KEY_PARAM *s_temp); -void _mi_store_var_pack_key(MI_KEYDEF *keyinfo, uchar *key_pos, - MI_KEY_PARAM *s_temp); -#ifdef NOT_USED -void _mi_store_pack_key(MI_KEYDEF *keyinfo, uchar *key_pos, - MI_KEY_PARAM *s_temp); -#endif -void _mi_store_bin_pack_key(MI_KEYDEF *keyinfo, uchar *key_pos, - MI_KEY_PARAM *s_temp); - -extern int _mi_ck_delete(MI_INFO *info,uint keynr,uchar *key,uint key_length); -extern int _mi_readinfo(MI_INFO *info,int lock_flag,int check_keybuffer); -extern int _mi_writeinfo(MI_INFO *info,uint options); -extern int _mi_test_if_changed(MI_INFO *info); -extern int _mi_mark_file_changed(MI_INFO *info); -extern int _mi_decrement_open_count(MI_INFO *info); -extern int _mi_check_index(MI_INFO *info,int inx); -extern int _mi_search(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,uint key_len, - uint nextflag,my_off_t pos); -extern int _mi_bin_search(struct st_myisam_info *info,MI_KEYDEF *keyinfo, - uchar *page,uchar *key,uint key_len,uint comp_flag, - uchar * *ret_pos,uchar *buff, my_bool *was_last_key); -extern int _mi_seq_search(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *page, - uchar *key,uint key_len,uint comp_flag, - uchar **ret_pos,uchar *buff, my_bool *was_last_key); -extern int _mi_prefix_search(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *page, - uchar *key,uint key_len,uint comp_flag, - uchar **ret_pos,uchar *buff, my_bool *was_last_key); -extern my_off_t _mi_kpos(uint nod_flag,uchar *after_key); -extern void _mi_kpointer(MI_INFO *info,uchar *buff,my_off_t pos); -extern my_off_t _mi_dpos(MI_INFO *info, uint nod_flag,uchar *after_key); -extern my_off_t _mi_rec_pos(MYISAM_SHARE *info, uchar *ptr); -extern void _mi_dpointer(MI_INFO *info, uchar *buff,my_off_t pos); -extern int ha_key_cmp(HA_KEYSEG *keyseg, uchar *a,uchar *b, - uint key_length,uint nextflag,uint *diff_length); -extern uint _mi_get_static_key(MI_KEYDEF *keyinfo,uint nod_flag,uchar * *page, - uchar *key); -extern uint _mi_get_pack_key(MI_KEYDEF *keyinfo,uint nod_flag,uchar * *page, - uchar *key); -extern uint _mi_get_binary_pack_key(MI_KEYDEF *keyinfo, uint nod_flag, - uchar **page_pos, uchar *key); -extern uchar *_mi_get_last_key(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *keypos, - uchar *lastkey,uchar *endpos, - uint *return_key_length); -extern uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, - uchar *key, uchar *keypos, uint *return_key_length); -extern uint _mi_keylength(MI_KEYDEF *keyinfo,uchar *key); -extern uint _mi_keylength_part(MI_KEYDEF *keyinfo, register uchar *key, - HA_KEYSEG *end); -extern uchar *_mi_move_key(MI_KEYDEF *keyinfo,uchar *to,uchar *from); -extern int _mi_search_next(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key, - uint key_length,uint nextflag,my_off_t pos); -extern int _mi_search_first(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos); -extern int _mi_search_last(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos); -extern uchar *_mi_fetch_keypage(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t page, - int level,uchar *buff,int return_buffer); -extern int _mi_write_keypage(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t page, - int level, uchar *buff); -extern int _mi_dispose(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos, - int level); -extern my_off_t _mi_new(MI_INFO *info,MI_KEYDEF *keyinfo,int level); -extern uint _mi_make_key(MI_INFO *info,uint keynr,uchar *key, - const byte *record,my_off_t filepos); -extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old, - uint key_length, HA_KEYSEG **last_used_keyseg); -extern int _mi_read_key_record(MI_INFO *info,my_off_t filepos,byte *buf); -extern int _mi_read_cache(IO_CACHE *info,byte *buff,my_off_t pos, - uint length,int re_read_if_possibly); -extern void update_auto_increment(MI_INFO *info,const byte *record); - -extern byte *mi_alloc_rec_buff(MI_INFO *,ulong, byte**); -#define mi_get_rec_buff_ptr(info,buf) \ - ((((info)->s->options & HA_OPTION_PACK_RECORD) && (buf)) ? \ - (buf) - MI_REC_BUFF_OFFSET : (buf)) -#define mi_get_rec_buff_len(info,buf) \ - (*((uint32 *)(mi_get_rec_buff_ptr(info,buf)))) - -extern ulong _mi_rec_unpack(MI_INFO *info,byte *to,byte *from, - ulong reclength); -extern my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *packpos, - ulong reclength); -extern int _mi_write_part_record(MI_INFO *info,my_off_t filepos,ulong length, - my_off_t next_filepos,byte **record, - ulong *reclength,int *flag); -extern void _mi_print_key(FILE *stream,HA_KEYSEG *keyseg,const uchar *key, - uint length); -extern my_bool _mi_read_pack_info(MI_INFO *info,pbool fix_keys); -extern int _mi_read_pack_record(MI_INFO *info,my_off_t filepos,byte *buf); -extern int _mi_read_rnd_pack_record(MI_INFO*, byte *,my_off_t, my_bool); -extern int _mi_pack_rec_unpack(MI_INFO *info,byte *to,byte *from, - ulong reclength); -extern ulonglong mi_safe_mul(ulonglong a,ulonglong b); -extern int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf, - const byte *oldrec, const byte *newrec, my_off_t pos); - -struct st_sort_info; - - -typedef struct st_mi_block_info { /* Parameter to _mi_get_block_info */ - uchar header[MI_BLOCK_INFO_HEADER_LENGTH]; - ulong rec_len; - ulong data_len; - ulong block_len; - ulong blob_len; - my_off_t filepos; - my_off_t next_filepos; - my_off_t prev_filepos; - uint second_read; - uint offset; -} MI_BLOCK_INFO; - - /* bits in return from _mi_get_block_info */ - -#define BLOCK_FIRST 1 -#define BLOCK_LAST 2 -#define BLOCK_DELETED 4 -#define BLOCK_ERROR 8 /* Wrong data */ -#define BLOCK_SYNC_ERROR 16 /* Right data at wrong place */ -#define BLOCK_FATAL_ERROR 32 /* hardware-error */ - -#define NEED_MEM ((uint) 10*4*(IO_SIZE+32)+32) /* Nead for recursion */ -#define MAXERR 20 -#define BUFFERS_WHEN_SORTING 16 /* Alloc for sort-key-tree */ -#define WRITE_COUNT MY_HOW_OFTEN_TO_WRITE -#define INDEX_TMP_EXT ".TMM" -#define DATA_TMP_EXT ".TMD" - -#define UPDATE_TIME 1 -#define UPDATE_STAT 2 -#define UPDATE_SORT 4 -#define UPDATE_AUTO_INC 8 -#define UPDATE_OPEN_COUNT 16 - -#define USE_BUFFER_INIT (((1024L*512L-MALLOC_OVERHEAD)/IO_SIZE)*IO_SIZE) -#define READ_BUFFER_INIT (1024L*256L-MALLOC_OVERHEAD) -#define SORT_BUFFER_INIT (2048L*1024L-MALLOC_OVERHEAD) -#define MIN_SORT_BUFFER (4096-MALLOC_OVERHEAD) - -enum myisam_log_commands { - MI_LOG_OPEN,MI_LOG_WRITE,MI_LOG_UPDATE,MI_LOG_DELETE,MI_LOG_CLOSE,MI_LOG_EXTRA,MI_LOG_LOCK,MI_LOG_DELETE_ALL -}; - -#define myisam_log(a,b,c,d) if (myisam_log_file >= 0) _myisam_log(a,b,c,d) -#define myisam_log_command(a,b,c,d,e) if (myisam_log_file >= 0) _myisam_log_command(a,b,c,d,e) -#define myisam_log_record(a,b,c,d,e) if (myisam_log_file >= 0) _myisam_log_record(a,b,c,d,e) - -#define fast_mi_writeinfo(INFO) if (!(INFO)->s->tot_locks) (void) _mi_writeinfo((INFO),0) -#define fast_mi_readinfo(INFO) ((INFO)->lock_type == F_UNLCK) && _mi_readinfo((INFO),F_RDLCK,1) - -#ifdef __cplusplus -extern "C" { -#endif - -extern uint _mi_get_block_info(MI_BLOCK_INFO *,File, my_off_t); -extern uint _mi_rec_pack(MI_INFO *info,byte *to,const byte *from); -extern uint _mi_pack_get_block_info(MI_INFO *, MI_BLOCK_INFO *, File, my_off_t); -extern void _my_store_blob_length(byte *pos,uint pack_length,uint length); -extern void _myisam_log(enum myisam_log_commands command,MI_INFO *info, - const byte *buffert,uint length); -extern void _myisam_log_command(enum myisam_log_commands command, - MI_INFO *info, const byte *buffert, - uint length, int result); -extern void _myisam_log_record(enum myisam_log_commands command,MI_INFO *info, - const byte *record,my_off_t filepos, - int result); -extern void mi_report_error(int errcode, const char *file_name); -extern my_bool _mi_memmap_file(MI_INFO *info); -extern void _mi_unmap_file(MI_INFO *info); -extern uint save_pack_length(byte *block_buff,ulong length); - -uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite); -char *mi_state_info_read(char *ptr, MI_STATE_INFO *state); -uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead); -uint mi_base_info_write(File file, MI_BASE_INFO *base); -char *my_n_base_info_read(char *ptr, MI_BASE_INFO *base); -int mi_keyseg_write(File file, const HA_KEYSEG *keyseg); -char *mi_keyseg_read(char *ptr, HA_KEYSEG *keyseg); -uint mi_keydef_write(File file, MI_KEYDEF *keydef); -char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef); -uint mi_uniquedef_write(File file, MI_UNIQUEDEF *keydef); -char *mi_uniquedef_read(char *ptr, MI_UNIQUEDEF *keydef); -uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo); -char *mi_recinfo_read(char *ptr, MI_COLUMNDEF *recinfo); -extern int mi_disable_indexes(MI_INFO *info); -extern int mi_enable_indexes(MI_INFO *info); -extern int mi_indexes_are_disabled(MI_INFO *info); -ulong _my_calc_total_blob_length(MI_INFO *info, const byte *record); -ha_checksum mi_checksum(MI_INFO *info, const byte *buf); -ha_checksum mi_static_checksum(MI_INFO *info, const byte *buf); -my_bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, byte *record, - ha_checksum unique_hash, my_off_t pos); -ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *buf); -int _mi_cmp_static_unique(MI_INFO *info, MI_UNIQUEDEF *def, - const byte *record, my_off_t pos); -int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def, - const byte *record, my_off_t pos); -int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b, - my_bool null_are_equal); -void mi_get_status(void* param); -void mi_update_status(void* param); -void mi_copy_status(void* to,void *from); -my_bool mi_check_status(void* param); -void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows); - -extern MI_INFO *test_if_reopen(char *filename); -my_bool check_table_is_closed(const char *name, const char *where); -int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup); -int mi_open_keyfile(MYISAM_SHARE *share); -void mi_setup_functions(register MYISAM_SHARE *share); - - /* Functions needed by mi_check */ -volatile int *killed_ptr(MI_CHECK *param); -void mi_check_print_error _VARARGS((MI_CHECK *param, const char *fmt,...)); -void mi_check_print_warning _VARARGS((MI_CHECK *param, const char *fmt,...)); -void mi_check_print_info _VARARGS((MI_CHECK *param, const char *fmt,...)); -int flush_pending_blocks(MI_SORT_PARAM *param); -int sort_ft_buf_flush(MI_SORT_PARAM *sort_param); -int thr_write_keys(MI_SORT_PARAM *sort_param); -#ifdef THREAD -pthread_handler_decl(thr_find_all_keys,arg); -#endif -int flush_blocks(MI_CHECK *param, KEY_CACHE *key_cache, File file); - -int sort_write_record(MI_SORT_PARAM *sort_param); -int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, ulong); - -#ifdef __cplusplus -} -#endif - diff --git a/myisam/myisamlog.c b/myisam/myisamlog.c deleted file mode 100644 index dc98d813266..00000000000 --- a/myisam/myisamlog.c +++ /dev/null @@ -1,845 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* write whats in isam.log */ - -#ifndef USE_MY_FUNC -#define USE_MY_FUNC -#endif - -#include "myisamdef.h" -#include <my_tree.h> -#include <stdarg.h> -#ifdef HAVE_GETRUSAGE -#include <sys/resource.h> -#endif - -#define FILENAME(A) (A ? A->show_name : "Unknown") - -struct file_info { - long process; - int filenr,id; - uint rnd; - my_string name,show_name,record; - MI_INFO *isam; - bool closed,used; - ulong accessed; -}; - -struct test_if_open_param { - my_string name; - int max_id; -}; - -struct st_access_param -{ - ulong min_accessed; - struct file_info *found; -}; - -#define NO_FILEPOS (ulong) ~0L - -extern int main(int argc,char * *argv); -static void get_options(int *argc,char ***argv); -static int examine_log(my_string file_name,char **table_names); -static int read_string(IO_CACHE *file,gptr *to,uint length); -static int file_info_compare(void *cmp_arg, void *a,void *b); -static int test_if_open(struct file_info *key,element_count count, - struct test_if_open_param *param); -static void fix_blob_pointers(MI_INFO *isam,byte *record); -static int test_when_accessed(struct file_info *key,element_count count, - struct st_access_param *access_param); -static void file_info_free(struct file_info *info); -static int close_some_file(TREE *tree); -static int reopen_closed_file(TREE *tree,struct file_info *file_info); -static int find_record_with_key(struct file_info *file_info,byte *record); -static void printf_log(const char *str,...); -static bool cmp_filename(struct file_info *file_info,my_string name); - -static uint verbose=0,update=0,test_info=0,max_files=0,re_open_count=0, - recover=0,prefix_remove=0,opt_processes=0; -static my_string log_filename=0,filepath=0,write_filename=0,record_pos_file=0; -static ulong com_count[10][3],number_of_commands=(ulong) ~0L, - isamlog_process; -static my_off_t isamlog_filepos,start_offset=0,record_pos= HA_OFFSET_ERROR; -static const char *command_name[]= -{"open","write","update","delete","close","extra","lock","re-open", - "delete-all", NullS}; - - -int main(int argc, char **argv) -{ - int error,i,first; - ulong total_count,total_error,total_recover; - MY_INIT(argv[0]); - - log_filename=myisam_log_filename; - get_options(&argc,&argv); - /* Number of MyISAM files we can have open at one time */ - max_files= (my_set_max_open_files(min(max_files,8))-6)/2; - if (update) - printf("Trying to %s MyISAM files according to log '%s'\n", - (recover ? "recover" : "update"),log_filename); - error= examine_log(log_filename,argv); - if (update && ! error) - puts("Tables updated successfully"); - total_count=total_error=total_recover=0; - for (i=first=0 ; command_name[i] ; i++) - { - if (com_count[i][0]) - { - if (!first++) - { - if (verbose || update) - puts(""); - puts("Commands Used count Errors Recover errors"); - } - printf("%-12s%9ld%10ld%17ld\n",command_name[i],com_count[i][0], - com_count[i][1],com_count[i][2]); - total_count+=com_count[i][0]; - total_error+=com_count[i][1]; - total_recover+=com_count[i][2]; - } - } - if (total_count) - printf("%-12s%9ld%10ld%17ld\n","Total",total_count,total_error, - total_recover); - if (re_open_count) - printf("Had to do %d re-open because of too few possibly open files\n", - re_open_count); - VOID(mi_panic(HA_PANIC_CLOSE)); - my_free_open_file_info(); - my_end(test_info ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR); - exit(error); - return 0; /* No compiler warning */ -} /* main */ - - -static void get_options(register int *argc, register char ***argv) -{ - int help,version; - const char *pos,*usage; - char option; - - help=0; - usage="Usage: %s [-?iruvDIV] [-c #] [-f #] [-F filepath/] [-o #] [-R file recordpos] [-w write_file] [log-filename [table ...]] \n"; - pos=""; - - while (--*argc > 0 && *(pos = *(++*argv)) == '-' ) { - while (*++pos) - { - version=0; - switch((option=*pos)) { - case '#': - DBUG_PUSH (++pos); - pos=" "; /* Skip rest of arg */ - break; - case 'c': - if (! *++pos) - { - if (!--*argc) - goto err; - else - pos= *(++*argv); - } - number_of_commands=(ulong) atol(pos); - pos=" "; - break; - case 'u': - update=1; - break; - case 'f': - if (! *++pos) - { - if (!--*argc) - goto err; - else - pos= *(++*argv); - } - max_files=(uint) atoi(pos); - pos=" "; - break; - case 'i': - test_info=1; - break; - case 'o': - if (! *++pos) - { - if (!--*argc) - goto err; - else - pos= *(++*argv); - } - start_offset=(my_off_t) strtoll(pos,NULL,10); - pos=" "; - break; - case 'p': - if (! *++pos) - { - if (!--*argc) - goto err; - else - pos= *(++*argv); - } - prefix_remove=atoi(pos); - break; - case 'r': - update=1; - recover++; - break; - case 'P': - opt_processes=1; - break; - case 'R': - if (! *++pos) - { - if (!--*argc) - goto err; - else - pos= *(++*argv); - } - record_pos_file=(char*) pos; - if (!--*argc) - goto err; - record_pos=(my_off_t) strtoll(*(++*argv),NULL,10); - pos=" "; - break; - case 'v': - verbose++; - break; - case 'w': - if (! *++pos) - { - if (!--*argc) - goto err; - else - pos= *(++*argv); - } - write_filename=(char*) pos; - pos=" "; - break; - case 'F': - if (! *++pos) - { - if (!--*argc) - goto err; - else - pos= *(++*argv); - } - filepath= (char*) pos; - pos=" "; - break; - case 'V': - version=1; - /* Fall through */ - case 'I': - case '?': -#include <help_start.h> - printf("%s Ver 1.4 for %s at %s\n",my_progname,SYSTEM_TYPE, - MACHINE_TYPE); - puts("By Monty, for your professional use\n"); - if (version) - break; - puts("Write info about whats in a MyISAM log file."); - printf("If no file name is given %s is used\n",log_filename); - puts(""); - printf(usage,my_progname); - puts(""); - puts("Options: -? or -I \"Info\" -V \"version\" -c \"do only # commands\""); - puts(" -f \"max open files\" -F \"filepath\" -i \"extra info\""); - puts(" -o \"offset\" -p # \"remove # components from path\""); - puts(" -r \"recover\" -R \"file recordposition\""); - puts(" -u \"update\" -v \"verbose\" -w \"write file\""); - puts(" -D \"myisam compiled with DBUG\" -P \"processes\""); - puts("\nOne can give a second and a third '-v' for more verbose."); - puts("Normaly one does a update (-u)."); - puts("If a recover is done all writes and all possibly updates and deletes is done\nand errors are only counted."); - puts("If one gives table names as arguments only these tables will be updated\n"); - help=1; -#include <help_end.h> - break; - default: - printf("illegal option: \"-%c\"\n",*pos); - break; - } - } - } - if (! *argc) - { - if (help) - exit(0); - (*argv)++; - } - if (*argc >= 1) - { - log_filename=(char*) pos; - (*argc)--; - (*argv)++; - } - return; - err: - VOID(fprintf(stderr,"option \"%c\" used without or with wrong argument\n", - option)); - exit(1); -} - - -static int examine_log(my_string file_name, char **table_names) -{ - uint command,result,files_open; - ulong access_time,length; - my_off_t filepos; - int lock_command,mi_result; - char isam_file_name[FN_REFLEN],llbuff[21],llbuff2[21]; - uchar head[20]; - gptr buff; - struct test_if_open_param open_param; - IO_CACHE cache; - File file; - FILE *write_file; - enum ha_extra_function extra_command; - TREE tree; - struct file_info file_info,*curr_file_info; - DBUG_ENTER("examine_log"); - - if ((file=my_open(file_name,O_RDONLY,MYF(MY_WME))) < 0) - DBUG_RETURN(1); - write_file=0; - if (write_filename) - { - if (!(write_file=my_fopen(write_filename,O_WRONLY,MYF(MY_WME)))) - { - my_close(file,MYF(0)); - DBUG_RETURN(1); - } - } - - init_io_cache(&cache,file,0,READ_CACHE,start_offset,0,MYF(0)); - bzero((gptr) com_count,sizeof(com_count)); - init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1, - (tree_element_free) file_info_free, NULL); - VOID(init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE, - 0, 0)); - - files_open=0; access_time=0; - while (access_time++ != number_of_commands && - !my_b_read(&cache,(byte*) head,9)) - { - isamlog_filepos=my_b_tell(&cache)-9L; - file_info.filenr= mi_uint2korr(head+1); - isamlog_process=file_info.process=(long) mi_uint4korr(head+3); - if (!opt_processes) - file_info.process=0; - result= mi_uint2korr(head+7); - if ((curr_file_info=(struct file_info*) tree_search(&tree, &file_info, - tree.custom_arg))) - { - curr_file_info->accessed=access_time; - if (update && curr_file_info->used && curr_file_info->closed) - { - if (reopen_closed_file(&tree,curr_file_info)) - { - command=sizeof(com_count)/sizeof(com_count[0][0])/3; - result=0; - goto com_err; - } - } - } - command=(uint) head[0]; - if (command < sizeof(com_count)/sizeof(com_count[0][0])/3 && - (!table_names[0] || (curr_file_info && curr_file_info->used))) - { - com_count[command][0]++; - if (result) - com_count[command][1]++; - } - switch ((enum myisam_log_commands) command) { - case MI_LOG_OPEN: - if (!table_names[0]) - { - com_count[command][0]--; /* Must be counted explicite */ - if (result) - com_count[command][1]--; - } - - if (curr_file_info) - printf("\nWarning: %s is opened with same process and filenumber\nMaybe you should use the -P option ?\n", - curr_file_info->show_name); - if (my_b_read(&cache,(byte*) head,2)) - goto err; - file_info.name=0; - file_info.show_name=0; - file_info.record=0; - if (read_string(&cache,(gptr*) &file_info.name, - (uint) mi_uint2korr(head))) - goto err; - { - uint i; - char *pos,*to; - - /* Fix if old DOS files to new format */ - for (pos=file_info.name; (pos=strchr(pos,'\\')) ; pos++) - *pos= '/'; - - pos=file_info.name; - for (i=0 ; i < prefix_remove ; i++) - { - char *next; - if (!(next=strchr(pos,'/'))) - break; - pos=next+1; - } - to=isam_file_name; - if (filepath) - to=convert_dirname(isam_file_name,filepath,NullS); - strmov(to,pos); - fn_ext(isam_file_name)[0]=0; /* Remove extension */ - } - open_param.name=file_info.name; - open_param.max_id=0; - VOID(tree_walk(&tree,(tree_walk_action) test_if_open,(void*) &open_param, - left_root_right)); - file_info.id=open_param.max_id+1; - /* - * In the line below +10 is added to accomodate '<' and '>' chars - * plus '\0' at the end, so that there is place for 7 digits. - * It is improbable that same table can have that many entries in - * the table cache. - * The additional space is needed for the sprintf commands two lines - * below. - */ - file_info.show_name=my_memdup(isam_file_name, - (uint) strlen(isam_file_name)+10, - MYF(MY_WME)); - if (file_info.id > 1) - sprintf(strend(file_info.show_name),"<%d>",file_info.id); - file_info.closed=1; - file_info.accessed=access_time; - file_info.used=1; - if (table_names[0]) - { - char **name; - file_info.used=0; - for (name=table_names ; *name ; name++) - { - if (!strcmp(*name,isam_file_name)) - file_info.used=1; /* Update/log only this */ - } - } - if (update && file_info.used) - { - if (files_open >= max_files) - { - if (close_some_file(&tree)) - goto com_err; - files_open--; - } - if (!(file_info.isam= mi_open(isam_file_name,O_RDWR, - HA_OPEN_WAIT_IF_LOCKED))) - goto com_err; - if (!(file_info.record=my_malloc(file_info.isam->s->base.reclength, - MYF(MY_WME)))) - goto end; - files_open++; - file_info.closed=0; - } - VOID(tree_insert(&tree, (gptr) &file_info, 0, tree.custom_arg)); - if (file_info.used) - { - if (verbose && !record_pos_file) - printf_log("%s: open -> %d",file_info.show_name, file_info.filenr); - com_count[command][0]++; - if (result) - com_count[command][1]++; - } - break; - case MI_LOG_CLOSE: - if (verbose && !record_pos_file && - (!table_names[0] || (curr_file_info && curr_file_info->used))) - printf_log("%s: %s -> %d",FILENAME(curr_file_info), - command_name[command],result); - if (curr_file_info) - { - if (!curr_file_info->closed) - files_open--; - VOID(tree_delete(&tree, (gptr) curr_file_info, tree.custom_arg)); - } - break; - case MI_LOG_EXTRA: - if (my_b_read(&cache,(byte*) head,1)) - goto err; - extra_command=(enum ha_extra_function) head[0]; - if (verbose && !record_pos_file && - (!table_names[0] || (curr_file_info && curr_file_info->used))) - printf_log("%s: %s(%d) -> %d",FILENAME(curr_file_info), - command_name[command], (int) extra_command,result); - if (update && curr_file_info && !curr_file_info->closed) - { - if (mi_extra(curr_file_info->isam, extra_command, 0) != (int) result) - { - fflush(stdout); - VOID(fprintf(stderr, - "Warning: error %d, expected %d on command %s at %s\n", - my_errno,result,command_name[command], - llstr(isamlog_filepos,llbuff))); - fflush(stderr); - } - } - break; - case MI_LOG_DELETE: - if (my_b_read(&cache,(byte*) head,8)) - goto err; - filepos=mi_sizekorr(head); - if (verbose && (!record_pos_file || - ((record_pos == filepos || record_pos == NO_FILEPOS) && - !cmp_filename(curr_file_info,record_pos_file))) && - (!table_names[0] || (curr_file_info && curr_file_info->used))) - printf_log("%s: %s at %ld -> %d",FILENAME(curr_file_info), - command_name[command],(long) filepos,result); - if (update && curr_file_info && !curr_file_info->closed) - { - if (mi_rrnd(curr_file_info->isam,curr_file_info->record,filepos)) - { - if (!recover) - goto com_err; - if (verbose) - printf_log("error: Didn't find row to delete with mi_rrnd"); - com_count[command][2]++; /* Mark error */ - } - mi_result=mi_delete(curr_file_info->isam,curr_file_info->record); - if ((mi_result == 0 && result) || - (mi_result && (uint) my_errno != result)) - { - if (!recover) - goto com_err; - if (mi_result) - com_count[command][2]++; /* Mark error */ - if (verbose) - printf_log("error: Got result %d from mi_delete instead of %d", - mi_result, result); - } - } - break; - case MI_LOG_WRITE: - case MI_LOG_UPDATE: - if (my_b_read(&cache,(byte*) head,12)) - goto err; - filepos=mi_sizekorr(head); - length=mi_uint4korr(head+8); - buff=0; - if (read_string(&cache,&buff,(uint) length)) - goto err; - if ((!record_pos_file || - ((record_pos == filepos || record_pos == NO_FILEPOS) && - !cmp_filename(curr_file_info,record_pos_file))) && - (!table_names[0] || (curr_file_info && curr_file_info->used))) - { - if (write_file && - (my_fwrite(write_file,buff,length,MYF(MY_WAIT_IF_FULL | MY_NABP)))) - goto end; - if (verbose) - printf_log("%s: %s at %ld, length=%ld -> %d", - FILENAME(curr_file_info), - command_name[command], filepos,length,result); - } - if (update && curr_file_info && !curr_file_info->closed) - { - if (curr_file_info->isam->s->base.blobs) - fix_blob_pointers(curr_file_info->isam,buff); - if ((enum myisam_log_commands) command == MI_LOG_UPDATE) - { - if (mi_rrnd(curr_file_info->isam,curr_file_info->record,filepos)) - { - if (!recover) - { - result=0; - goto com_err; - } - if (verbose) - printf_log("error: Didn't find row to update with mi_rrnd"); - if (recover == 1 || result || - find_record_with_key(curr_file_info,buff)) - { - com_count[command][2]++; /* Mark error */ - break; - } - } - mi_result=mi_update(curr_file_info->isam,curr_file_info->record, - buff); - if ((mi_result == 0 && result) || - (mi_result && (uint) my_errno != result)) - { - if (!recover) - goto com_err; - if (verbose) - printf_log("error: Got result %d from mi_update instead of %d", - mi_result, result); - if (mi_result) - com_count[command][2]++; /* Mark error */ - } - } - else - { - mi_result=mi_write(curr_file_info->isam,buff); - if ((mi_result == 0 && result) || - (mi_result && (uint) my_errno != result)) - { - if (!recover) - goto com_err; - if (verbose) - printf_log("error: Got result %d from mi_write instead of %d", - mi_result, result); - if (mi_result) - com_count[command][2]++; /* Mark error */ - } - if (!recover && filepos != curr_file_info->isam->lastpos) - { - printf("error: Wrote at position: %s, should have been %s", - llstr(curr_file_info->isam->lastpos,llbuff), - llstr(filepos,llbuff2)); - goto end; - } - } - } - my_free(buff,MYF(0)); - break; - case MI_LOG_LOCK: - if (my_b_read(&cache,(byte*) head,sizeof(lock_command))) - goto err; - memcpy_fixed(&lock_command,head,sizeof(lock_command)); - if (verbose && !record_pos_file && - (!table_names[0] || (curr_file_info && curr_file_info->used))) - printf_log("%s: %s(%d) -> %d\n",FILENAME(curr_file_info), - command_name[command],lock_command,result); - if (update && curr_file_info && !curr_file_info->closed) - { - if (mi_lock_database(curr_file_info->isam,lock_command) != - (int) result) - goto com_err; - } - break; - case MI_LOG_DELETE_ALL: - if (verbose && !record_pos_file && - (!table_names[0] || (curr_file_info && curr_file_info->used))) - printf_log("%s: %s -> %d\n",FILENAME(curr_file_info), - command_name[command],result); - break; - default: - fflush(stdout); - VOID(fprintf(stderr, - "Error: found unknown command %d in logfile, aborted\n", - command)); - fflush(stderr); - goto end; - } - } - end_key_cache(dflt_key_cache,1); - delete_tree(&tree); - VOID(end_io_cache(&cache)); - VOID(my_close(file,MYF(0))); - if (write_file && my_fclose(write_file,MYF(MY_WME))) - DBUG_RETURN(1); - DBUG_RETURN(0); - - err: - fflush(stdout); - VOID(fprintf(stderr,"Got error %d when reading from logfile\n",my_errno)); - fflush(stderr); - goto end; - com_err: - fflush(stdout); - VOID(fprintf(stderr,"Got error %d, expected %d on command %s at %s\n", - my_errno,result,command_name[command], - llstr(isamlog_filepos,llbuff))); - fflush(stderr); - end: - end_key_cache(dflt_key_cache, 1); - delete_tree(&tree); - VOID(end_io_cache(&cache)); - VOID(my_close(file,MYF(0))); - if (write_file) - VOID(my_fclose(write_file,MYF(MY_WME))); - DBUG_RETURN(1); -} - - -static int read_string(IO_CACHE *file, register gptr *to, register uint length) -{ - DBUG_ENTER("read_string"); - - if (*to) - my_free((gptr) *to,MYF(0)); - if (!(*to= (gptr) my_malloc(length+1,MYF(MY_WME))) || - my_b_read(file,(byte*) *to,length)) - { - if (*to) - my_free(*to,MYF(0)); - *to= 0; - DBUG_RETURN(1); - } - *((char*) *to+length)= '\0'; - DBUG_RETURN (0); -} /* read_string */ - - -static int file_info_compare(void* cmp_arg __attribute__((unused)), - void *a, void *b) -{ - long lint; - - if ((lint=((struct file_info*) a)->process - - ((struct file_info*) b)->process)) - return lint < 0L ? -1 : 1; - return ((struct file_info*) a)->filenr - ((struct file_info*) b)->filenr; -} - - /* ARGSUSED */ - -static int test_if_open (struct file_info *key, - element_count count __attribute__((unused)), - struct test_if_open_param *param) -{ - if (!strcmp(key->name,param->name) && key->id > param->max_id) - param->max_id=key->id; - return 0; -} - - -static void fix_blob_pointers(MI_INFO *info, byte *record) -{ - byte *pos; - MI_BLOB *blob,*end; - - pos=record+info->s->base.reclength; - for (end=info->blobs+info->s->base.blobs, blob= info->blobs; - blob != end ; - blob++) - { - memcpy_fixed(record+blob->offset+blob->pack_length,&pos,sizeof(char*)); - pos+=_mi_calc_blob_length(blob->pack_length,record+blob->offset); - } -} - - /* close the file with hasn't been accessed for the longest time */ - /* ARGSUSED */ - -static int test_when_accessed (struct file_info *key, - element_count count __attribute__((unused)), - struct st_access_param *access_param) -{ - if (key->accessed < access_param->min_accessed && ! key->closed) - { - access_param->min_accessed=key->accessed; - access_param->found=key; - } - return 0; -} - - -static void file_info_free(struct file_info *fileinfo) -{ - DBUG_ENTER("file_info_free"); - if (update) - { - if (!fileinfo->closed) - VOID(mi_close(fileinfo->isam)); - if (fileinfo->record) - my_free(fileinfo->record,MYF(0)); - } - my_free(fileinfo->name,MYF(0)); - my_free(fileinfo->show_name,MYF(0)); - DBUG_VOID_RETURN; -} - - - -static int close_some_file(TREE *tree) -{ - struct st_access_param access_param; - - access_param.min_accessed=LONG_MAX; - access_param.found=0; - - VOID(tree_walk(tree,(tree_walk_action) test_when_accessed, - (void*) &access_param,left_root_right)); - if (!access_param.found) - return 1; /* No open file that is possibly to close */ - if (mi_close(access_param.found->isam)) - return 1; - access_param.found->closed=1; - return 0; -} - - -static int reopen_closed_file(TREE *tree, struct file_info *fileinfo) -{ - char name[FN_REFLEN]; - if (close_some_file(tree)) - return 1; /* No file to close */ - strmov(name,fileinfo->show_name); - if (fileinfo->id > 1) - *strrchr(name,'<')='\0'; /* Remove "<id>" */ - - if (!(fileinfo->isam= mi_open(name,O_RDWR,HA_OPEN_WAIT_IF_LOCKED))) - return 1; - fileinfo->closed=0; - re_open_count++; - return 0; -} - - /* Try to find record with uniq key */ - -static int find_record_with_key(struct file_info *file_info, byte *record) -{ - uint key; - MI_INFO *info=file_info->isam; - uchar tmp_key[MI_MAX_KEY_BUFF]; - - for (key=0 ; key < info->s->base.keys ; key++) - { - if ((((ulonglong) 1 << key) & info->s->state.key_map) && - info->s->keyinfo[key].flag & HA_NOSAME) - { - VOID(_mi_make_key(info,key,tmp_key,record,0L)); - return mi_rkey(info,file_info->record,(int) key,(char*) tmp_key,0, - HA_READ_KEY_EXACT); - } - } - return 1; -} - - -static void printf_log(const char *format,...) -{ - char llbuff[21]; - va_list args; - va_start(args,format); - if (verbose > 2) - printf("%9s:",llstr(isamlog_filepos,llbuff)); - if (verbose > 1) - printf("%5ld ",isamlog_process); /* Write process number */ - (void) vprintf((char*) format,args); - putchar('\n'); - va_end(args); -} - - -static bool cmp_filename(struct file_info *file_info, my_string name) -{ - if (!file_info) - return 1; - return strcmp(file_info->name,name) ? 1 : 0; -} diff --git a/myisam/myisampack.c b/myisam/myisampack.c deleted file mode 100644 index bda620a594a..00000000000 --- a/myisam/myisampack.c +++ /dev/null @@ -1,2180 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Pack MyISAM file */ - -#ifndef USE_MY_FUNC -#define USE_MY_FUNC /* We need at least my_malloc */ -#endif - -#include "myisamdef.h" -#include <queues.h> -#include <my_tree.h> -#include "mysys_err.h" -#ifdef MSDOS -#include <io.h> -#endif -#ifndef __GNU_LIBRARY__ -#define __GNU_LIBRARY__ /* Skip warnings in getopt.h */ -#endif -#include <my_getopt.h> - -#if INT_MAX > 32767 -#define BITS_SAVED 32 -#else -#define BITS_SAVED 16 -#endif - -#define IS_OFFSET ((uint) 32768) /* Bit if offset or char in tree */ -#define HEAD_LENGTH 32 -#define ALLOWED_JOIN_DIFF 256 /* Diff allowed to join trees */ - -#define DATA_TMP_EXT ".TMD" -#define OLD_EXT ".OLD" -#define WRITE_COUNT MY_HOW_OFTEN_TO_WRITE - -struct st_file_buffer { - File file; - char *buffer,*pos,*end; - my_off_t pos_in_file; - int bits; - uint current_byte; -}; - -struct st_huff_tree; -struct st_huff_element; - -typedef struct st_huff_counts { - uint field_length,max_zero_fill; - uint pack_type; - uint max_end_space,max_pre_space,length_bits,min_space; - ulong max_length; - enum en_fieldtype field_type; - struct st_huff_tree *tree; /* Tree for field */ - my_off_t counts[256]; - my_off_t end_space[8]; - my_off_t pre_space[8]; - my_off_t tot_end_space,tot_pre_space,zero_fields,empty_fields,bytes_packed; - TREE int_tree; - byte *tree_buff; - byte *tree_pos; -} HUFF_COUNTS; - -typedef struct st_huff_element HUFF_ELEMENT; - -struct st_huff_element { - my_off_t count; - union un_element { - struct st_nod { - HUFF_ELEMENT *left,*right; - } nod; - struct st_leaf { - HUFF_ELEMENT *null; - uint element_nr; /* Number of element */ - } leaf; - } a; -}; - - -typedef struct st_huff_tree { - HUFF_ELEMENT *root,*element_buffer; - HUFF_COUNTS *counts; - uint tree_number; - uint elements; - my_off_t bytes_packed; - uint tree_pack_length; - uint min_chr,max_chr,char_bits,offset_bits,max_offset,height; - ulong *code; - uchar *code_len; -} HUFF_TREE; - - -typedef struct st_isam_mrg { - MI_INFO **file,**current,**end; - uint free_file; - uint count; - uint min_pack_length; /* Theese is used by packed data */ - uint max_pack_length; - uint ref_length; - uint max_blob_length; - my_off_t records; - /* true if at least one source file has at least one disabled index */ - my_bool src_file_has_indexes_disabled; -} PACK_MRG_INFO; - - -extern int main(int argc,char * *argv); -static void get_options(int *argc,char ***argv); -static MI_INFO *open_isam_file(char *name,int mode); -static bool open_isam_files(PACK_MRG_INFO *mrg,char **names,uint count); -static int compress(PACK_MRG_INFO *file,char *join_name); -static HUFF_COUNTS *init_huff_count(MI_INFO *info,my_off_t records); -static void free_counts_and_tree_and_queue(HUFF_TREE *huff_trees, - uint trees, - HUFF_COUNTS *huff_counts, - uint fields); -static int compare_tree(void* cmp_arg __attribute__((unused)), - const uchar *s,const uchar *t); -static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts); -static void check_counts(HUFF_COUNTS *huff_counts,uint trees, - my_off_t records); -static int test_space_compress(HUFF_COUNTS *huff_counts,my_off_t records, - uint max_space_length,my_off_t *space_counts, - my_off_t tot_space_count, - enum en_fieldtype field_type); -static HUFF_TREE* make_huff_trees(HUFF_COUNTS *huff_counts,uint trees); -static int make_huff_tree(HUFF_TREE *tree,HUFF_COUNTS *huff_counts); -static int compare_huff_elements(void *not_used, byte *a,byte *b); -static int save_counts_in_queue(byte *key,element_count count, - HUFF_TREE *tree); -static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,uint flag); -static uint join_same_trees(HUFF_COUNTS *huff_counts,uint trees); -static int make_huff_decode_table(HUFF_TREE *huff_tree,uint trees); -static void make_traverse_code_tree(HUFF_TREE *huff_tree, - HUFF_ELEMENT *element,uint size, - ulong code); -static int write_header(PACK_MRG_INFO *isam_file, uint header_length,uint trees, - my_off_t tot_elements,my_off_t filelength); -static void write_field_info(HUFF_COUNTS *counts, uint fields,uint trees); -static my_off_t write_huff_tree(HUFF_TREE *huff_tree,uint trees); -static uint *make_offset_code_tree(HUFF_TREE *huff_tree, - HUFF_ELEMENT *element, - uint *offset); -static uint max_bit(uint value); -static int compress_isam_file(PACK_MRG_INFO *file,HUFF_COUNTS *huff_counts); -static char *make_new_name(char *new_name,char *old_name); -static char *make_old_name(char *new_name,char *old_name); -static void init_file_buffer(File file,pbool read_buffer); -static int flush_buffer(ulong neaded_length); -static void end_file_buffer(void); -static void write_bits(ulong value,uint bits); -static void flush_bits(void); -static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length, - ha_checksum crc); -static int save_state_mrg(File file,PACK_MRG_INFO *isam_file,my_off_t new_length, - ha_checksum crc); -static int mrg_close(PACK_MRG_INFO *mrg); -static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf); -static void mrg_reset(PACK_MRG_INFO *mrg); - - -static int error_on_write=0,test_only=0,verbose=0,silent=0, - write_loop=0,force_pack=0, isamchk_neaded=0; -static int tmpfile_createflag=O_RDWR | O_TRUNC | O_EXCL; -static my_bool backup, opt_wait; -static uint tree_buff_length=8196-MALLOC_OVERHEAD; -static char tmp_dir[FN_REFLEN]={0},*join_table; -static my_off_t intervall_length; -static ha_checksum glob_crc; -static struct st_file_buffer file_buffer; -static QUEUE queue; -static HUFF_COUNTS *global_count; -static char zero_string[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -static const char *load_default_groups[]= { "myisampack",0 }; - - /* The main program */ - -int main(int argc, char **argv) -{ - int error,ok; - PACK_MRG_INFO merge; - char **default_argv; - MY_INIT(argv[0]); - - load_defaults("my",load_default_groups,&argc,&argv); - default_argv= argv; - get_options(&argc,&argv); - - error=ok=isamchk_neaded=0; - if (join_table) - { /* Join files into one */ - if (open_isam_files(&merge,argv,(uint) argc) || - compress(&merge,join_table)) - error=1; - } - else while (argc--) - { - MI_INFO *isam_file; - if (!(isam_file=open_isam_file(*argv++,O_RDWR))) - error=1; - else - { - merge.file= &isam_file; - merge.current=0; - merge.free_file=0; - merge.count=1; - if (compress(&merge,0)) - error=1; - else - ok=1; - } - } - if (ok && isamchk_neaded && !silent) - puts("Remember to run myisamchk -rq on compressed tables"); - VOID(fflush(stdout)); VOID(fflush(stderr)); - free_defaults(default_argv); - my_end(verbose ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR); - exit(error ? 2 : 0); -#ifndef _lint - return 0; /* No compiler warning */ -#endif -} - -enum options_mp {OPT_CHARSETS_DIR_MP=256}; - -static struct my_option my_long_options[] = -{ - {"backup", 'b', "Make a backup of the table as table_name.OLD.", - (gptr*) &backup, (gptr*) &backup, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"character-sets-dir", OPT_CHARSETS_DIR_MP, - "Directory where character sets are.", (gptr*) &charsets_dir, - (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", - 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"force", 'f', - "Force packing of table even if it gets bigger or if tempfile exists.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"join", 'j', - "Join all given tables into 'new_table_name'. All tables MUST have identical layouts.", - (gptr*) &join_table, (gptr*) &join_table, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, - 0, 0, 0}, - {"help", '?', "Display this help and exit.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"silent", 's', "Be more silent.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"tmpdir", 'T', "Use temporary directory to store temporary table.", - 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"test", 't', "Don't pack table, only test packing it.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"verbose", 'v', "Write info about progress and packing result.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"version", 'V', "Output version information and exit.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"wait", 'w', "Wait and retry if table is in use.", (gptr*) &opt_wait, - (gptr*) &opt_wait, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} -}; - -#include <help_start.h> - -static void print_version(void) -{ - printf("%s Ver 1.22 for %s on %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); - NETWARE_SET_SCREEN_MODE(1); -} - - -static void usage(void) -{ - print_version(); - puts("Copyright (C) 2002 MySQL AB"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,"); - puts("and you are welcome to modify and redistribute it under the GPL license\n"); - - puts("Pack a MyISAM-table to take much less space."); - puts("Keys are not updated, you must run myisamchk -rq on the datafile"); - puts("afterwards to update the keys."); - puts("You should give the .MYI file as the filename argument."); - - printf("\nUsage: %s [OPTIONS] filename...\n", my_progname); - my_print_help(my_long_options); - print_defaults("my", load_default_groups); - my_print_variables(my_long_options); -} - -#include <help_end.h> - -static my_bool -get_one_option(int optid, const struct my_option *opt __attribute__((unused)), - char *argument) -{ - uint length; - - switch(optid) { - case 'f': - force_pack= 1; - tmpfile_createflag= O_RDWR | O_TRUNC; - break; - case 's': - write_loop= verbose= 0; - silent= 1; - break; - case 't': - test_only= verbose= 1; - break; - case 'T': - length= (uint) (strmov(tmp_dir, argument) - tmp_dir); - if (length != dirname_length(tmp_dir)) - { - tmp_dir[length]=FN_LIBCHAR; - tmp_dir[length+1]=0; - } - break; - case 'v': - verbose= 1; - silent= 0; - break; - case '#': - DBUG_PUSH(argument ? argument : "d:t:o"); - break; - case 'V': - print_version(); - exit(0); - case 'I': - case '?': - usage(); - exit(0); - } - return 0; -} - - /* reads options */ - /* Initiates DEBUG - but no debugging here ! */ - -static void get_options(int *argc,char ***argv) -{ - int ho_error; - - my_progname= argv[0][0]; - if (isatty(fileno(stdout))) - write_loop=1; - - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) - exit(ho_error); - - if (!*argc) - { - usage(); - exit(1); - } - if (join_table) - { - backup=0; /* Not needed */ - tmp_dir[0]=0; - } - return; -} - - -static MI_INFO *open_isam_file(char *name,int mode) -{ - MI_INFO *isam_file; - MYISAM_SHARE *share; - DBUG_ENTER("open_isam_file"); - - if (!(isam_file=mi_open(name,mode, - (opt_wait ? HA_OPEN_WAIT_IF_LOCKED : - HA_OPEN_ABORT_IF_LOCKED)))) - { - VOID(fprintf(stderr,"%s gave error %d on open\n",name,my_errno)); - DBUG_RETURN(0); - } - share=isam_file->s; - if (share->options & HA_OPTION_COMPRESS_RECORD && !join_table) - { - if (!force_pack) - { - VOID(fprintf(stderr,"%s is already compressed\n",name)); - VOID(mi_close(isam_file)); - DBUG_RETURN(0); - } - if (verbose) - puts("Recompressing already compressed table"); - share->options&= ~HA_OPTION_READ_ONLY_DATA; /* We are modifing it */ - } - if (! force_pack && share->state.state.records != 0 && - (share->state.state.records <= 1 || - share->state.state.data_file_length < 1024)) - { - VOID(fprintf(stderr,"%s is too small to compress\n",name)); - VOID(mi_close(isam_file)); - DBUG_RETURN(0); - } - VOID(mi_lock_database(isam_file,F_WRLCK)); - DBUG_RETURN(isam_file); -} - - -static bool open_isam_files(PACK_MRG_INFO *mrg,char **names,uint count) -{ - uint i,j; - mrg->count=0; - mrg->current=0; - mrg->file=(MI_INFO**) my_malloc(sizeof(MI_INFO*)*count,MYF(MY_FAE)); - mrg->free_file=1; - mrg->src_file_has_indexes_disabled= 0; - for (i=0; i < count ; i++) - { - if (!(mrg->file[i]=open_isam_file(names[i],O_RDONLY))) - goto error; - - mrg->src_file_has_indexes_disabled|= ((mrg->file[i]->s->state.key_map != - (((ulonglong) 1) << - mrg->file[i]->s->base. keys) - 1)); - } - /* Check that files are identical */ - for (j=0 ; j < count-1 ; j++) - { - MI_COLUMNDEF *m1,*m2,*end; - if (mrg->file[j]->s->base.reclength != mrg->file[j+1]->s->base.reclength || - mrg->file[j]->s->base.fields != mrg->file[j+1]->s->base.fields) - goto diff_file; - m1=mrg->file[j]->s->rec; - end=m1+mrg->file[j]->s->base.fields; - m2=mrg->file[j+1]->s->rec; - for ( ; m1 != end ; m1++,m2++) - { - if (m1->type != m2->type || m1->length != m2->length) - goto diff_file; - } - } - mrg->count=count; - return 0; - - diff_file: - fprintf(stderr,"%s: Tables '%s' and '%s' are not identical\n", - my_progname,names[j],names[j+1]); - error: - while (i--) - mi_close(mrg->file[i]); - my_free((gptr) mrg->file,MYF(0)); - return 1; -} - - -static int compress(PACK_MRG_INFO *mrg,char *result_table) -{ - int error; - File new_file,join_isam_file; - MI_INFO *isam_file; - MYISAM_SHARE *share; - char org_name[FN_REFLEN],new_name[FN_REFLEN],temp_name[FN_REFLEN]; - uint i,header_length,fields,trees,used_trees; - my_off_t old_length,new_length,tot_elements; - HUFF_COUNTS *huff_counts; - HUFF_TREE *huff_trees; - DBUG_ENTER("compress"); - - isam_file=mrg->file[0]; /* Take this as an example */ - share=isam_file->s; - new_file=join_isam_file= -1; - trees=fields=0; - huff_trees=0; - huff_counts=0; - - /* Create temporary or join file */ - - if (backup) - VOID(fn_format(org_name,isam_file->filename,"",MI_NAME_DEXT,2)); - else - VOID(fn_format(org_name,isam_file->filename,"",MI_NAME_DEXT,2+4+16)); - if (!test_only && result_table) - { - /* Make a new indexfile based on first file in list */ - uint length; - char *buff; - strmov(org_name,result_table); /* Fix error messages */ - VOID(fn_format(new_name,result_table,"",MI_NAME_IEXT,2)); - if ((join_isam_file=my_create(new_name,0,tmpfile_createflag,MYF(MY_WME))) - < 0) - goto err; - length=(uint) share->base.keystart; - if (!(buff=my_malloc(length,MYF(MY_WME)))) - goto err; - if (my_pread(share->kfile,buff,length,0L,MYF(MY_WME | MY_NABP)) || - my_write(join_isam_file,buff,length, - MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL))) - { - my_free(buff,MYF(0)); - goto err; - } - my_free(buff,MYF(0)); - VOID(fn_format(new_name,result_table,"",MI_NAME_DEXT,2)); - } - else if (!tmp_dir[0]) - VOID(make_new_name(new_name,org_name)); - else - VOID(fn_format(new_name,org_name,tmp_dir,DATA_TMP_EXT,1+2+4)); - if (!test_only && - (new_file=my_create(new_name,0,tmpfile_createflag,MYF(MY_WME))) < 0) - goto err; - - /* Start calculating statistics */ - - mrg->records=0; - for (i=0 ; i < mrg->count ; i++) - mrg->records+=mrg->file[i]->s->state.state.records; - if (write_loop || verbose) - { - printf("Compressing %s: (%lu records)\n", - result_table ? new_name : org_name,(ulong) mrg->records); - } - trees=fields=share->base.fields; - huff_counts=init_huff_count(isam_file,mrg->records); - QUICK_SAFEMALLOC; - if (write_loop || verbose) - printf("- Calculating statistics\n"); - if (get_statistic(mrg,huff_counts)) - goto err; - NORMAL_SAFEMALLOC; - old_length=0; - for (i=0; i < mrg->count ; i++) - old_length+= (mrg->file[i]->s->state.state.data_file_length - - mrg->file[i]->s->state.state.empty); - - if (init_queue(&queue,256,0,0,compare_huff_elements,0)) - goto err; - check_counts(huff_counts,fields,mrg->records); - huff_trees=make_huff_trees(huff_counts,trees); - if ((int) (used_trees=join_same_trees(huff_counts,trees)) < 0) - goto err; - if (make_huff_decode_table(huff_trees,fields)) - goto err; - - init_file_buffer(new_file,0); - file_buffer.pos_in_file=HEAD_LENGTH; - if (! test_only) - VOID(my_seek(new_file,file_buffer.pos_in_file,MY_SEEK_SET,MYF(0))); - - write_field_info(huff_counts,fields,used_trees); - if (!(tot_elements=write_huff_tree(huff_trees,trees))) - goto err; - header_length=(uint) file_buffer.pos_in_file+ - (uint) (file_buffer.pos-file_buffer.buffer); - - /* Compress file */ - if (write_loop || verbose) - printf("- Compressing file\n"); - error=compress_isam_file(mrg,huff_counts); - new_length=file_buffer.pos_in_file; - if (!error && !test_only) - { - char buff[MEMMAP_EXTRA_MARGIN]; /* End marginal for memmap */ - bzero(buff,sizeof(buff)); - error=my_write(file_buffer.file,buff,sizeof(buff), - MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)) != 0; - } - if (!error) - error=write_header(mrg,header_length,used_trees,tot_elements, - new_length); - end_file_buffer(); - - if (verbose && mrg->records) - printf("Min record length: %6d Max length: %6d Mean total length: %6ld\n", - mrg->min_pack_length,mrg->max_pack_length, - (ulong) (new_length/mrg->records)); - - if (!test_only) - { - error|=my_close(new_file,MYF(MY_WME)); - if (!result_table) - { - error|=my_close(isam_file->dfile,MYF(MY_WME)); - isam_file->dfile= -1; /* Tell mi_close file is closed */ - } - } - - free_counts_and_tree_and_queue(huff_trees,trees,huff_counts,fields); - if (! test_only && ! error) - { - if (result_table) - { - error=save_state_mrg(join_isam_file,mrg,new_length,glob_crc); - } - else - { - if (backup) - { - if (my_rename(org_name,make_old_name(temp_name,isam_file->filename), - MYF(MY_WME))) - error=1; - else - { - if (tmp_dir[0]) - error=my_copy(new_name,org_name,MYF(MY_WME)); - else - error=my_rename(new_name,org_name,MYF(MY_WME)); - if (!error) - VOID(my_copystat(temp_name,org_name,MYF(MY_COPYTIME))); - } - } - else - { - if (tmp_dir[0]) - error=my_copy(new_name,org_name, - MYF(MY_WME | MY_HOLD_ORIGINAL_MODES | MY_COPYTIME)); - else - error=my_redel(org_name,new_name,MYF(MY_WME | MY_COPYTIME)); - } - if (! error) - error=save_state(isam_file,mrg,new_length,glob_crc); - } - } - error|=mrg_close(mrg); - if (join_isam_file >= 0) - error|=my_close(join_isam_file,MYF(MY_WME)); - if (error) - { - VOID(fprintf(stderr,"Aborting: %s is not compressed\n",org_name)); - VOID(my_delete(new_name,MYF(MY_WME))); - DBUG_RETURN(-1); - } - if (write_loop || verbose) - { - if (old_length) - printf("%.4g%% \n", (((longlong) (old_length -new_length))*100.0/ - (longlong) old_length)); - else - puts("Empty file saved in compressed format"); - } - DBUG_RETURN(0); - - err: - free_counts_and_tree_and_queue(huff_trees,trees,huff_counts,fields); - if (new_file >= 0) - VOID(my_close(new_file,MYF(0))); - if (join_isam_file >= 0) - VOID(my_close(join_isam_file,MYF(0))); - mrg_close(mrg); - VOID(fprintf(stderr,"Aborted: %s is not compressed\n",org_name)); - DBUG_RETURN(-1); -} - - /* Init a huff_count-struct for each field and init it */ - -static HUFF_COUNTS *init_huff_count(MI_INFO *info,my_off_t records) -{ - reg2 uint i; - reg1 HUFF_COUNTS *count; - if ((count = (HUFF_COUNTS*) my_malloc(info->s->base.fields* - sizeof(HUFF_COUNTS), - MYF(MY_ZEROFILL | MY_WME)))) - { - for (i=0 ; i < info->s->base.fields ; i++) - { - enum en_fieldtype type; - count[i].field_length=info->s->rec[i].length; - type= count[i].field_type= (enum en_fieldtype) info->s->rec[i].type; - if (type == FIELD_INTERVALL || - type == FIELD_CONSTANT || - type == FIELD_ZERO) - type = FIELD_NORMAL; - if (count[i].field_length <= 8 && - (type == FIELD_NORMAL || - type == FIELD_SKIP_ZERO)) - count[i].max_zero_fill= count[i].field_length; - init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0, NULL, - NULL); - if (records && type != FIELD_BLOB && type != FIELD_VARCHAR) - count[i].tree_pos=count[i].tree_buff = - my_malloc(count[i].field_length > 1 ? tree_buff_length : 2, - MYF(MY_WME)); - } - } - return count; -} - - - /* Free memory used by counts and trees */ - -static void free_counts_and_tree_and_queue(HUFF_TREE *huff_trees, uint trees, - HUFF_COUNTS *huff_counts, - uint fields) -{ - register uint i; - - if (huff_trees) - { - for (i=0 ; i < trees ; i++) - { - if (huff_trees[i].element_buffer) - my_free((gptr) huff_trees[i].element_buffer,MYF(0)); - if (huff_trees[i].code) - my_free((gptr) huff_trees[i].code,MYF(0)); - } - my_free((gptr) huff_trees,MYF(0)); - } - if (huff_counts) - { - for (i=0 ; i < fields ; i++) - { - if (huff_counts[i].tree_buff) - { - my_free((gptr) huff_counts[i].tree_buff,MYF(0)); - delete_tree(&huff_counts[i].int_tree); - } - } - my_free((gptr) huff_counts,MYF(0)); - } - delete_queue(&queue); /* This is safe to free */ - return; -} - - /* Read through old file and gather some statistics */ - -static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts) -{ - int error; - uint length; - ulong reclength,max_blob_length; - byte *record,*pos,*next_pos,*end_pos,*start_pos; - ha_rows record_count; - my_bool static_row_size; - HUFF_COUNTS *count,*end_count; - TREE_ELEMENT *element; - DBUG_ENTER("get_statistic"); - - reclength=mrg->file[0]->s->base.reclength; - record=(byte*) my_alloca(reclength); - end_count=huff_counts+mrg->file[0]->s->base.fields; - record_count=0; glob_crc=0; - max_blob_length=0; - - /* Check how to calculate checksum */ - static_row_size=1; - for (count=huff_counts ; count < end_count ; count++) - { - if (count->field_type == FIELD_BLOB || - count->field_type == FIELD_VARCHAR) - { - static_row_size=0; - break; - } - } - - mrg_reset(mrg); - while ((error=mrg_rrnd(mrg,record)) != HA_ERR_END_OF_FILE) - { - ulong tot_blob_length=0; - if (! error) - { - if (static_row_size) - glob_crc+=mi_static_checksum(mrg->file[0],record); - else - glob_crc+=mi_checksum(mrg->file[0],record); - for (pos=record,count=huff_counts ; - count < end_count ; - count++, - pos=next_pos) - { - next_pos=end_pos=(start_pos=pos)+count->field_length; - - /* Put value in tree if there is room for it */ - if (count->tree_buff) - { - global_count=count; - if (!(element=tree_insert(&count->int_tree,pos, 0, - count->int_tree.custom_arg)) || - (element->count == 1 && - count->tree_buff + tree_buff_length < - count->tree_pos + count->field_length) || - (count->field_length == 1 && - count->int_tree.elements_in_tree > 1)) - { - delete_tree(&count->int_tree); - my_free(count->tree_buff,MYF(0)); - count->tree_buff=0; - } - else - { - if (element->count == 1) - { /* New element */ - memcpy(count->tree_pos,pos,(size_t) count->field_length); - tree_set_pointer(element,count->tree_pos); - count->tree_pos+=count->field_length; - } - } - } - - /* Save character counters and space-counts and zero-field-counts */ - if (count->field_type == FIELD_NORMAL || - count->field_type == FIELD_SKIP_ENDSPACE) - { - for ( ; end_pos > pos ; end_pos--) - if (end_pos[-1] != ' ') - break; - if (end_pos == pos) - { - count->empty_fields++; - count->max_zero_fill=0; - continue; - } - length= (uint) (next_pos-end_pos); - count->tot_end_space+=length; - if (length < 8) - count->end_space[length]++; - if (count->max_end_space < length) - count->max_end_space = length; - } - if (count->field_type == FIELD_NORMAL || - count->field_type == FIELD_SKIP_PRESPACE) - { - for (pos=start_pos; pos < end_pos ; pos++) - if (pos[0] != ' ') - break; - if (end_pos == pos) - { - count->empty_fields++; - count->max_zero_fill=0; - continue; - } - length= (uint) (pos-start_pos); - count->tot_pre_space+=length; - if (length < 8) - count->pre_space[length]++; - if (count->max_pre_space < length) - count->max_pre_space = length; - } - if (count->field_type == FIELD_BLOB) - { - uint field_length=count->field_length -mi_portable_sizeof_char_ptr; - ulong blob_length= _mi_calc_blob_length(field_length, start_pos); - memcpy_fixed((char*) &pos, start_pos+field_length,sizeof(char*)); - end_pos=pos+blob_length; - tot_blob_length+=blob_length; - set_if_bigger(count->max_length,blob_length); - } - else if (count->field_type == FIELD_VARCHAR) - { - uint pack_length= HA_VARCHAR_PACKLENGTH(count->field_length-1); - length= (pack_length == 1 ? (uint) *(uchar*) start_pos : - uint2korr(start_pos)); - pos= start_pos+pack_length; - end_pos= pos+length; - set_if_bigger(count->max_length,length); - } - if (count->field_length <= 8 && - (count->field_type == FIELD_NORMAL || - count->field_type == FIELD_SKIP_ZERO)) - { - uint i; - if (!memcmp((byte*) start_pos,zero_string,count->field_length)) - { - count->zero_fields++; - continue; - } - for (i =0 ; i < count->max_zero_fill && ! end_pos[-1 - (int) i] ; - i++) ; - if (i < count->max_zero_fill) - count->max_zero_fill=i; - } - if (count->field_type == FIELD_ZERO || - count->field_type == FIELD_CHECK) - continue; - for ( ; pos < end_pos ; pos++) - count->counts[(uchar) *pos]++; - } - if (tot_blob_length > max_blob_length) - max_blob_length=tot_blob_length; - record_count++; - if (write_loop && record_count % WRITE_COUNT == 0) - { - printf("%lu\r",(ulong) record_count); VOID(fflush(stdout)); - } - } - else if (error != HA_ERR_RECORD_DELETED) - { - fprintf(stderr,"Got error %d while reading rows",error); - break; - } - } - if (write_loop) - { - printf(" \r"); VOID(fflush(stdout)); - } - mrg->records=record_count; - mrg->max_blob_length=max_blob_length; - my_afree((gptr) record); - DBUG_RETURN(error != HA_ERR_END_OF_FILE); -} - -static int compare_huff_elements(void *not_used __attribute__((unused)), - byte *a, byte *b) -{ - return *((my_off_t*) a) < *((my_off_t*) b) ? -1 : - (*((my_off_t*) a) == *((my_off_t*) b) ? 0 : 1); -} - - /* Check each tree if we should use pre-space-compress, end-space- - compress, empty-field-compress or zero-field-compress */ - -static void check_counts(HUFF_COUNTS *huff_counts, uint trees, - my_off_t records) -{ - uint space_fields,fill_zero_fields,field_count[(int) FIELD_VARCHAR+1]; - my_off_t old_length,new_length,length; - DBUG_ENTER("check_counts"); - - bzero((gptr) field_count,sizeof(field_count)); - space_fields=fill_zero_fields=0; - - for (; trees-- ; huff_counts++) - { - if (huff_counts->field_type == FIELD_BLOB) - { - huff_counts->length_bits=max_bit(huff_counts->max_length); - goto found_pack; - } - else if (huff_counts->field_type == FIELD_VARCHAR) - { - huff_counts->length_bits=max_bit(huff_counts->max_length); - goto found_pack; - } - else if (huff_counts->field_type == FIELD_CHECK) - { - huff_counts->bytes_packed=0; - huff_counts->counts[0]=0; - goto found_pack; - } - - huff_counts->field_type=FIELD_NORMAL; - huff_counts->pack_type=0; - - if (huff_counts->zero_fields || ! records) - { - my_off_t old_space_count; - if (huff_counts->zero_fields == records) - { - huff_counts->field_type= FIELD_ZERO; - huff_counts->bytes_packed=0; - huff_counts->counts[0]=0; - goto found_pack; - } - old_space_count=huff_counts->counts[' ']; - huff_counts->counts[' ']+=huff_counts->tot_end_space+ - huff_counts->tot_pre_space + - huff_counts->empty_fields * huff_counts->field_length; - old_length=calc_packed_length(huff_counts,0)+records/8; - length=huff_counts->zero_fields*huff_counts->field_length; - huff_counts->counts[0]+=length; - new_length=calc_packed_length(huff_counts,0); - if (old_length < new_length && huff_counts->field_length > 1) - { - huff_counts->field_type=FIELD_SKIP_ZERO; - huff_counts->counts[0]-=length; - huff_counts->bytes_packed=old_length- records/8; - goto found_pack; - } - huff_counts->counts[' ']=old_space_count; - } - huff_counts->bytes_packed=calc_packed_length(huff_counts,0); - if (huff_counts->empty_fields) - { - if (huff_counts->field_length > 2 && - huff_counts->empty_fields + (records - huff_counts->empty_fields)* - (1+max_bit(max(huff_counts->max_pre_space, - huff_counts->max_end_space))) < - records * max_bit(huff_counts->field_length)) - { - huff_counts->pack_type |= PACK_TYPE_SPACE_FIELDS; - } - else - { - length=huff_counts->empty_fields*huff_counts->field_length; - if (huff_counts->tot_end_space || ! huff_counts->tot_pre_space) - { - huff_counts->tot_end_space+=length; - huff_counts->max_end_space=huff_counts->field_length; - if (huff_counts->field_length < 8) - huff_counts->end_space[huff_counts->field_length]+= - huff_counts->empty_fields; - } - if (huff_counts->tot_pre_space) - { - huff_counts->tot_pre_space+=length; - huff_counts->max_pre_space=huff_counts->field_length; - if (huff_counts->field_length < 8) - huff_counts->pre_space[huff_counts->field_length]+= - huff_counts->empty_fields; - } - } - } - if (huff_counts->tot_end_space) - { - huff_counts->counts[' ']+=huff_counts->tot_pre_space; - if (test_space_compress(huff_counts,records,huff_counts->max_end_space, - huff_counts->end_space, - huff_counts->tot_end_space,FIELD_SKIP_ENDSPACE)) - goto found_pack; - huff_counts->counts[' ']-=huff_counts->tot_pre_space; - } - if (huff_counts->tot_pre_space) - { - if (test_space_compress(huff_counts,records,huff_counts->max_pre_space, - huff_counts->pre_space, - huff_counts->tot_pre_space,FIELD_SKIP_PRESPACE)) - goto found_pack; - } - - found_pack: /* Found field-packing */ - - /* Test if we can use zero-fill */ - - if (huff_counts->max_zero_fill && - (huff_counts->field_type == FIELD_NORMAL || - huff_counts->field_type == FIELD_SKIP_ZERO)) - { - huff_counts->counts[0]-=huff_counts->max_zero_fill* - (huff_counts->field_type == FIELD_SKIP_ZERO ? - records - huff_counts->zero_fields : records); - huff_counts->pack_type|=PACK_TYPE_ZERO_FILL; - huff_counts->bytes_packed=calc_packed_length(huff_counts,0); - } - - /* Test if intervall-field is better */ - - if (huff_counts->tree_buff) - { - HUFF_TREE tree; - - tree.element_buffer=0; - if (!make_huff_tree(&tree,huff_counts) && - tree.bytes_packed+tree.tree_pack_length < huff_counts->bytes_packed) - { - if (tree.elements == 1) - huff_counts->field_type=FIELD_CONSTANT; - else - huff_counts->field_type=FIELD_INTERVALL; - huff_counts->pack_type=0; - } - else - { - my_free((gptr) huff_counts->tree_buff,MYF(0)); - delete_tree(&huff_counts->int_tree); - huff_counts->tree_buff=0; - } - if (tree.element_buffer) - my_free((gptr) tree.element_buffer,MYF(0)); - } - if (huff_counts->pack_type & PACK_TYPE_SPACE_FIELDS) - space_fields++; - if (huff_counts->pack_type & PACK_TYPE_ZERO_FILL) - fill_zero_fields++; - field_count[huff_counts->field_type]++; - } - if (verbose) - printf("\nnormal: %3d empty-space: %3d empty-zero: %3d empty-fill: %3d\npre-space: %3d end-space: %3d intervall-fields: %3d zero: %3d\n", - field_count[FIELD_NORMAL],space_fields, - field_count[FIELD_SKIP_ZERO],fill_zero_fields, - field_count[FIELD_SKIP_PRESPACE], - field_count[FIELD_SKIP_ENDSPACE], - field_count[FIELD_INTERVALL], - field_count[FIELD_ZERO]); - DBUG_VOID_RETURN; -} - - /* Test if we can use space-compression and empty-field-compression */ - -static int -test_space_compress(HUFF_COUNTS *huff_counts, my_off_t records, - uint max_space_length, my_off_t *space_counts, - my_off_t tot_space_count, enum en_fieldtype field_type) -{ - int min_pos; - uint length_bits,i; - my_off_t space_count,min_space_count,min_pack,new_length,skip; - - length_bits=max_bit(max_space_length); - - /* Default no end_space-packing */ - space_count=huff_counts->counts[(uint) ' ']; - min_space_count= (huff_counts->counts[(uint) ' ']+= tot_space_count); - min_pack=calc_packed_length(huff_counts,0); - min_pos= -2; - huff_counts->counts[(uint) ' ']=space_count; - - /* Test with allways space-count */ - new_length=huff_counts->bytes_packed+length_bits*records/8; - if (new_length+1 < min_pack) - { - min_pos= -1; - min_pack=new_length; - min_space_count=space_count; - } - /* Test with length-flag */ - for (skip=0L, i=0 ; i < 8 ; i++) - { - if (space_counts[i]) - { - if (i) - huff_counts->counts[(uint) ' ']+=space_counts[i]; - skip+=huff_counts->pre_space[i]; - new_length=calc_packed_length(huff_counts,0)+ - (records+(records-skip)*(1+length_bits))/8; - if (new_length < min_pack) - { - min_pos=(int) i; - min_pack=new_length; - min_space_count=huff_counts->counts[(uint) ' ']; - } - } - } - - huff_counts->counts[(uint) ' ']=min_space_count; - huff_counts->bytes_packed=min_pack; - switch (min_pos) { - case -2: - return(0); /* No space-compress */ - case -1: /* Always space-count */ - huff_counts->field_type=field_type; - huff_counts->min_space=0; - huff_counts->length_bits=max_bit(max_space_length); - break; - default: - huff_counts->field_type=field_type; - huff_counts->min_space=(uint) min_pos; - huff_counts->pack_type|=PACK_TYPE_SELECTED; - huff_counts->length_bits=max_bit(max_space_length); - break; - } - return(1); /* Using space-compress */ -} - - - /* Make a huff_tree of each huff_count */ - -static HUFF_TREE* make_huff_trees(HUFF_COUNTS *huff_counts, uint trees) -{ - uint tree; - HUFF_TREE *huff_tree; - DBUG_ENTER("make_huff_trees"); - - if (!(huff_tree=(HUFF_TREE*) my_malloc(trees*sizeof(HUFF_TREE), - MYF(MY_WME | MY_ZEROFILL)))) - DBUG_RETURN(0); - - for (tree=0 ; tree < trees ; tree++) - { - if (make_huff_tree(huff_tree+tree,huff_counts+tree)) - { - while (tree--) - my_free((gptr) huff_tree[tree].element_buffer,MYF(0)); - my_free((gptr) huff_tree,MYF(0)); - DBUG_RETURN(0); - } - } - DBUG_RETURN(huff_tree); -} - - /* Update huff_tree according to huff_counts->counts or - huff_counts->tree_buff */ - -static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts) -{ - uint i,found,bits_packed,first,last; - my_off_t bytes_packed; - HUFF_ELEMENT *a,*b,*new_huff_el; - - first=last=0; - if (huff_counts->tree_buff) - { - found= (uint) (huff_counts->tree_pos - huff_counts->tree_buff) / - huff_counts->field_length; - first=0; last=found-1; - } - else - { - for (i=found=0 ; i < 256 ; i++) - { - if (huff_counts->counts[i]) - { - if (! found++) - first=i; - last=i; - } - } - if (found < 2) - found=2; - } - - if (queue.max_elements < found) - { - delete_queue(&queue); - if (init_queue(&queue,found,0,0,compare_huff_elements,0)) - return -1; - } - - if (!huff_tree->element_buffer) - { - if (!(huff_tree->element_buffer= - (HUFF_ELEMENT*) my_malloc(found*2*sizeof(HUFF_ELEMENT),MYF(MY_WME)))) - return 1; - } - else - { - HUFF_ELEMENT *temp; - if (!(temp= - (HUFF_ELEMENT*) my_realloc((gptr) huff_tree->element_buffer, - found*2*sizeof(HUFF_ELEMENT), - MYF(MY_WME)))) - return 1; - huff_tree->element_buffer=temp; - } - - huff_counts->tree=huff_tree; - huff_tree->counts=huff_counts; - huff_tree->min_chr=first; - huff_tree->max_chr=last; - huff_tree->char_bits=max_bit(last-first); - huff_tree->offset_bits=max_bit(found-1)+1; - - if (huff_counts->tree_buff) - { - huff_tree->elements=0; - tree_walk(&huff_counts->int_tree, - (int (*)(void*, element_count,void*)) save_counts_in_queue, - (gptr) huff_tree, left_root_right); - huff_tree->tree_pack_length=(1+15+16+5+5+ - (huff_tree->char_bits+1)*found+ - (huff_tree->offset_bits+1)* - (found-2)+7)/8 + - (uint) (huff_tree->counts->tree_pos- - huff_tree->counts->tree_buff); - } - else - { - huff_tree->elements=found; - huff_tree->tree_pack_length=(9+9+5+5+ - (huff_tree->char_bits+1)*found+ - (huff_tree->offset_bits+1)* - (found-2)+7)/8; - - for (i=first, found=0 ; i <= last ; i++) - { - if (huff_counts->counts[i]) - { - new_huff_el=huff_tree->element_buffer+(found++); - new_huff_el->count=huff_counts->counts[i]; - new_huff_el->a.leaf.null=0; - new_huff_el->a.leaf.element_nr=i; - queue.root[found]=(byte*) new_huff_el; - } - } - while (found < 2) - { /* Our huff_trees request at least 2 elements */ - new_huff_el=huff_tree->element_buffer+(found++); - new_huff_el->count=0; - new_huff_el->a.leaf.null=0; - if (last) - new_huff_el->a.leaf.element_nr=huff_tree->min_chr=last-1; - else - new_huff_el->a.leaf.element_nr=huff_tree->max_chr=last+1; - queue.root[found]=(byte*) new_huff_el; - } - } - queue.elements=found; - - for (i=found/2 ; i > 0 ; i--) - _downheap(&queue,i); - bytes_packed=0; bits_packed=0; - for (i=1 ; i < found ; i++) - { - a=(HUFF_ELEMENT*) queue_remove(&queue,0); - b=(HUFF_ELEMENT*) queue.root[1]; - new_huff_el=huff_tree->element_buffer+found+i; - new_huff_el->count=a->count+b->count; - bits_packed+=(uint) (new_huff_el->count & 7); - bytes_packed+=new_huff_el->count/8; - new_huff_el->a.nod.left=a; /* lesser in left */ - new_huff_el->a.nod.right=b; - queue.root[1]=(byte*) new_huff_el; - queue_replaced(&queue); - } - huff_tree->root=(HUFF_ELEMENT*) queue.root[1]; - huff_tree->bytes_packed=bytes_packed+(bits_packed+7)/8; - return 0; -} - -static int compare_tree(void* cmp_arg __attribute__((unused)), - register const uchar *s, register const uchar *t) -{ - uint length; - for (length=global_count->field_length; length-- ;) - if (*s++ != *t++) - return (int) s[-1] - (int) t[-1]; - return 0; -} - - /* Used by make_huff_tree to save intervall-counts in queue */ - -static int save_counts_in_queue(byte *key, element_count count, - HUFF_TREE *tree) -{ - HUFF_ELEMENT *new_huff_el; - - new_huff_el=tree->element_buffer+(tree->elements++); - new_huff_el->count=count; - new_huff_el->a.leaf.null=0; - new_huff_el->a.leaf.element_nr= (uint) (key- tree->counts->tree_buff) / - tree->counts->field_length; - queue.root[tree->elements]=(byte*) new_huff_el; - return 0; -} - - - /* Calculate length of file if given counts should be used */ - /* Its actually a faster version of make_huff_tree */ - -static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts, - uint add_tree_lenght) -{ - uint i,found,bits_packed,first,last; - my_off_t bytes_packed; - HUFF_ELEMENT element_buffer[256]; - DBUG_ENTER("calc_packed_length"); - - first=last=0; - for (i=found=0 ; i < 256 ; i++) - { - if (huff_counts->counts[i]) - { - if (! found++) - first=i; - last=i; - queue.root[found]=(byte*) &huff_counts->counts[i]; - } - } - if (!found) - DBUG_RETURN(0); /* Empty tree */ - if (found < 2) - queue.root[++found]=(byte*) &huff_counts->counts[last ? 0 : 1]; - - queue.elements=found; - - bytes_packed=0; bits_packed=0; - if (add_tree_lenght) - bytes_packed=(8+9+5+5+(max_bit(last-first)+1)*found+ - (max_bit(found-1)+1+1)*(found-2) +7)/8; - for (i=(found+1)/2 ; i > 0 ; i--) - _downheap(&queue,i); - for (i=0 ; i < found-1 ; i++) - { - HUFF_ELEMENT *a,*b,*new_huff_el; - a=(HUFF_ELEMENT*) queue_remove(&queue,0); - b=(HUFF_ELEMENT*) queue.root[1]; - new_huff_el=element_buffer+i; - new_huff_el->count=a->count+b->count; - bits_packed+=(uint) (new_huff_el->count & 7); - bytes_packed+=new_huff_el->count/8; - queue.root[1]=(byte*) new_huff_el; - queue_replaced(&queue); - } - DBUG_RETURN(bytes_packed+(bits_packed+7)/8); -} - - - /* Remove trees that don't give any compression */ - -static uint join_same_trees(HUFF_COUNTS *huff_counts, uint trees) -{ - uint k,tree_number; - HUFF_COUNTS count,*i,*j,*last_count; - - last_count=huff_counts+trees; - for (tree_number=0, i=huff_counts ; i < last_count ; i++) - { - if (!i->tree->tree_number) - { - i->tree->tree_number= ++tree_number; - if (i->tree_buff) - continue; /* Don't join intervall */ - for (j=i+1 ; j < last_count ; j++) - { - if (! j->tree->tree_number && ! j->tree_buff) - { - for (k=0 ; k < 256 ; k++) - count.counts[k]=i->counts[k]+j->counts[k]; - if (calc_packed_length(&count,1) <= - i->tree->bytes_packed + j->tree->bytes_packed+ - i->tree->tree_pack_length+j->tree->tree_pack_length+ - ALLOWED_JOIN_DIFF) - { - memcpy_fixed((byte*) i->counts,(byte*) count.counts, - sizeof(count.counts[0])*256); - my_free((gptr) j->tree->element_buffer,MYF(0)); - j->tree->element_buffer=0; - j->tree=i->tree; - bmove((byte*) i->counts,(byte*) count.counts, - sizeof(count.counts[0])*256); - if (make_huff_tree(i->tree,i)) - return (uint) -1; - } - } - } - } - } - if (verbose) - printf("Original trees: %d After join: %d\n",trees,tree_number); - return tree_number; /* Return trees left */ -} - - - /* Fill in huff_tree decode tables */ - -static int make_huff_decode_table(HUFF_TREE *huff_tree, uint trees) -{ - uint elements; - for ( ; trees-- ; huff_tree++) - { - if (huff_tree->tree_number > 0) - { - elements=huff_tree->counts->tree_buff ? huff_tree->elements : 256; - if (!(huff_tree->code = - (ulong*) my_malloc(elements* - (sizeof(ulong)+sizeof(uchar)), - MYF(MY_WME | MY_ZEROFILL)))) - return 1; - huff_tree->code_len=(uchar*) (huff_tree->code+elements); - make_traverse_code_tree(huff_tree,huff_tree->root,32,0); - } - } - return 0; -} - - -static void make_traverse_code_tree(HUFF_TREE *huff_tree, - HUFF_ELEMENT *element, - uint size, ulong code) -{ - uint chr; - if (!element->a.leaf.null) - { - chr=element->a.leaf.element_nr; - huff_tree->code_len[chr]=(uchar) (32-size); - huff_tree->code[chr]= (code >> size); - if (huff_tree->height < 32-size) - huff_tree->height= 32-size; - } - else - { - size--; - make_traverse_code_tree(huff_tree,element->a.nod.left,size,code); - make_traverse_code_tree(huff_tree,element->a.nod.right,size, - code+((ulong) 1L << size)); - } - return; -} - - - /* Write header to new packed data file */ - -static int write_header(PACK_MRG_INFO *mrg,uint head_length,uint trees, - my_off_t tot_elements,my_off_t filelength) -{ - byte *buff=file_buffer.pos; - - bzero(buff,HEAD_LENGTH); - memcpy_fixed(buff,myisam_pack_file_magic,4); - int4store(buff+4,head_length); - int4store(buff+8, mrg->min_pack_length); - int4store(buff+12,mrg->max_pack_length); - int4store(buff+16,tot_elements); - int4store(buff+20,intervall_length); - int2store(buff+24,trees); - buff[26]=(char) mrg->ref_length; - /* Save record pointer length */ - buff[27]= (uchar) mi_get_pointer_length((ulonglong) filelength,2); - if (test_only) - return 0; - VOID(my_seek(file_buffer.file,0L,MY_SEEK_SET,MYF(0))); - return my_write(file_buffer.file,file_buffer.pos,HEAD_LENGTH, - MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)) != 0; -} - - /* Write fieldinfo to new packed file */ - -static void write_field_info(HUFF_COUNTS *counts, uint fields, uint trees) -{ - reg1 uint i; - uint huff_tree_bits; - huff_tree_bits=max_bit(trees ? trees-1 : 0); - - for (i=0 ; i++ < fields ; counts++) - { - write_bits((ulong) (int) counts->field_type,5); - write_bits(counts->pack_type,6); - if (counts->pack_type & PACK_TYPE_ZERO_FILL) - write_bits(counts->max_zero_fill,5); - else - write_bits(counts->length_bits,5); - write_bits((ulong) counts->tree->tree_number-1,huff_tree_bits); - } - flush_bits(); - return; -} - - /* Write all huff_trees to new datafile. Return tot count of - elements in all trees - Returns 0 on error */ - -static my_off_t write_huff_tree(HUFF_TREE *huff_tree, uint trees) -{ - uint i,int_length; - uint *packed_tree,*offset,length; - my_off_t elements; - - for (i=length=0 ; i < trees ; i++) - if (huff_tree[i].tree_number > 0 && huff_tree[i].elements > length) - length=huff_tree[i].elements; - if (!(packed_tree=(uint*) my_alloca(sizeof(uint)*length*2))) - { - my_error(EE_OUTOFMEMORY,MYF(ME_BELL),sizeof(uint)*length*2); - return 0; - } - - intervall_length=0; - for (elements=0; trees-- ; huff_tree++) - { - if (huff_tree->tree_number == 0) - continue; /* Deleted tree */ - elements+=huff_tree->elements; - huff_tree->max_offset=2; - if (huff_tree->elements <= 1) - offset=packed_tree; - else - offset=make_offset_code_tree(huff_tree,huff_tree->root,packed_tree); - huff_tree->offset_bits=max_bit(huff_tree->max_offset); - if (huff_tree->max_offset >= IS_OFFSET) - { /* This should be impossible */ - VOID(fprintf(stderr,"Tree offset got too big: %d, aborted\n", - huff_tree->max_offset)); - my_afree((gptr) packed_tree); - return 0; - } - -#ifdef EXTRA_DBUG - printf("pos: %d elements: %d tree-elements: %d char_bits: %d\n", - (uint) (file_buffer.pos-file_buffer.buffer), - huff_tree->elements, (offset-packed_tree),huff_tree->char_bits); -#endif - if (!huff_tree->counts->tree_buff) - { - write_bits(0,1); - write_bits(huff_tree->min_chr,8); - write_bits(huff_tree->elements,9); - write_bits(huff_tree->char_bits,5); - write_bits(huff_tree->offset_bits,5); - int_length=0; - } - else - { - int_length=(uint) (huff_tree->counts->tree_pos - - huff_tree->counts->tree_buff); - write_bits(1,1); - write_bits(huff_tree->elements,15); - write_bits(int_length,16); - write_bits(huff_tree->char_bits,5); - write_bits(huff_tree->offset_bits,5); - intervall_length+=int_length; - } - length=(uint) (offset-packed_tree); - if (length != huff_tree->elements*2-2) - printf("error: Huff-tree-length: %d != calc_length: %d\n", - length,huff_tree->elements*2-2); - - for (i=0 ; i < length ; i++) - { - if (packed_tree[i] & IS_OFFSET) - write_bits(packed_tree[i] - IS_OFFSET+ (1 << huff_tree->offset_bits), - huff_tree->offset_bits+1); - else - write_bits(packed_tree[i]-huff_tree->min_chr,huff_tree->char_bits+1); - } - flush_bits(); - if (huff_tree->counts->tree_buff) - { - for (i=0 ; i < int_length ; i++) - write_bits((uint) (uchar) huff_tree->counts->tree_buff[i],8); - } - flush_bits(); - } - my_afree((gptr) packed_tree); - return elements; -} - - -static uint *make_offset_code_tree(HUFF_TREE *huff_tree, HUFF_ELEMENT *element, - uint *offset) -{ - uint *prev_offset; - - prev_offset= offset; - if (!element->a.nod.left->a.leaf.null) - { - offset[0] =(uint) element->a.nod.left->a.leaf.element_nr; - offset+=2; - } - else - { - prev_offset[0]= IS_OFFSET+2; - offset=make_offset_code_tree(huff_tree,element->a.nod.left,offset+2); - } - if (!element->a.nod.right->a.leaf.null) - { - prev_offset[1]=element->a.nod.right->a.leaf.element_nr; - return offset; - } - else - { - uint temp=(uint) (offset-prev_offset-1); - prev_offset[1]= IS_OFFSET+ temp; - if (huff_tree->max_offset < temp) - huff_tree->max_offset = temp; - return make_offset_code_tree(huff_tree,element->a.nod.right,offset); - } -} - - /* Get number of bits neaded to represent value */ - -static uint max_bit(register uint value) -{ - reg2 uint power=1; - - while ((value>>=1)) - power++; - return (power); -} - - -static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) -{ - int error; - uint i,max_calc_length,pack_ref_length,min_record_length,max_record_length, - intervall,field_length,max_pack_length,pack_blob_length; - my_off_t record_count; - ulong length,pack_length; - byte *record,*pos,*end_pos,*record_pos,*start_pos; - HUFF_COUNTS *count,*end_count; - HUFF_TREE *tree; - MI_INFO *isam_file=mrg->file[0]; - DBUG_ENTER("compress_isam_file"); - - if (!(record=(byte*) my_alloca(isam_file->s->base.reclength))) - return -1; - end_count=huff_counts+isam_file->s->base.fields; - min_record_length= (uint) ~0; - max_record_length=0; - - for (i=max_calc_length=0 ; i < isam_file->s->base.fields ; i++) - { - if (!(huff_counts[i].pack_type & PACK_TYPE_ZERO_FILL)) - huff_counts[i].max_zero_fill=0; - if (huff_counts[i].field_type == FIELD_CONSTANT || - huff_counts[i].field_type == FIELD_ZERO || - huff_counts[i].field_type == FIELD_CHECK) - continue; - if (huff_counts[i].field_type == FIELD_INTERVALL) - max_calc_length+=huff_counts[i].tree->height; - else if (huff_counts[i].field_type == FIELD_BLOB || - huff_counts[i].field_type == FIELD_VARCHAR) - max_calc_length+=huff_counts[i].tree->height*huff_counts[i].max_length + huff_counts[i].length_bits +1; - else - max_calc_length+= - (huff_counts[i].field_length - huff_counts[i].max_zero_fill)* - huff_counts[i].tree->height+huff_counts[i].length_bits; - } - max_calc_length/=8; - if (max_calc_length < 254) - pack_ref_length=1; - else if (max_calc_length <= 65535) - pack_ref_length=3; - else - pack_ref_length=4; - record_count=0; - pack_blob_length=0; - if (isam_file->s->base.blobs) - { - if (mrg->max_blob_length < 254) - pack_blob_length=1; - else if (mrg->max_blob_length <= 65535) - pack_blob_length=3; - else - pack_blob_length=4; - } - max_pack_length=pack_ref_length+pack_blob_length; - - mrg_reset(mrg); - while ((error=mrg_rrnd(mrg,record)) != HA_ERR_END_OF_FILE) - { - ulong tot_blob_length=0; - if (! error) - { - if (flush_buffer(max_calc_length+max_pack_length)) - break; - record_pos=file_buffer.pos; - file_buffer.pos+=max_pack_length; - for (start_pos=record, count= huff_counts; count < end_count ; count++) - { - end_pos=start_pos+(field_length=count->field_length); - tree=count->tree; - - if (count->pack_type & PACK_TYPE_SPACE_FIELDS) - { - for (pos=start_pos ; *pos == ' ' && pos < end_pos; pos++) ; - if (pos == end_pos) - { - write_bits(1,1); - start_pos=end_pos; - continue; - } - write_bits(0,1); - } - end_pos-=count->max_zero_fill; - field_length-=count->max_zero_fill; - - switch(count->field_type) { - case FIELD_SKIP_ZERO: - if (!memcmp((byte*) start_pos,zero_string,field_length)) - { - write_bits(1,1); - start_pos=end_pos; - break; - } - write_bits(0,1); - /* Fall through */ - case FIELD_NORMAL: - for ( ; start_pos < end_pos ; start_pos++) - write_bits(tree->code[(uchar) *start_pos], - (uint) tree->code_len[(uchar) *start_pos]); - break; - case FIELD_SKIP_ENDSPACE: - for (pos=end_pos ; pos > start_pos && pos[-1] == ' ' ; pos--) ; - length=(uint) (end_pos-pos); - if (count->pack_type & PACK_TYPE_SELECTED) - { - if (length > count->min_space) - { - write_bits(1,1); - write_bits(length,count->length_bits); - } - else - { - write_bits(0,1); - pos=end_pos; - } - } - else - write_bits(length,count->length_bits); - for ( ; start_pos < pos ; start_pos++) - write_bits(tree->code[(uchar) *start_pos], - (uint) tree->code_len[(uchar) *start_pos]); - start_pos=end_pos; - break; - case FIELD_SKIP_PRESPACE: - for (pos=start_pos ; pos < end_pos && pos[0] == ' ' ; pos++) ; - length=(uint) (pos-start_pos); - if (count->pack_type & PACK_TYPE_SELECTED) - { - if (length > count->min_space) - { - write_bits(1,1); - write_bits(length,count->length_bits); - } - else - { - pos=start_pos; - write_bits(0,1); - } - } - else - write_bits(length,count->length_bits); - for (start_pos=pos ; start_pos < end_pos ; start_pos++) - write_bits(tree->code[(uchar) *start_pos], - (uint) tree->code_len[(uchar) *start_pos]); - break; - case FIELD_CONSTANT: - case FIELD_ZERO: - case FIELD_CHECK: - start_pos=end_pos; - break; - case FIELD_INTERVALL: - global_count=count; - pos=(byte*) tree_search(&count->int_tree, start_pos, - count->int_tree.custom_arg); - intervall=(uint) (pos - count->tree_buff)/field_length; - write_bits(tree->code[intervall],(uint) tree->code_len[intervall]); - start_pos=end_pos; - break; - case FIELD_BLOB: - { - ulong blob_length=_mi_calc_blob_length(field_length- - mi_portable_sizeof_char_ptr, - start_pos); - if (!blob_length) - { - write_bits(1,1); /* Empty blob */ - } - else - { - byte *blob,*blob_end; - write_bits(0,1); - write_bits(blob_length,count->length_bits); - memcpy_fixed(&blob,end_pos-mi_portable_sizeof_char_ptr, - sizeof(char*)); - blob_end=blob+blob_length; - for ( ; blob < blob_end ; blob++) - write_bits(tree->code[(uchar) *blob], - (uint) tree->code_len[(uchar) *blob]); - tot_blob_length+=blob_length; - } - start_pos= end_pos; - break; - } - case FIELD_VARCHAR: - { - uint pack_length= HA_VARCHAR_PACKLENGTH(count->field_length-1); - ulong col_length= (pack_length == 1 ? (uint) *(uchar*) start_pos : - uint2korr(start_pos)); - if (!col_length) - { - write_bits(1,1); /* Empty varchar */ - } - else - { - byte *end=start_pos+pack_length+col_length; - write_bits(0,1); - write_bits(col_length,count->length_bits); - for (start_pos+=pack_length ; start_pos < end ; start_pos++) - write_bits(tree->code[(uchar) *start_pos], - (uint) tree->code_len[(uchar) *start_pos]); - } - start_pos= end_pos; - break; - } - case FIELD_LAST: - abort(); /* Impossible */ - } - start_pos+=count->max_zero_fill; - } - flush_bits(); - length=(ulong) (file_buffer.pos-record_pos)-max_pack_length; - pack_length=save_pack_length(record_pos,length); - if (pack_blob_length) - pack_length+=save_pack_length(record_pos+pack_length,tot_blob_length); - - /* Correct file buffer if the header was smaller */ - if (pack_length != max_pack_length) - { - bmove(record_pos+pack_length,record_pos+max_pack_length,length); - file_buffer.pos-= (max_pack_length-pack_length); - } - if (length < (ulong) min_record_length) - min_record_length=(uint) length; - if (length > (ulong) max_record_length) - max_record_length=(uint) length; - if (write_loop && ++record_count % WRITE_COUNT == 0) - { - printf("%lu\r",(ulong) record_count); VOID(fflush(stdout)); - } - } - else if (error != HA_ERR_RECORD_DELETED) - break; - } - if (error == HA_ERR_END_OF_FILE) - error=0; - else - { - fprintf(stderr,"%s: Got error %d reading records\n",my_progname,error); - } - - my_afree((gptr) record); - mrg->ref_length=max_pack_length; - mrg->min_pack_length=max_record_length ? min_record_length : 0; - mrg->max_pack_length=max_record_length; - DBUG_RETURN(error || error_on_write || flush_buffer(~(ulong) 0)); -} - - -static char *make_new_name(char *new_name, char *old_name) -{ - return fn_format(new_name,old_name,"",DATA_TMP_EXT,2+4); -} - -static char *make_old_name(char *new_name, char *old_name) -{ - return fn_format(new_name,old_name,"",OLD_EXT,2+4); -} - - /* rutines for bit writing buffer */ - -static void init_file_buffer(File file, pbool read_buffer) -{ - file_buffer.file=file; - file_buffer.buffer=my_malloc(ALIGN_SIZE(RECORD_CACHE_SIZE),MYF(MY_WME)); - file_buffer.end=file_buffer.buffer+ALIGN_SIZE(RECORD_CACHE_SIZE)-8; - file_buffer.pos_in_file=0; - error_on_write=0; - if (read_buffer) - { - - file_buffer.pos=file_buffer.end; - file_buffer.bits=0; - } - else - { - file_buffer.pos=file_buffer.buffer; - file_buffer.bits=BITS_SAVED; - } - file_buffer.current_byte=0; -} - - -static int flush_buffer(ulong neaded_length) -{ - ulong length; - if ((ulong) (file_buffer.end - file_buffer.pos) > neaded_length) - return 0; - length=(ulong) (file_buffer.pos-file_buffer.buffer); - file_buffer.pos=file_buffer.buffer; - file_buffer.pos_in_file+=length; - if (test_only) - return 0; - if (error_on_write|| my_write(file_buffer.file,file_buffer.buffer, - length, - MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL))) - { - error_on_write=1; - return 1; - } - - if (neaded_length != ~(ulong) 0 && - (ulong) (file_buffer.end-file_buffer.buffer) < neaded_length) - { - char *tmp; - neaded_length+=256; /* some margin */ - tmp=my_realloc(file_buffer.buffer, neaded_length,MYF(MY_WME)); - if (!tmp) - return 1; - file_buffer.pos= tmp + (ulong) (file_buffer.pos - file_buffer.buffer); - file_buffer.buffer=tmp; - file_buffer.end=tmp+neaded_length-8; - } - return 0; -} - - -static void end_file_buffer(void) -{ - my_free((gptr) file_buffer.buffer,MYF(0)); -} - - /* output `bits` low bits of `value' */ - -static void write_bits (register ulong value, register uint bits) -{ - if ((file_buffer.bits-=(int) bits) >= 0) - { - file_buffer.current_byte|=value << file_buffer.bits; - } - else - { - reg3 uint byte_buff; - bits= (uint) -file_buffer.bits; - byte_buff=file_buffer.current_byte | (uint) (value >> bits); -#if BITS_SAVED == 32 - *file_buffer.pos++= (byte) (byte_buff >> 24) ; - *file_buffer.pos++= (byte) (byte_buff >> 16) ; -#endif - *file_buffer.pos++= (byte) (byte_buff >> 8) ; - *file_buffer.pos++= (byte) byte_buff; - - value&=(1 << bits)-1; -#if BITS_SAVED == 16 - if (bits >= sizeof(uint)) - { - bits-=8; - *file_buffer.pos++= (uchar) (value >> bits); - value&= (1 << bits)-1; - if (bits >= sizeof(uint)) - { - bits-=8; - *file_buffer.pos++= (uchar) (value >> bits); - value&= (1 << bits)-1; - } - } -#endif - if (file_buffer.pos >= file_buffer.end) - VOID(flush_buffer((uint) ~0)); - file_buffer.bits=(int) (BITS_SAVED - bits); - file_buffer.current_byte=(uint) (value << (BITS_SAVED - bits)); - } - return; -} - - /* Flush bits in bit_buffer to buffer */ - -static void flush_bits (void) -{ - uint bits,byte_buff; - - bits=(file_buffer.bits) & ~7; - byte_buff = file_buffer.current_byte >> bits; - bits=BITS_SAVED - bits; - while (bits > 0) - { - bits-=8; - *file_buffer.pos++= (byte) (uchar) (byte_buff >> bits) ; - } - file_buffer.bits=BITS_SAVED; - file_buffer.current_byte=0; - return; -} - - -/**************************************************************************** -** functions to handle the joined files -****************************************************************************/ - -static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length, - ha_checksum crc) -{ - MYISAM_SHARE *share=isam_file->s; - uint options=mi_uint2korr(share->state.header.options); - uint key; - DBUG_ENTER("save_state"); - - options|= HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA; - mi_int2store(share->state.header.options,options); - - share->state.state.data_file_length=new_length; - share->state.state.del=0; - share->state.state.empty=0; - share->state.dellink= HA_OFFSET_ERROR; - share->state.split=(ha_rows) mrg->records; - share->state.version=(ulong) time((time_t*) 0); - if (share->state.key_map != (ULL(1) << share->base.keys) - 1) - { - /* - Some indexes are disabled, cannot use current key_file_length value - as an estimate of upper bound of index file size. Use packed data file - size instead. - */ - share->state.state.key_file_length= new_length; - } - /* - If there are no disabled indexes, keep key_file_length value from - original file so "myisamchk -rq" can use this value (this is necessary - because index size cannot be easily calculated for fulltext keys) - */ - share->state.key_map=0; - for (key=0 ; key < share->base.keys ; key++) - share->state.key_root[key]= HA_OFFSET_ERROR; - for (key=0 ; key < share->state.header.max_block_size ; key++) - share->state.key_del[key]= HA_OFFSET_ERROR; - share->state.checksum=crc; /* Save crc here */ - share->changed=1; /* Force write of header */ - share->state.open_count=0; - share->global_changed=0; - VOID(my_chsize(share->kfile, share->base.keystart, 0, MYF(0))); - if (share->base.keys) - isamchk_neaded=1; - DBUG_RETURN(mi_state_info_write(share->kfile,&share->state,1+2)); -} - - -static int save_state_mrg(File file,PACK_MRG_INFO *mrg,my_off_t new_length, - ha_checksum crc) -{ - MI_STATE_INFO state; - MI_INFO *isam_file=mrg->file[0]; - uint options; - DBUG_ENTER("save_state_mrg"); - - state= isam_file->s->state; - options= (mi_uint2korr(state.header.options) | HA_OPTION_COMPRESS_RECORD | - HA_OPTION_READ_ONLY_DATA); - mi_int2store(state.header.options,options); - state.state.data_file_length=new_length; - state.state.del=0; - state.state.empty=0; - state.state.records=state.split=(ha_rows) mrg->records; - /* See comment above in save_state about key_file_length handling. */ - if (mrg->src_file_has_indexes_disabled) - { - isam_file->s->state.state.key_file_length= - max(isam_file->s->state.state.key_file_length, new_length); - } - state.dellink= HA_OFFSET_ERROR; - state.version=(ulong) time((time_t*) 0); - state.key_map=0; - state.checksum=crc; - if (isam_file->s->base.keys) - isamchk_neaded=1; - state.changed=STATE_CHANGED | STATE_NOT_ANALYZED; /* Force check of table */ - DBUG_RETURN (mi_state_info_write(file,&state,1+2)); -} - - -/* reset for mrg_rrnd */ - -static void mrg_reset(PACK_MRG_INFO *mrg) -{ - if (mrg->current) - { - mi_extra(*mrg->current, HA_EXTRA_NO_CACHE, 0); - mrg->current=0; - } -} - -static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf) -{ - int error; - MI_INFO *isam_info; - my_off_t filepos; - - if (!info->current) - { - isam_info= *(info->current=info->file); - info->end=info->current+info->count; - mi_extra(isam_info, HA_EXTRA_RESET, 0); - mi_extra(isam_info, HA_EXTRA_CACHE, 0); - filepos=isam_info->s->pack.header_length; - } - else - { - isam_info= *info->current; - filepos= isam_info->nextpos; - } - - for (;;) - { - isam_info->update&= HA_STATE_CHANGED; - if (!(error=(*isam_info->s->read_rnd)(isam_info,(byte*) buf, - filepos, 1)) || - error != HA_ERR_END_OF_FILE) - return (error); - mi_extra(isam_info,HA_EXTRA_NO_CACHE, 0); - if (info->current+1 == info->end) - return(HA_ERR_END_OF_FILE); - info->current++; - isam_info= *info->current; - filepos=isam_info->s->pack.header_length; - mi_extra(isam_info,HA_EXTRA_RESET, 0); - mi_extra(isam_info,HA_EXTRA_CACHE, 0); - } -} - - -static int mrg_close(PACK_MRG_INFO *mrg) -{ - uint i; - int error=0; - for (i=0 ; i < mrg->count ; i++) - error|=mi_close(mrg->file[i]); - if (mrg->free_file) - my_free((gptr) mrg->file,MYF(0)); - return error; -} diff --git a/myisam/rt_index.c b/myisam/rt_index.c deleted file mode 100644 index 97554dca4e6..00000000000 --- a/myisam/rt_index.c +++ /dev/null @@ -1,1082 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin & MySQL Finland AB - & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "myisamdef.h" - -#ifdef HAVE_RTREE_KEYS - -#include "rt_index.h" -#include "rt_key.h" -#include "rt_mbr.h" - -#define REINSERT_BUFFER_INC 10 -#define PICK_BY_AREA -/*#define PICK_BY_PERIMETER*/ - -typedef struct st_page_level -{ - uint level; - my_off_t offs; -} stPageLevel; - -typedef struct st_page_list -{ - ulong n_pages; - ulong m_pages; - stPageLevel *pages; -} stPageList; - - -/* - Find next key in r-tree according to search_flag recursively - - NOTES - Used in rtree_find_first() and rtree_find_next() - - RETURN - -1 Error - 0 Found - 1 Not found -*/ - -static int rtree_find_req(MI_INFO *info, MI_KEYDEF *keyinfo, uint search_flag, - uint nod_cmp_flag, my_off_t page, int level) -{ - uchar *k; - uchar *last; - uint nod_flag; - int res; - uchar *page_buf; - int k_len; - uint *saved_key = (uint*) (info->rtree_recursion_state) + level; - - if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length))) - { - my_errno = HA_ERR_OUT_OF_MEM; - return -1; - } - if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0)) - goto err1; - nod_flag = mi_test_if_nod(page_buf); - - k_len = keyinfo->keylength - info->s->base.rec_reflength; - - if(info->rtree_recursion_depth >= level) - { - k = page_buf + *saved_key; - } - else - { - k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); - } - last = rt_PAGE_END(page_buf); - - for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag)) - { - if (nod_flag) - { - /* this is an internal node in the tree */ - if (!(res = rtree_key_cmp(keyinfo->seg, info->first_mbr_key, k, - info->last_rkey_length, nod_cmp_flag))) - { - switch ((res = rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, - _mi_kpos(nod_flag, k), level + 1))) - { - case 0: /* found - exit from recursion */ - *saved_key = k - page_buf; - goto ok; - case 1: /* not found - continue searching */ - info->rtree_recursion_depth = level; - break; - default: /* error */ - case -1: - goto err1; - } - } - } - else - { - /* this is a leaf */ - if (!rtree_key_cmp(keyinfo->seg, info->first_mbr_key, k, - info->last_rkey_length, search_flag)) - { - uchar *after_key = rt_PAGE_NEXT_KEY(k, k_len, nod_flag); - info->lastpos = _mi_dpos(info, 0, after_key); - info->lastkey_length = k_len + info->s->base.rec_reflength; - memcpy(info->lastkey, k, info->lastkey_length); - info->rtree_recursion_depth = level; - *saved_key = last - page_buf; - - if (after_key < last) - { - info->int_keypos = info->buff; - info->int_maxpos = info->buff + (last - after_key); - memcpy(info->buff, after_key, last - after_key); - info->buff_used = 0; - } - else - { - info->buff_used = 1; - } - - res = 0; - goto ok; - } - } - } - info->lastpos = HA_OFFSET_ERROR; - my_errno = HA_ERR_KEY_NOT_FOUND; - res = 1; - -ok: - my_afree((byte*)page_buf); - return res; - -err1: - my_afree((byte*)page_buf); - info->lastpos = HA_OFFSET_ERROR; - return -1; -} - - -/* - Find first key in r-tree according to search_flag condition - - SYNOPSIS - rtree_find_first() - info Handler to MyISAM file - uint keynr Key number to use - key Key to search for - key_length Length of 'key' - search_flag Bitmap of flags how to do the search - - RETURN - -1 Error - 0 Found - 1 Not found -*/ - -int rtree_find_first(MI_INFO *info, uint keynr, uchar *key, uint key_length, - uint search_flag) -{ - my_off_t root; - uint nod_cmp_flag; - MI_KEYDEF *keyinfo = info->s->keyinfo + keynr; - - if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) - { - my_errno= HA_ERR_END_OF_FILE; - return -1; - } - - /* Save searched key */ - memcpy(info->first_mbr_key, key, keyinfo->keylength - - info->s->base.rec_reflength); - info->last_rkey_length = key_length; - - info->rtree_recursion_depth = -1; - info->buff_used = 1; - - nod_cmp_flag = ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ? - MBR_WITHIN : MBR_INTERSECT); - return rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root, 0); -} - - -/* - Find next key in r-tree according to search_flag condition - - SYNOPSIS - rtree_find_next() - info Handler to MyISAM file - uint keynr Key number to use - search_flag Bitmap of flags how to do the search - - RETURN - -1 Error - 0 Found - 1 Not found -*/ - -int rtree_find_next(MI_INFO *info, uint keynr, uint search_flag) -{ - my_off_t root; - uint nod_cmp_flag; - MI_KEYDEF *keyinfo = info->s->keyinfo + keynr; - - if (info->update & HA_STATE_DELETED) - return rtree_find_first(info, keynr, info->lastkey, info->lastkey_length, - search_flag); - - if (!info->buff_used) - { - uchar *key= info->int_keypos; - - while (key < info->int_maxpos) - { - if (!rtree_key_cmp(keyinfo->seg, info->first_mbr_key, key, - info->last_rkey_length, search_flag)) - { - uchar *after_key = key + keyinfo->keylength; - - info->lastpos= _mi_dpos(info, 0, after_key); - memcpy(info->lastkey, key, info->lastkey_length); - - if (after_key < info->int_maxpos) - info->int_keypos= after_key; - else - info->buff_used= 1; - return 0; - } - key+= keyinfo->keylength; - } - } - if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) - { - my_errno= HA_ERR_END_OF_FILE; - return -1; - } - - nod_cmp_flag = ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ? - MBR_WITHIN : MBR_INTERSECT); - return rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root, 0); -} - - -/* - Get next key in r-tree recursively - - NOTES - Used in rtree_get_first() and rtree_get_next() - - RETURN - -1 Error - 0 Found - 1 Not found -*/ - -static int rtree_get_req(MI_INFO *info, MI_KEYDEF *keyinfo, uint key_length, - my_off_t page, int level) -{ - uchar *k; - uchar *last; - uint nod_flag; - int res; - uchar *page_buf; - uint k_len; - uint *saved_key = (uint*) (info->rtree_recursion_state) + level; - - if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length))) - return -1; - if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0)) - goto err1; - nod_flag = mi_test_if_nod(page_buf); - - k_len = keyinfo->keylength - info->s->base.rec_reflength; - - if(info->rtree_recursion_depth >= level) - { - k = page_buf + *saved_key; - if (!nod_flag) - { - /* Only leaf pages contain data references. */ - /* Need to check next key with data reference. */ - k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag); - } - } - else - { - k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); - } - last = rt_PAGE_END(page_buf); - - for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag)) - { - if (nod_flag) - { - /* this is an internal node in the tree */ - switch ((res = rtree_get_req(info, keyinfo, key_length, - _mi_kpos(nod_flag, k), level + 1))) - { - case 0: /* found - exit from recursion */ - *saved_key = k - page_buf; - goto ok; - case 1: /* not found - continue searching */ - info->rtree_recursion_depth = level; - break; - default: - case -1: /* error */ - goto err1; - } - } - else - { - /* this is a leaf */ - uchar *after_key = rt_PAGE_NEXT_KEY(k, k_len, nod_flag); - info->lastpos = _mi_dpos(info, 0, after_key); - info->lastkey_length = k_len + info->s->base.rec_reflength; - memcpy(info->lastkey, k, info->lastkey_length); - - info->rtree_recursion_depth = level; - *saved_key = k - page_buf; - - if (after_key < last) - { - info->int_keypos = (uchar*)saved_key; - memcpy(info->buff, page_buf, keyinfo->block_length); - info->int_maxpos = rt_PAGE_END(info->buff); - info->buff_used = 0; - } - else - { - info->buff_used = 1; - } - - res = 0; - goto ok; - } - } - info->lastpos = HA_OFFSET_ERROR; - my_errno = HA_ERR_KEY_NOT_FOUND; - res = 1; - -ok: - my_afree((byte*)page_buf); - return res; - -err1: - my_afree((byte*)page_buf); - info->lastpos = HA_OFFSET_ERROR; - return -1; -} - - -/* - Get first key in r-tree - - RETURN - -1 Error - 0 Found - 1 Not found -*/ - -int rtree_get_first(MI_INFO *info, uint keynr, uint key_length) -{ - my_off_t root; - MI_KEYDEF *keyinfo = info->s->keyinfo + keynr; - - if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) - { - my_errno= HA_ERR_END_OF_FILE; - return -1; - } - - info->rtree_recursion_depth = -1; - info->buff_used = 1; - - return rtree_get_req(info, &keyinfo[keynr], key_length, root, 0); -} - - -/* - Get next key in r-tree - - RETURN - -1 Error - 0 Found - 1 Not found -*/ - -int rtree_get_next(MI_INFO *info, uint keynr, uint key_length) -{ - my_off_t root; - MI_KEYDEF *keyinfo = info->s->keyinfo + keynr; - - if (!info->buff_used) - { - uint k_len = keyinfo->keylength - info->s->base.rec_reflength; - /* rt_PAGE_NEXT_KEY(info->int_keypos) */ - uchar *key = info->buff + *(int*)info->int_keypos + k_len + - info->s->base.rec_reflength; - /* rt_PAGE_NEXT_KEY(key) */ - uchar *after_key = key + k_len + info->s->base.rec_reflength; - - info->lastpos = _mi_dpos(info, 0, after_key); - info->lastkey_length = k_len + info->s->base.rec_reflength; - memcpy(info->lastkey, key, k_len + info->s->base.rec_reflength); - - *(int*)info->int_keypos = key - info->buff; - if (after_key >= info->int_maxpos) - { - info->buff_used = 1; - } - - return 0; - } - else - { - if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) - { - my_errno= HA_ERR_END_OF_FILE; - return -1; - } - - return rtree_get_req(info, &keyinfo[keynr], key_length, root, 0); - } -} - - -/* - Choose non-leaf better key for insertion -*/ - -#ifdef PICK_BY_PERIMETER -static uchar *rtree_pick_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, - uint key_length, uchar *page_buf, uint nod_flag) -{ - double increase; - double best_incr = DBL_MAX; - double perimeter; - double best_perimeter; - uchar *best_key; - uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); - uchar *last = rt_PAGE_END(page_buf); - - LINT_INIT(best_perimeter); - LINT_INIT(best_key); - - for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag)) - { - if ((increase = rtree_perimeter_increase(keyinfo->seg, k, key, key_length, - &perimeter)) == -1) - return NULL; - if ((increase < best_incr)|| - (increase == best_incr && perimeter < best_perimeter)) - { - best_key = k; - best_perimeter= perimeter; - best_incr = increase; - } - } - return best_key; -} - -#endif /*PICK_BY_PERIMETER*/ - -#ifdef PICK_BY_AREA -static uchar *rtree_pick_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, - uint key_length, uchar *page_buf, uint nod_flag) -{ - double increase; - double best_incr = DBL_MAX; - double area; - double best_area; - uchar *best_key; - uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); - uchar *last = rt_PAGE_END(page_buf); - - LINT_INIT(best_area); - LINT_INIT(best_key); - - for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag)) - { - /* The following is safe as -1.0 is an exact number */ - if ((increase = rtree_area_increase(keyinfo->seg, k, key, key_length, - &area)) == -1.0) - return NULL; - /* The following should be safe, even if we compare doubles */ - if (increase < best_incr) - { - best_key = k; - best_area = area; - best_incr = increase; - } - else - { - /* The following should be safe, even if we compare doubles */ - if ((increase == best_incr) && (area < best_area)) - { - best_key = k; - best_area = area; - best_incr = increase; - } - } - } - return best_key; -} - -#endif /*PICK_BY_AREA*/ - -/* - Go down and insert key into tree - - RETURN - -1 Error - 0 Child was not split - 1 Child was split -*/ - -static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, - uint key_length, my_off_t page, my_off_t *new_page, - int ins_level, int level) -{ - uchar *k; - uint nod_flag; - uchar *page_buf; - int res; - - if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length + - MI_MAX_KEY_BUFF))) - { - my_errno = HA_ERR_OUT_OF_MEM; - return -1; - } - if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0)) - goto err1; - nod_flag = mi_test_if_nod(page_buf); - - if ((ins_level == -1 && nod_flag) || /* key: go down to leaf */ - (ins_level > -1 && ins_level > level)) /* branch: go down to ins_level */ - { - if ((k = rtree_pick_key(info, keyinfo, key, key_length, page_buf, - nod_flag)) == NULL) - goto err1; - switch ((res = rtree_insert_req(info, keyinfo, key, key_length, - _mi_kpos(nod_flag, k), new_page, ins_level, level + 1))) - { - case 0: /* child was not split */ - { - rtree_combine_rect(keyinfo->seg, k, key, k, key_length); - if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf)) - goto err1; - goto ok; - } - case 1: /* child was split */ - { - uchar *new_key = page_buf + keyinfo->block_length + nod_flag; - /* set proper MBR for key */ - if (rtree_set_key_mbr(info, keyinfo, k, key_length, - _mi_kpos(nod_flag, k))) - goto err1; - /* add new key for new page */ - _mi_kpointer(info, new_key - nod_flag, *new_page); - if (rtree_set_key_mbr(info, keyinfo, new_key, key_length, *new_page)) - goto err1; - res = rtree_add_key(info, keyinfo, new_key, key_length, - page_buf, new_page); - if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf)) - goto err1; - goto ok; - } - default: - case -1: /* error */ - { - goto err1; - } - } - } - else - { - res = rtree_add_key(info, keyinfo, key, key_length, page_buf, new_page); - if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf)) - goto err1; - goto ok; - } - -ok: - my_afree((byte*)page_buf); - return res; - -err1: - my_afree((byte*)page_buf); - return -1; -} - - -/* - Insert key into the tree - - RETURN - -1 Error - 0 Root was not split - 1 Root was split -*/ - -static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, - uint key_length, int ins_level) -{ - my_off_t old_root; - MI_KEYDEF *keyinfo = info->s->keyinfo + keynr; - int res; - my_off_t new_page; - - if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) - { - int res; - - if ((old_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) == HA_OFFSET_ERROR) - return -1; - info->buff_used = 1; - mi_putint(info->buff, 2, 0); - res = rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL); - if (_mi_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff)) - return 1; - info->s->state.key_root[keynr] = old_root; - return res; - } - - switch ((res = rtree_insert_req(info, keyinfo, key, key_length, - old_root, &new_page, ins_level, 0))) - { - case 0: /* root was not split */ - { - break; - } - case 1: /* root was split, grow a new root */ - { - uchar *new_root_buf; - my_off_t new_root; - uchar *new_key; - uint nod_flag = info->s->base.key_reflength; - - if (!(new_root_buf = (uchar*)my_alloca((uint)keyinfo->block_length + - MI_MAX_KEY_BUFF))) - { - my_errno = HA_ERR_OUT_OF_MEM; - return -1; - } - - mi_putint(new_root_buf, 2, nod_flag); - if ((new_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) == - HA_OFFSET_ERROR) - goto err1; - - new_key = new_root_buf + keyinfo->block_length + nod_flag; - - _mi_kpointer(info, new_key - nod_flag, old_root); - if (rtree_set_key_mbr(info, keyinfo, new_key, key_length, old_root)) - goto err1; - if (rtree_add_key(info, keyinfo, new_key, key_length, new_root_buf, NULL) - == -1) - goto err1; - _mi_kpointer(info, new_key - nod_flag, new_page); - if (rtree_set_key_mbr(info, keyinfo, new_key, key_length, new_page)) - goto err1; - if (rtree_add_key(info, keyinfo, new_key, key_length, new_root_buf, NULL) - == -1) - goto err1; - if (_mi_write_keypage(info, keyinfo, new_root, - DFLT_INIT_HITS, new_root_buf)) - goto err1; - info->s->state.key_root[keynr] = new_root; - - my_afree((byte*)new_root_buf); - break; -err1: - my_afree((byte*)new_root_buf); - return -1; - } - default: - case -1: /* error */ - { - break; - } - } - return res; -} - - -/* - Insert key into the tree - interface function - - RETURN - -1 Error - 0 OK -*/ - -int rtree_insert(MI_INFO *info, uint keynr, uchar *key, uint key_length) -{ - return (!key_length || - (rtree_insert_level(info, keynr, key, key_length, -1) == -1)) ? -1 : 0; -} - - -/* - Fill reinsert page buffer - - RETURN - -1 Error - 0 OK -*/ - -static int rtree_fill_reinsert_list(stPageList *ReinsertList, my_off_t page, - int level) -{ - if (ReinsertList->n_pages == ReinsertList->m_pages) - { - ReinsertList->m_pages += REINSERT_BUFFER_INC; - if (!(ReinsertList->pages = (stPageLevel*)my_realloc((gptr)ReinsertList->pages, - ReinsertList->m_pages * sizeof(stPageLevel), MYF(MY_ALLOW_ZERO_PTR)))) - goto err1; - } - /* save page to ReinsertList */ - ReinsertList->pages[ReinsertList->n_pages].offs = page; - ReinsertList->pages[ReinsertList->n_pages].level = level; - ReinsertList->n_pages++; - return 0; - -err1: - return -1; -} - - -/* - Go down and delete key from the tree - - RETURN - -1 Error - 0 Deleted - 1 Not found - 2 Empty leaf -*/ - -static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, - uint key_length, my_off_t page, uint *page_size, - stPageList *ReinsertList, int level) -{ - uchar *k; - uchar *last; - ulong i; - uint nod_flag; - uchar *page_buf; - int res; - - if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length))) - { - my_errno = HA_ERR_OUT_OF_MEM; - return -1; - } - if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0)) - goto err1; - nod_flag = mi_test_if_nod(page_buf); - - k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); - last = rt_PAGE_END(page_buf); - - for (i = 0; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag), ++i) - { - if (nod_flag) - { - /* not leaf */ - if (!rtree_key_cmp(keyinfo->seg, key, k, key_length, MBR_WITHIN)) - { - switch ((res = rtree_delete_req(info, keyinfo, key, key_length, - _mi_kpos(nod_flag, k), page_size, ReinsertList, level + 1))) - { - case 0: /* deleted */ - { - /* test page filling */ - if (*page_size + key_length >= rt_PAGE_MIN_SIZE(keyinfo->block_length)) - { - /* OK */ - if (rtree_set_key_mbr(info, keyinfo, k, key_length, - _mi_kpos(nod_flag, k))) - goto err1; - if (_mi_write_keypage(info, keyinfo, page, - DFLT_INIT_HITS, page_buf)) - goto err1; - } - else - { - /* too small: delete key & add it descendant to reinsert list */ - if (rtree_fill_reinsert_list(ReinsertList, _mi_kpos(nod_flag, k), - level + 1)) - goto err1; - rtree_delete_key(info, page_buf, k, key_length, nod_flag); - if (_mi_write_keypage(info, keyinfo, page, - DFLT_INIT_HITS, page_buf)) - goto err1; - *page_size = mi_getint(page_buf); - } - - goto ok; - } - case 1: /* not found - continue searching */ - { - break; - } - case 2: /* vacuous case: last key in the leaf */ - { - rtree_delete_key(info, page_buf, k, key_length, nod_flag); - if (_mi_write_keypage(info, keyinfo, page, - DFLT_INIT_HITS, page_buf)) - goto err1; - *page_size = mi_getint(page_buf); - res = 0; - goto ok; - } - default: /* error */ - case -1: - { - goto err1; - } - } - } - } - else - { - /* leaf */ - if (!rtree_key_cmp(keyinfo->seg, key, k, key_length, MBR_EQUAL | MBR_DATA)) - { - rtree_delete_key(info, page_buf, k, key_length, nod_flag); - *page_size = mi_getint(page_buf); - if (*page_size == 2) - { - /* last key in the leaf */ - res = 2; - if (_mi_dispose(info, keyinfo, page, DFLT_INIT_HITS)) - goto err1; - } - else - { - res = 0; - if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf)) - goto err1; - } - goto ok; - } - } - } - res = 1; - -ok: - my_afree((byte*)page_buf); - return res; - -err1: - my_afree((byte*)page_buf); - return -1; -} - - -/* - Delete key - interface function - - RETURN - -1 Error - 0 Deleted -*/ - -int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length) -{ - uint page_size; - stPageList ReinsertList; - my_off_t old_root; - MI_KEYDEF *keyinfo = info->s->keyinfo + keynr; - - if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) - { - my_errno= HA_ERR_END_OF_FILE; - return -1; - } - - ReinsertList.pages = NULL; - ReinsertList.n_pages = 0; - ReinsertList.m_pages = 0; - - switch (rtree_delete_req(info, keyinfo, key, key_length, old_root, - &page_size, &ReinsertList, 0)) - { - case 2: - { - info->s->state.key_root[keynr] = HA_OFFSET_ERROR; - return 0; - } - case 0: - { - uint nod_flag; - ulong i; - for (i = 0; i < ReinsertList.n_pages; ++i) - { - uchar *page_buf; - uint nod_flag; - uchar *k; - uchar *last; - - if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length))) - { - my_errno = HA_ERR_OUT_OF_MEM; - goto err1; - } - if (!_mi_fetch_keypage(info, keyinfo, ReinsertList.pages[i].offs, - DFLT_INIT_HITS, page_buf, 0)) - goto err1; - nod_flag = mi_test_if_nod(page_buf); - k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); - last = rt_PAGE_END(page_buf); - for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag)) - { - if (rtree_insert_level(info, keynr, k, key_length, - ReinsertList.pages[i].level) == -1) - { - my_afree((byte*)page_buf); - goto err1; - } - } - my_afree((byte*)page_buf); - if (_mi_dispose(info, keyinfo, ReinsertList.pages[i].offs, - DFLT_INIT_HITS)) - goto err1; - } - if (ReinsertList.pages) - my_free((byte*) ReinsertList.pages, MYF(0)); - - /* check for redundant root (not leaf, 1 child) and eliminate */ - if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) - goto err1; - if (!_mi_fetch_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, - info->buff, 0)) - goto err1; - nod_flag = mi_test_if_nod(info->buff); - page_size = mi_getint(info->buff); - if (nod_flag && (page_size == 2 + key_length + nod_flag)) - { - my_off_t new_root = _mi_kpos(nod_flag, - rt_PAGE_FIRST_KEY(info->buff, nod_flag)); - if (_mi_dispose(info, keyinfo, old_root, DFLT_INIT_HITS)) - goto err1; - info->s->state.key_root[keynr] = new_root; - } - info->update= HA_STATE_DELETED; - return 0; - -err1: - return -1; - } - case 1: /* not found */ - { - my_errno = HA_ERR_KEY_NOT_FOUND; - return -1; - } - default: - case -1: /* error */ - { - return -1; - } - } -} - - -/* - Estimate number of suitable keys in the tree - - RETURN - estimated value -*/ - -ha_rows rtree_estimate(MI_INFO *info, uint keynr, uchar *key, - uint key_length, uint flag) -{ - MI_KEYDEF *keyinfo = info->s->keyinfo + keynr; - my_off_t root; - uint i = 0; - uchar *k; - uchar *last; - uint nod_flag; - uchar *page_buf; - uint k_len; - double area = 0; - ha_rows res = 0; - - if (flag & MBR_DISJOINT) - return info->state->records; - - if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) - return HA_POS_ERROR; - if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length))) - return HA_POS_ERROR; - if (!_mi_fetch_keypage(info, keyinfo, root, DFLT_INIT_HITS, page_buf, 0)) - goto err1; - nod_flag = mi_test_if_nod(page_buf); - - k_len = keyinfo->keylength - info->s->base.rec_reflength; - - k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); - last = rt_PAGE_END(page_buf); - - for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag), ++i) - { - if (nod_flag) - { - double k_area = rtree_rect_volume(keyinfo->seg, k, key_length); - - /* The following should be safe, even if we compare doubles */ - if (k_area == 0) - { - if (flag & (MBR_CONTAIN | MBR_INTERSECT)) - { - area += 1; - } - else if (flag & (MBR_WITHIN | MBR_EQUAL)) - { - if (!rtree_key_cmp(keyinfo->seg, key, k, key_length, MBR_WITHIN)) - area += 1; - } - else - goto err1; - } - else - { - if (flag & (MBR_CONTAIN | MBR_INTERSECT)) - { - area += rtree_overlapping_area(keyinfo->seg, key, k, key_length) / - k_area; - } - else if (flag & (MBR_WITHIN | MBR_EQUAL)) - { - if (!rtree_key_cmp(keyinfo->seg, key, k, key_length, MBR_WITHIN)) - area += rtree_rect_volume(keyinfo->seg, key, key_length) / - k_area; - } - else - goto err1; - } - } - else - { - if (!rtree_key_cmp(keyinfo->seg, key, k, key_length, flag)) - ++res; - } - } - if (nod_flag) - { - if (i) - res = (ha_rows) (area / i * info->state->records); - else - res = HA_POS_ERROR; - } - - my_afree((byte*)page_buf); - return res; - -err1: - my_afree((byte*)page_buf); - return HA_POS_ERROR; -} - -#endif /*HAVE_RTREE_KEYS*/ - diff --git a/myisam/rt_index.h b/myisam/rt_index.h deleted file mode 100644 index d3fcd934719..00000000000 --- a/myisam/rt_index.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin & MySQL Finland AB - & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#ifndef _rt_index_h -#define _rt_index_h - -#ifdef HAVE_RTREE_KEYS - -#define rt_PAGE_FIRST_KEY(page, nod_flag) (page + 2 + nod_flag) -#define rt_PAGE_NEXT_KEY(key, key_length, nod_flag) (key + key_length + \ - (nod_flag ? nod_flag : info->s->base.rec_reflength)) -#define rt_PAGE_END(page) (page + mi_getint(page)) - -#define rt_PAGE_MIN_SIZE(block_length) ((uint)(block_length) / 3) - -int rtree_insert(MI_INFO *info, uint keynr, uchar *key, uint key_length); -int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length); - -int rtree_find_first(MI_INFO *info, uint keynr, uchar *key, uint key_length, - uint search_flag); -int rtree_find_next(MI_INFO *info, uint keynr, uint search_flag); - -int rtree_get_first(MI_INFO *info, uint keynr, uint key_length); -int rtree_get_next(MI_INFO *info, uint keynr, uint key_length); - -ha_rows rtree_estimate(MI_INFO *info, uint keynr, uchar *key, - uint key_length, uint flag); - -int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, - uint key_length, my_off_t *new_page_offs); - -#endif /*HAVE_RTREE_KEYS*/ -#endif /* _rt_index_h */ diff --git a/myisam/rt_key.c b/myisam/rt_key.c deleted file mode 100644 index e2a402fbefd..00000000000 --- a/myisam/rt_key.c +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "myisamdef.h" - -#ifdef HAVE_RTREE_KEYS -#include "rt_index.h" -#include "rt_key.h" -#include "rt_mbr.h" - -/* - Add key to the page - - RESULT VALUES - -1 Error - 0 Not split - 1 Split -*/ - -int rtree_add_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, - uint key_length, uchar *page_buf, my_off_t *new_page) -{ - uint page_size = mi_getint(page_buf); - uint nod_flag = mi_test_if_nod(page_buf); - - if (page_size + key_length + info->s->base.rec_reflength <= - keyinfo->block_length) - { - /* split won't be necessary */ - if (nod_flag) - { - /* save key */ - memcpy(rt_PAGE_END(page_buf), key - nod_flag, key_length + nod_flag); - page_size += key_length + nod_flag; - } - else - { - /* save key */ - memcpy(rt_PAGE_END(page_buf), key, key_length + - info->s->base.rec_reflength); - page_size += key_length + info->s->base.rec_reflength; - } - mi_putint(page_buf, page_size, nod_flag); - return 0; - } - - return (rtree_split_page(info, keyinfo, page_buf, key, key_length, - new_page) ? -1 : 1); -} - -/* - Delete key from the page -*/ -int rtree_delete_key(MI_INFO *info, uchar *page_buf, uchar *key, - uint key_length, uint nod_flag) -{ - uint16 page_size = mi_getint(page_buf); - uchar *key_start; - - key_start= key - nod_flag; - if (!nod_flag) - key_length += info->s->base.rec_reflength; - - memmove(key_start, key + key_length, page_size - key_length - - (key - page_buf)); - page_size-= key_length + nod_flag; - - mi_putint(page_buf, page_size, nod_flag); - return 0; -} - - -/* - Calculate and store key MBR -*/ - -int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, - uint key_length, my_off_t child_page) -{ - if (!_mi_fetch_keypage(info, keyinfo, child_page, - DFLT_INIT_HITS, info->buff, 0)) - return -1; - - return rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length); -} - -#endif /*HAVE_RTREE_KEYS*/ diff --git a/myisam/rt_key.h b/myisam/rt_key.h deleted file mode 100644 index df4f8aa03a2..00000000000 --- a/myisam/rt_key.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin & MySQL Finland AB - & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Written by Ramil Kalimullin, who has a shared copyright to this code */ - -#ifndef _rt_key_h -#define _rt_key_h - -#ifdef HAVE_RTREE_KEYS - -int rtree_add_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, - uint key_length, uchar *page_buf, my_off_t *new_page); -int rtree_delete_key(MI_INFO *info, uchar *page, uchar *key, - uint key_length, uint nod_flag); -int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, - uint key_length, my_off_t child_page); - -#endif /*HAVE_RTREE_KEYS*/ -#endif /* _rt_key_h */ diff --git a/myisam/rt_mbr.c b/myisam/rt_mbr.c deleted file mode 100644 index c43daec2f7c..00000000000 --- a/myisam/rt_mbr.c +++ /dev/null @@ -1,801 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin & MySQL Finland AB - & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "myisamdef.h" - -#ifdef HAVE_RTREE_KEYS - -#include "rt_index.h" -#include "rt_mbr.h" - -#define INTERSECT_CMP(amin, amax, bmin, bmax) ((amin > bmax) || (bmin > amax)) -#define CONTAIN_CMP(amin, amax, bmin, bmax) ((bmin > amin) || (bmax < amax)) -#define WITHIN_CMP(amin, amax, bmin, bmax) ((amin > bmin) || (amax < bmax)) -#define DISJOINT_CMP(amin, amax, bmin, bmax) ((amin <= bmax) && (bmin <= amax)) -#define EQUAL_CMP(amin, amax, bmin, bmax) ((amin != bmin) || (amax != bmax)) - -#define FCMP(A, B) ((int)(A) - (int)(B)) -#define p_inc(A, B, X) {A += X; B += X;} - -#define RT_CMP(nextflag) \ - if (nextflag & MBR_INTERSECT) \ - { \ - if (INTERSECT_CMP(amin, amax, bmin, bmax)) \ - return 1; \ - } \ - else if (nextflag & MBR_CONTAIN) \ - { \ - if (CONTAIN_CMP(amin, amax, bmin, bmax)) \ - return 1; \ - } \ - else if (nextflag & MBR_WITHIN) \ - { \ - if (WITHIN_CMP(amin, amax, bmin, bmax)) \ - return 1; \ - } \ - else if (nextflag & MBR_EQUAL) \ - { \ - if (EQUAL_CMP(amin, amax, bmin, bmax)) \ - return 1; \ - } \ - else /* if (nextflag & MBR_DISJOINT) */ \ - { \ - if (DISJOINT_CMP(amin, amax, bmin, bmax)) \ - return 1; \ - } - -#define RT_CMP_KORR(type, korr_func, len, nextflag) \ -{ \ - type amin, amax, bmin, bmax; \ - amin = korr_func(a); \ - bmin = korr_func(b); \ - amax = korr_func(a+len); \ - bmax = korr_func(b+len); \ - RT_CMP(nextflag); \ -} - -#define RT_CMP_GET(type, get_func, len, nextflag) \ -{ \ - type amin, amax, bmin, bmax; \ - get_func(amin, a); \ - get_func(bmin, b); \ - get_func(amax, a+len); \ - get_func(bmax, b+len); \ - RT_CMP(nextflag); \ -} - -/* - Compares two keys a and b depending on nextflag - nextflag can contain these flags: - MBR_INTERSECT(a,b) a overlaps b - MBR_CONTAIN(a,b) a contains b - MBR_DISJOINT(a,b) a disjoint b - MBR_WITHIN(a,b) a within b - MBR_EQUAL(a,b) All coordinates of MBRs are equal - MBR_DATA(a,b) Data reference is the same - Returns 0 on success. -*/ -int rtree_key_cmp(HA_KEYSEG *keyseg, uchar *b, uchar *a, uint key_length, - uint nextflag) -{ - for (; (int) key_length > 0; keyseg += 2 ) - { - uint32 keyseg_length; - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_INT8: - RT_CMP_KORR(int8, mi_sint1korr, 1, nextflag); - break; - case HA_KEYTYPE_BINARY: - RT_CMP_KORR(uint8, mi_uint1korr, 1, nextflag); - break; - case HA_KEYTYPE_SHORT_INT: - RT_CMP_KORR(int16, mi_sint2korr, 2, nextflag); - break; - case HA_KEYTYPE_USHORT_INT: - RT_CMP_KORR(uint16, mi_uint2korr, 2, nextflag); - break; - case HA_KEYTYPE_INT24: - RT_CMP_KORR(int32, mi_sint3korr, 3, nextflag); - break; - case HA_KEYTYPE_UINT24: - RT_CMP_KORR(uint32, mi_uint3korr, 3, nextflag); - break; - case HA_KEYTYPE_LONG_INT: - RT_CMP_KORR(int32, mi_sint4korr, 4, nextflag); - break; - case HA_KEYTYPE_ULONG_INT: - RT_CMP_KORR(uint32, mi_uint4korr, 4, nextflag); - break; -#ifdef HAVE_LONG_LONG - case HA_KEYTYPE_LONGLONG: - RT_CMP_KORR(longlong, mi_sint8korr, 8, nextflag) - break; - case HA_KEYTYPE_ULONGLONG: - RT_CMP_KORR(ulonglong, mi_uint8korr, 8, nextflag) - break; -#endif - case HA_KEYTYPE_FLOAT: - /* The following should be safe, even if we compare doubles */ - RT_CMP_GET(float, mi_float4get, 4, nextflag); - break; - case HA_KEYTYPE_DOUBLE: - RT_CMP_GET(double, mi_float8get, 8, nextflag); - break; - case HA_KEYTYPE_END: - goto end; - default: - return 1; - } - keyseg_length= keyseg->length * 2; - key_length-= keyseg_length; - a+= keyseg_length; - b+= keyseg_length; - } - -end: - if (nextflag & MBR_DATA) - { - uchar *end = a + keyseg->length; - do - { - if (*a++ != *b++) - return FCMP(a[-1], b[-1]); - } while (a != end); - } - return 0; -} - -#define RT_VOL_KORR(type, korr_func, len, cast) \ -{ \ - type amin, amax; \ - amin = korr_func(a); \ - amax = korr_func(a+len); \ - res *= (cast(amax) - cast(amin)); \ -} - -#define RT_VOL_GET(type, get_func, len, cast) \ -{ \ - type amin, amax; \ - get_func(amin, a); \ - get_func(amax, a+len); \ - res *= (cast(amax) - cast(amin)); \ -} - -/* - Calculates rectangle volume -*/ -double rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length) -{ - double res = 1; - for (; (int)key_length > 0; keyseg += 2) - { - uint32 keyseg_length; - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_INT8: - RT_VOL_KORR(int8, mi_sint1korr, 1, (double)); - break; - case HA_KEYTYPE_BINARY: - RT_VOL_KORR(uint8, mi_uint1korr, 1, (double)); - break; - case HA_KEYTYPE_SHORT_INT: - RT_VOL_KORR(int16, mi_sint2korr, 2, (double)); - break; - case HA_KEYTYPE_USHORT_INT: - RT_VOL_KORR(uint16, mi_uint2korr, 2, (double)); - break; - case HA_KEYTYPE_INT24: - RT_VOL_KORR(int32, mi_sint3korr, 3, (double)); - break; - case HA_KEYTYPE_UINT24: - RT_VOL_KORR(uint32, mi_uint3korr, 3, (double)); - break; - case HA_KEYTYPE_LONG_INT: - RT_VOL_KORR(int32, mi_sint4korr, 4, (double)); - break; - case HA_KEYTYPE_ULONG_INT: - RT_VOL_KORR(uint32, mi_uint4korr, 4, (double)); - break; -#ifdef HAVE_LONG_LONG - case HA_KEYTYPE_LONGLONG: - RT_VOL_KORR(longlong, mi_sint8korr, 8, (double)); - break; - case HA_KEYTYPE_ULONGLONG: - RT_VOL_KORR(longlong, mi_sint8korr, 8, ulonglong2double); - break; -#endif - case HA_KEYTYPE_FLOAT: - RT_VOL_GET(float, mi_float4get, 4, (double)); - break; - case HA_KEYTYPE_DOUBLE: - RT_VOL_GET(double, mi_float8get, 8, (double)); - break; - case HA_KEYTYPE_END: - key_length = 0; - break; - default: - return -1; - } - keyseg_length= keyseg->length * 2; - key_length-= keyseg_length; - a+= keyseg_length; - } - return res; -} - -#define RT_D_MBR_KORR(type, korr_func, len, cast) \ -{ \ - type amin, amax; \ - amin = korr_func(a); \ - amax = korr_func(a+len); \ - *res++ = cast(amin); \ - *res++ = cast(amax); \ -} - -#define RT_D_MBR_GET(type, get_func, len, cast) \ -{ \ - type amin, amax; \ - get_func(amin, a); \ - get_func(amax, a+len); \ - *res++ = cast(amin); \ - *res++ = cast(amax); \ -} - - -/* - Creates an MBR as an array of doubles. -*/ - -int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) -{ - for (; (int)key_length > 0; keyseg += 2) - { - uint32 keyseg_length; - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_INT8: - RT_D_MBR_KORR(int8, mi_sint1korr, 1, (double)); - break; - case HA_KEYTYPE_BINARY: - RT_D_MBR_KORR(uint8, mi_uint1korr, 1, (double)); - break; - case HA_KEYTYPE_SHORT_INT: - RT_D_MBR_KORR(int16, mi_sint2korr, 2, (double)); - break; - case HA_KEYTYPE_USHORT_INT: - RT_D_MBR_KORR(uint16, mi_uint2korr, 2, (double)); - break; - case HA_KEYTYPE_INT24: - RT_D_MBR_KORR(int32, mi_sint3korr, 3, (double)); - break; - case HA_KEYTYPE_UINT24: - RT_D_MBR_KORR(uint32, mi_uint3korr, 3, (double)); - break; - case HA_KEYTYPE_LONG_INT: - RT_D_MBR_KORR(int32, mi_sint4korr, 4, (double)); - break; - case HA_KEYTYPE_ULONG_INT: - RT_D_MBR_KORR(uint32, mi_uint4korr, 4, (double)); - break; -#ifdef HAVE_LONG_LONG - case HA_KEYTYPE_LONGLONG: - RT_D_MBR_KORR(longlong, mi_sint8korr, 8, (double)); - break; - case HA_KEYTYPE_ULONGLONG: - RT_D_MBR_KORR(longlong, mi_sint8korr, 8, ulonglong2double); - break; -#endif - case HA_KEYTYPE_FLOAT: - RT_D_MBR_GET(float, mi_float4get, 4, (double)); - break; - case HA_KEYTYPE_DOUBLE: - RT_D_MBR_GET(double, mi_float8get, 8, (double)); - break; - case HA_KEYTYPE_END: - key_length = 0; - break; - default: - return 1; - } - keyseg_length= keyseg->length * 2; - key_length-= keyseg_length; - a+= keyseg_length; - } - return 0; -} - -#define RT_COMB_KORR(type, korr_func, store_func, len) \ -{ \ - type amin, amax, bmin, bmax; \ - amin = korr_func(a); \ - bmin = korr_func(b); \ - amax = korr_func(a+len); \ - bmax = korr_func(b+len); \ - amin = min(amin, bmin); \ - amax = max(amax, bmax); \ - store_func(c, amin); \ - store_func(c+len, amax); \ -} - -#define RT_COMB_GET(type, get_func, store_func, len) \ -{ \ - type amin, amax, bmin, bmax; \ - get_func(amin, a); \ - get_func(bmin, b); \ - get_func(amax, a+len); \ - get_func(bmax, b+len); \ - amin = min(amin, bmin); \ - amax = max(amax, bmax); \ - store_func(c, amin); \ - store_func(c+len, amax); \ -} - -/* - Creates common minimal bounding rectungle - for two input rectagnles a and b - Result is written to c -*/ - -int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c, - uint key_length) -{ - for ( ; (int) key_length > 0 ; keyseg += 2) - { - uint32 keyseg_length; - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_INT8: - RT_COMB_KORR(int8, mi_sint1korr, mi_int1store, 1); - break; - case HA_KEYTYPE_BINARY: - RT_COMB_KORR(uint8, mi_uint1korr, mi_int1store, 1); - break; - case HA_KEYTYPE_SHORT_INT: - RT_COMB_KORR(int16, mi_sint2korr, mi_int2store, 2); - break; - case HA_KEYTYPE_USHORT_INT: - RT_COMB_KORR(uint16, mi_uint2korr, mi_int2store, 2); - break; - case HA_KEYTYPE_INT24: - RT_COMB_KORR(int32, mi_sint3korr, mi_int3store, 3); - break; - case HA_KEYTYPE_UINT24: - RT_COMB_KORR(uint32, mi_uint3korr, mi_int3store, 3); - break; - case HA_KEYTYPE_LONG_INT: - RT_COMB_KORR(int32, mi_sint4korr, mi_int4store, 4); - break; - case HA_KEYTYPE_ULONG_INT: - RT_COMB_KORR(uint32, mi_uint4korr, mi_int4store, 4); - break; -#ifdef HAVE_LONG_LONG - case HA_KEYTYPE_LONGLONG: - RT_COMB_KORR(longlong, mi_sint8korr, mi_int8store, 8); - break; - case HA_KEYTYPE_ULONGLONG: - RT_COMB_KORR(ulonglong, mi_uint8korr, mi_int8store, 8); - break; -#endif - case HA_KEYTYPE_FLOAT: - RT_COMB_GET(float, mi_float4get, mi_float4store, 4); - break; - case HA_KEYTYPE_DOUBLE: - RT_COMB_GET(double, mi_float8get, mi_float8store, 8); - break; - case HA_KEYTYPE_END: - return 0; - default: - return 1; - } - keyseg_length= keyseg->length * 2; - key_length-= keyseg_length; - a+= keyseg_length; - b+= keyseg_length; - c+= keyseg_length; - } - return 0; -} - - -#define RT_OVL_AREA_KORR(type, korr_func, len) \ -{ \ - type amin, amax, bmin, bmax; \ - amin = korr_func(a); \ - bmin = korr_func(b); \ - amax = korr_func(a+len); \ - bmax = korr_func(b+len); \ - amin = max(amin, bmin); \ - amax = min(amax, bmax); \ - if (amin >= amax) \ - return 0; \ - res *= amax - amin; \ -} - -#define RT_OVL_AREA_GET(type, get_func, len) \ -{ \ - type amin, amax, bmin, bmax; \ - get_func(amin, a); \ - get_func(bmin, b); \ - get_func(amax, a+len); \ - get_func(bmax, b+len); \ - amin = max(amin, bmin); \ - amax = min(amax, bmax); \ - if (amin >= amax) \ - return 0; \ - res *= amax - amin; \ -} - -/* -Calculates overlapping area of two MBRs a & b -*/ -double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b, - uint key_length) -{ - double res = 1; - for (; (int) key_length > 0 ; keyseg += 2) - { - uint32 keyseg_length; - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_INT8: - RT_OVL_AREA_KORR(int8, mi_sint1korr, 1); - break; - case HA_KEYTYPE_BINARY: - RT_OVL_AREA_KORR(uint8, mi_uint1korr, 1); - break; - case HA_KEYTYPE_SHORT_INT: - RT_OVL_AREA_KORR(int16, mi_sint2korr, 2); - break; - case HA_KEYTYPE_USHORT_INT: - RT_OVL_AREA_KORR(uint16, mi_uint2korr, 2); - break; - case HA_KEYTYPE_INT24: - RT_OVL_AREA_KORR(int32, mi_sint3korr, 3); - break; - case HA_KEYTYPE_UINT24: - RT_OVL_AREA_KORR(uint32, mi_uint3korr, 3); - break; - case HA_KEYTYPE_LONG_INT: - RT_OVL_AREA_KORR(int32, mi_sint4korr, 4); - break; - case HA_KEYTYPE_ULONG_INT: - RT_OVL_AREA_KORR(uint32, mi_uint4korr, 4); - break; -#ifdef HAVE_LONG_LONG - case HA_KEYTYPE_LONGLONG: - RT_OVL_AREA_KORR(longlong, mi_sint8korr, 8); - break; - case HA_KEYTYPE_ULONGLONG: - RT_OVL_AREA_KORR(longlong, mi_sint8korr, 8); - break; -#endif - case HA_KEYTYPE_FLOAT: - RT_OVL_AREA_GET(float, mi_float4get, 4); - break; - case HA_KEYTYPE_DOUBLE: - RT_OVL_AREA_GET(double, mi_float8get, 8); - break; - case HA_KEYTYPE_END: - return res; - default: - return -1; - } - keyseg_length= keyseg->length * 2; - key_length-= keyseg_length; - a+= keyseg_length; - b+= keyseg_length; - } - return res; -} - -#define RT_AREA_INC_KORR(type, korr_func, len) \ -{ \ - type amin, amax, bmin, bmax; \ - amin = korr_func(a); \ - bmin = korr_func(b); \ - amax = korr_func(a+len); \ - bmax = korr_func(b+len); \ - a_area *= (((double)amax) - ((double)amin)); \ - loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \ -} - -#define RT_AREA_INC_GET(type, get_func, len)\ -{\ - type amin, amax, bmin, bmax; \ - get_func(amin, a); \ - get_func(bmin, b); \ - get_func(amax, a+len); \ - get_func(bmax, b+len); \ - a_area *= (((double)amax) - ((double)amin)); \ - loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \ -} - -/* -Calculates MBR_AREA(a+b) - MBR_AREA(a) -*/ -double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, - uint key_length, double *ab_area) -{ - double a_area= 1.0; - double loc_ab_area= 1.0; - - *ab_area= 1.0; - for (; (int)key_length > 0; keyseg += 2) - { - uint32 keyseg_length; - - if (keyseg->null_bit) /* Handle NULL part */ - return -1; - - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_INT8: - RT_AREA_INC_KORR(int8, mi_sint1korr, 1); - break; - case HA_KEYTYPE_BINARY: - RT_AREA_INC_KORR(uint8, mi_uint1korr, 1); - break; - case HA_KEYTYPE_SHORT_INT: - RT_AREA_INC_KORR(int16, mi_sint2korr, 2); - break; - case HA_KEYTYPE_USHORT_INT: - RT_AREA_INC_KORR(uint16, mi_uint2korr, 2); - break; - case HA_KEYTYPE_INT24: - RT_AREA_INC_KORR(int32, mi_sint3korr, 3); - break; - case HA_KEYTYPE_UINT24: - RT_AREA_INC_KORR(int32, mi_uint3korr, 3); - break; - case HA_KEYTYPE_LONG_INT: - RT_AREA_INC_KORR(int32, mi_sint4korr, 4); - break; - case HA_KEYTYPE_ULONG_INT: - RT_AREA_INC_KORR(uint32, mi_uint4korr, 4); - break; -#ifdef HAVE_LONG_LONG - case HA_KEYTYPE_LONGLONG: - RT_AREA_INC_KORR(longlong, mi_sint8korr, 8); - break; - case HA_KEYTYPE_ULONGLONG: - RT_AREA_INC_KORR(longlong, mi_sint8korr, 8); - break; -#endif - case HA_KEYTYPE_FLOAT: - RT_AREA_INC_GET(float, mi_float4get, 4); - break; - case HA_KEYTYPE_DOUBLE: - RT_AREA_INC_GET(double, mi_float8get, 8); - break; - case HA_KEYTYPE_END: - goto safe_end; - default: - return -1; - } - keyseg_length= keyseg->length * 2; - key_length-= keyseg_length; - a+= keyseg_length; - b+= keyseg_length; - } -safe_end: - *ab_area= loc_ab_area; - return loc_ab_area - a_area; -} - -#define RT_PERIM_INC_KORR(type, korr_func, len) \ -{ \ - type amin, amax, bmin, bmax; \ - amin = korr_func(a); \ - bmin = korr_func(b); \ - amax = korr_func(a+len); \ - bmax = korr_func(b+len); \ - a_perim+= (((double)amax) - ((double)amin)); \ - *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \ -} - -#define RT_PERIM_INC_GET(type, get_func, len)\ -{\ - type amin, amax, bmin, bmax; \ - get_func(amin, a); \ - get_func(bmin, b); \ - get_func(amax, a+len); \ - get_func(bmax, b+len); \ - a_perim+= (((double)amax) - ((double)amin)); \ - *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \ -} - -/* -Calculates MBR_PERIMETER(a+b) - MBR_PERIMETER(a) -*/ -double rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, - uint key_length, double *ab_perim) -{ - double a_perim = 0.0; - - *ab_perim= 0.0; - for (; (int)key_length > 0; keyseg += 2) - { - uint32 keyseg_length; - - if (keyseg->null_bit) /* Handle NULL part */ - return -1; - - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_INT8: - RT_PERIM_INC_KORR(int8, mi_sint1korr, 1); - break; - case HA_KEYTYPE_BINARY: - RT_PERIM_INC_KORR(uint8, mi_uint1korr, 1); - break; - case HA_KEYTYPE_SHORT_INT: - RT_PERIM_INC_KORR(int16, mi_sint2korr, 2); - break; - case HA_KEYTYPE_USHORT_INT: - RT_PERIM_INC_KORR(uint16, mi_uint2korr, 2); - break; - case HA_KEYTYPE_INT24: - RT_PERIM_INC_KORR(int32, mi_sint3korr, 3); - break; - case HA_KEYTYPE_UINT24: - RT_PERIM_INC_KORR(int32, mi_uint3korr, 3); - break; - case HA_KEYTYPE_LONG_INT: - RT_PERIM_INC_KORR(int32, mi_sint4korr, 4); - break; - case HA_KEYTYPE_ULONG_INT: - RT_PERIM_INC_KORR(uint32, mi_uint4korr, 4); - break; -#ifdef HAVE_LONG_LONG - case HA_KEYTYPE_LONGLONG: - RT_PERIM_INC_KORR(longlong, mi_sint8korr, 8); - break; - case HA_KEYTYPE_ULONGLONG: - RT_PERIM_INC_KORR(longlong, mi_sint8korr, 8); - break; -#endif - case HA_KEYTYPE_FLOAT: - RT_PERIM_INC_GET(float, mi_float4get, 4); - break; - case HA_KEYTYPE_DOUBLE: - RT_PERIM_INC_GET(double, mi_float8get, 8); - break; - case HA_KEYTYPE_END: - return *ab_perim - a_perim; - default: - return -1; - } - keyseg_length= keyseg->length * 2; - key_length-= keyseg_length; - a+= keyseg_length; - b+= keyseg_length; - } - return *ab_perim - a_perim; -} - - -#define RT_PAGE_MBR_KORR(type, korr_func, store_func, len) \ -{ \ - type amin, amax, bmin, bmax; \ - amin = korr_func(k + inc); \ - amax = korr_func(k + inc + len); \ - k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag); \ - for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag)) \ -{ \ - bmin = korr_func(k + inc); \ - bmax = korr_func(k + inc + len); \ - if (amin > bmin) \ - amin = bmin; \ - if (amax < bmax) \ - amax = bmax; \ -} \ - store_func(c, amin); \ - c += len; \ - store_func(c, amax); \ - c += len; \ - inc += 2 * len; \ -} - -#define RT_PAGE_MBR_GET(type, get_func, store_func, len) \ -{ \ - type amin, amax, bmin, bmax; \ - get_func(amin, k + inc); \ - get_func(amax, k + inc + len); \ - k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag); \ - for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag)) \ -{ \ - get_func(bmin, k + inc); \ - get_func(bmax, k + inc + len); \ - if (amin > bmin) \ - amin = bmin; \ - if (amax < bmax) \ - amax = bmax; \ -} \ - store_func(c, amin); \ - c += len; \ - store_func(c, amax); \ - c += len; \ - inc += 2 * len; \ -} - -/* -Calculates key page total MBR = MBR(key1) + MBR(key2) + ... -*/ -int rtree_page_mbr(MI_INFO *info, HA_KEYSEG *keyseg, uchar *page_buf, - uchar *c, uint key_length) -{ - uint inc = 0; - uint k_len = key_length; - uint nod_flag = mi_test_if_nod(page_buf); - uchar *k; - uchar *last = rt_PAGE_END(page_buf); - - for (; (int)key_length > 0; keyseg += 2) - { - key_length -= keyseg->length * 2; - - /* Handle NULL part */ - if (keyseg->null_bit) - { - return 1; - } - - k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); - - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_INT8: - RT_PAGE_MBR_KORR(int8, mi_sint1korr, mi_int1store, 1); - break; - case HA_KEYTYPE_BINARY: - RT_PAGE_MBR_KORR(uint8, mi_uint1korr, mi_int1store, 1); - break; - case HA_KEYTYPE_SHORT_INT: - RT_PAGE_MBR_KORR(int16, mi_sint2korr, mi_int2store, 2); - break; - case HA_KEYTYPE_USHORT_INT: - RT_PAGE_MBR_KORR(uint16, mi_uint2korr, mi_int2store, 2); - break; - case HA_KEYTYPE_INT24: - RT_PAGE_MBR_KORR(int32, mi_sint3korr, mi_int3store, 3); - break; - case HA_KEYTYPE_UINT24: - RT_PAGE_MBR_KORR(uint32, mi_uint3korr, mi_int3store, 3); - break; - case HA_KEYTYPE_LONG_INT: - RT_PAGE_MBR_KORR(int32, mi_sint4korr, mi_int4store, 4); - break; - case HA_KEYTYPE_ULONG_INT: - RT_PAGE_MBR_KORR(uint32, mi_uint4korr, mi_int4store, 4); - break; -#ifdef HAVE_LONG_LONG - case HA_KEYTYPE_LONGLONG: - RT_PAGE_MBR_KORR(longlong, mi_sint8korr, mi_int8store, 8); - break; - case HA_KEYTYPE_ULONGLONG: - RT_PAGE_MBR_KORR(ulonglong, mi_uint8korr, mi_int8store, 8); - break; -#endif - case HA_KEYTYPE_FLOAT: - RT_PAGE_MBR_GET(float, mi_float4get, mi_float4store, 4); - break; - case HA_KEYTYPE_DOUBLE: - RT_PAGE_MBR_GET(double, mi_float8get, mi_float8store, 8); - break; - case HA_KEYTYPE_END: - return 0; - default: - return 1; - } - } - return 0; -} - -#endif /*HAVE_RTREE_KEYS*/ diff --git a/myisam/rt_mbr.h b/myisam/rt_mbr.h deleted file mode 100644 index 2153faad2b4..00000000000 --- a/myisam/rt_mbr.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin & MySQL Finland AB - & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#ifndef _rt_mbr_h -#define _rt_mbr_h - -#ifdef HAVE_RTREE_KEYS - -int rtree_key_cmp(HA_KEYSEG *keyseg, uchar *a, uchar *b, uint key_length, - uint nextflag); -int rtree_combine_rect(HA_KEYSEG *keyseg,uchar *, uchar *, uchar*, - uint key_length); -double rtree_rect_volume(HA_KEYSEG *keyseg, uchar*, uint key_length); -int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res); -double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar *a, uchar *b, - uint key_length); -double rtree_area_increase(HA_KEYSEG *keyseg, uchar *a, uchar *b, - uint key_length, double *ab_area); -double rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, - uint key_length, double *ab_perim); -int rtree_page_mbr(MI_INFO *info, HA_KEYSEG *keyseg, uchar *page_buf, - uchar* c, uint key_length); -#endif /*HAVE_RTREE_KEYS*/ -#endif /* _rt_mbr_h */ diff --git a/myisam/rt_split.c b/myisam/rt_split.c deleted file mode 100644 index 005e86805bb..00000000000 --- a/myisam/rt_split.c +++ /dev/null @@ -1,352 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & Alexey Botchkov & MySQL Finland AB - & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "myisamdef.h" - -#ifdef HAVE_RTREE_KEYS - -#include "rt_index.h" -#include "rt_key.h" -#include "rt_mbr.h" - -typedef struct -{ - double square; - int n_node; - uchar *key; - double *coords; -} SplitStruct; - -inline static double *reserve_coords(double **d_buffer, int n_dim) -{ - double *coords = *d_buffer; - (*d_buffer) += n_dim * 2; - return coords; -} - -static void mbr_join(double *a, const double *b, int n_dim) -{ - double *end = a + n_dim * 2; - do - { - if (a[0] > b[0]) - a[0] = b[0]; - - if (a[1] < b[1]) - a[1] = b[1]; - - a += 2; - b += 2; - }while (a != end); -} - -/* -Counts the square of mbr which is a join of a and b -*/ -static double mbr_join_square(const double *a, const double *b, int n_dim) -{ - const double *end = a + n_dim * 2; - double square = 1.0; - do - { - square *= - ((a[1] < b[1]) ? b[1] : a[1]) - ((a[0] > b[0]) ? b[0] : a[0]); - - a += 2; - b += 2; - }while (a != end); - - return square; -} - -static double count_square(const double *a, int n_dim) -{ - const double *end = a + n_dim * 2; - double square = 1.0; - do - { - square *= a[1] - a[0]; - a += 2; - }while (a != end); - return square; -} - -inline static void copy_coords(double *dst, const double *src, int n_dim) -{ - memcpy(dst, src, sizeof(double) * (n_dim * 2)); -} - -/* -Select two nodes to collect group upon -*/ -static void pick_seeds(SplitStruct *node, int n_entries, - SplitStruct **seed_a, SplitStruct **seed_b, int n_dim) -{ - SplitStruct *cur1; - SplitStruct *lim1 = node + (n_entries - 1); - SplitStruct *cur2; - SplitStruct *lim2 = node + n_entries; - - double max_d = -DBL_MAX; - double d; - - for (cur1 = node; cur1 < lim1; ++cur1) - { - for (cur2=cur1 + 1; cur2 < lim2; ++cur2) - { - - d = mbr_join_square(cur1->coords, cur2->coords, n_dim) - cur1->square - - cur2->square; - if (d > max_d) - { - max_d = d; - *seed_a = cur1; - *seed_b = cur2; - } - } - } -} - -/* -Select next node and group where to add -*/ -static void pick_next(SplitStruct *node, int n_entries, double *g1, double *g2, - SplitStruct **choice, int *n_group, int n_dim) -{ - SplitStruct *cur = node; - SplitStruct *end = node + n_entries; - - double max_diff = -DBL_MAX; - - for (; cur<end; ++cur) - { - double diff; - double abs_diff; - - if (cur->n_node) - { - continue; - } - - diff = mbr_join_square(g1, cur->coords, n_dim) - - mbr_join_square(g2, cur->coords, n_dim); - - abs_diff = fabs(diff); - if (abs_diff > max_diff) - { - max_diff = abs_diff; - *n_group = 1 + (diff > 0); - *choice = cur; - } - } -} - -/* -Mark not-in-group entries as n_group -*/ -static void mark_all_entries(SplitStruct *node, int n_entries, int n_group) -{ - SplitStruct *cur = node; - SplitStruct *end = node + n_entries; - for (; cur<end; ++cur) - { - if (cur->n_node) - { - continue; - } - cur->n_node = n_group; - } -} - -static int split_rtree_node(SplitStruct *node, int n_entries, - int all_size, /* Total key's size */ - int key_size, - int min_size, /* Minimal group size */ - int size1, int size2 /* initial group sizes */, - double **d_buffer, int n_dim) -{ - SplitStruct *cur; - SplitStruct *a; - SplitStruct *b; - double *g1 = reserve_coords(d_buffer, n_dim); - double *g2 = reserve_coords(d_buffer, n_dim); - SplitStruct *next; - int next_node; - int i; - SplitStruct *end = node + n_entries; - - if (all_size < min_size * 2) - { - return 1; - } - - cur = node; - for (; cur<end; ++cur) - { - cur->square = count_square(cur->coords, n_dim); - cur->n_node = 0; - } - - pick_seeds(node, n_entries, &a, &b, n_dim); - a->n_node = 1; - b->n_node = 2; - - - copy_coords(g1, a->coords, n_dim); - size1 += key_size; - copy_coords(g2, b->coords, n_dim); - size2 += key_size; - - - for (i=n_entries - 2; i>0; --i) - { - if (all_size - (size2 + key_size) < min_size) /* Can't write into group 2 */ - { - mark_all_entries(node, n_entries, 1); - break; - } - - if (all_size - (size1 + key_size) < min_size) /* Can't write into group 1 */ - { - mark_all_entries(node, n_entries, 2); - break; - } - - pick_next(node, n_entries, g1, g2, &next, &next_node, n_dim); - if (next_node == 1) - { - size1 += key_size; - mbr_join(g1, next->coords, n_dim); - } - else - { - size2 += key_size; - mbr_join(g2, next->coords, n_dim); - } - next->n_node = next_node; - } - - return 0; -} - -int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, - uint key_length, my_off_t *new_page_offs) -{ - int n1, n2; /* Number of items in groups */ - - SplitStruct *task; - SplitStruct *cur; - SplitStruct *stop; - double *coord_buf; - double *next_coord; - double *old_coord; - int n_dim; - uchar *source_cur, *cur1, *cur2; - uchar *new_page; - int err_code = 0; - - uint nod_flag = mi_test_if_nod(page); - uint full_length = key_length + (nod_flag ? nod_flag : - info->s->base.rec_reflength); - - int max_keys = (mi_getint(page)-2) / (full_length); - - n_dim = keyinfo->keysegs / 2; - - if (!(coord_buf= my_alloca(n_dim * 2 * sizeof(double) * (max_keys + 1 + 4) + - sizeof(SplitStruct) * (max_keys + 1)))) - return -1; - - task= (SplitStruct *)(coord_buf + n_dim * 2 * (max_keys + 1 + 4)); - - next_coord = coord_buf; - - stop = task + max_keys; - source_cur = rt_PAGE_FIRST_KEY(page, nod_flag); - - for (cur = task; cur < stop; ++cur, source_cur = rt_PAGE_NEXT_KEY(source_cur, - key_length, nod_flag)) - { - cur->coords = reserve_coords(&next_coord, n_dim); - cur->key = source_cur; - rtree_d_mbr(keyinfo->seg, source_cur, key_length, cur->coords); - } - - cur->coords = reserve_coords(&next_coord, n_dim); - rtree_d_mbr(keyinfo->seg, key, key_length, cur->coords); - cur->key = key; - - old_coord = next_coord; - - if (split_rtree_node(task, max_keys + 1, - mi_getint(page) + full_length + 2, full_length, - rt_PAGE_MIN_SIZE(keyinfo->block_length), - 2, 2, &next_coord, n_dim)) - { - err_code = 1; - goto split_err; - } - - if (!(new_page = (uchar*)my_alloca((uint)keyinfo->block_length))) - { - err_code= -1; - goto split_err; - } - - stop = task + (max_keys + 1); - cur1 = rt_PAGE_FIRST_KEY(page, nod_flag); - cur2 = rt_PAGE_FIRST_KEY(new_page, nod_flag); - - n1 = 0; - n2 = 0; - for (cur = task; cur < stop; ++cur) - { - uchar *to; - if (cur->n_node == 1) - { - to = cur1; - cur1 = rt_PAGE_NEXT_KEY(cur1, key_length, nod_flag); - ++n1; - } - else - { - to = cur2; - cur2 = rt_PAGE_NEXT_KEY(cur2, key_length, nod_flag); - ++n2; - } - if (to != cur->key) - memcpy(to - nod_flag, cur->key - nod_flag, full_length); - } - - mi_putint(page, 2 + n1 * full_length, nod_flag); - mi_putint(new_page, 2 + n2 * full_length, nod_flag); - - if ((*new_page_offs= _mi_new(info, keyinfo, DFLT_INIT_HITS)) == - HA_OFFSET_ERROR) - err_code= -1; - else - err_code= _mi_write_keypage(info, keyinfo, *new_page_offs, - DFLT_INIT_HITS, new_page); - - my_afree((byte*)new_page); - -split_err: - my_afree((byte*) coord_buf); - return err_code; -} - -#endif /*HAVE_RTREE_KEYS*/ diff --git a/myisam/rt_test.c b/myisam/rt_test.c deleted file mode 100644 index 4f04aa11fce..00000000000 --- a/myisam/rt_test.c +++ /dev/null @@ -1,471 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Testing of the basic functions of a MyISAM rtree table */ -/* Written by Alex Barkov who has a shared copyright to this code */ - - -#include "myisam.h" - -#ifdef HAVE_RTREE_KEYS - -#include "rt_index.h" - -#define MAX_REC_LENGTH 1024 -#define ndims 2 -#define KEYALG HA_KEY_ALG_RTREE - -static int read_with_pos(MI_INFO * file, int silent); -static void create_record(char *record,uint rownr); -static void create_record1(char *record,uint rownr); -static void print_record(char * record,my_off_t offs,const char * tail); -static int run_test(const char *filename); - -static double rt_data[]= -{ - /*1*/ 0,10,0,10, - /*2*/ 5,15,0,10, - /*3*/ 0,10,5,15, - /*4*/ 10,20,10,20, - /*5*/ 0,10,0,10, - /*6*/ 5,15,0,10, - /*7*/ 0,10,5,15, - /*8*/ 10,20,10,20, - /*9*/ 0,10,0,10, - /*10*/ 5,15,0,10, - /*11*/ 0,10,5,15, - /*12*/ 10,20,10,20, - /*13*/ 0,10,0,10, - /*14*/ 5,15,0,10, - /*15*/ 0,10,5,15, - /*16*/ 10,20,10,20, - /*17*/ 5,15,0,10, - /*18*/ 0,10,5,15, - /*19*/ 10,20,10,20, - /*20*/ 0,10,0,10, - - /*1*/ 100,110,0,10, - /*2*/ 105,115,0,10, - /*3*/ 100,110,5,15, - /*4*/ 110,120,10,20, - /*5*/ 100,110,0,10, - /*6*/ 105,115,0,10, - /*7*/ 100,110,5,15, - /*8*/ 110,120,10,20, - /*9*/ 100,110,0,10, - /*10*/ 105,115,0,10, - /*11*/ 100,110,5,15, - /*12*/ 110,120,10,20, - /*13*/ 100,110,0,10, - /*14*/ 105,115,0,10, - /*15*/ 100,110,5,15, - /*16*/ 110,120,10,20, - /*17*/ 105,115,0,10, - /*18*/ 100,110,5,15, - /*19*/ 110,120,10,20, - /*20*/ 100,110,0,10, - -1 -}; - -int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) -{ - MY_INIT(argv[0]); - exit(run_test("rt_test")); -} - - -static int run_test(const char *filename) -{ - MI_INFO *file; - MI_UNIQUEDEF uniquedef; - MI_CREATE_INFO create_info; - MI_COLUMNDEF recinfo[20]; - MI_KEYDEF keyinfo[20]; - HA_KEYSEG keyseg[20]; - key_range range; - - int silent=0; - int opt_unique=0; - int create_flag=0; - int key_type=HA_KEYTYPE_DOUBLE; - int key_length=8; - int null_fields=0; - int nrecords=sizeof(rt_data)/(sizeof(double)*4);/* 3000;*/ - int rec_length=0; - int uniques=0; - int i; - int error; - int row_count=0; - char record[MAX_REC_LENGTH]; - char read_record[MAX_REC_LENGTH]; - int upd= 10; - ha_rows hrows; - - /* Define a column for NULLs and DEL markers*/ - - recinfo[0].type=FIELD_NORMAL; - recinfo[0].length=1; /* For NULL bits */ - rec_length=1; - - /* Define 2*ndims columns for coordinates*/ - - for (i=1; i<=2*ndims ;i++){ - recinfo[i].type=FIELD_NORMAL; - recinfo[i].length=key_length; - rec_length+=key_length; - } - - /* Define a key with 2*ndims segments */ - - keyinfo[0].seg=keyseg; - keyinfo[0].keysegs=2*ndims; - keyinfo[0].flag=0; - keyinfo[0].key_alg=KEYALG; - - for (i=0; i<2*ndims; i++){ - keyinfo[0].seg[i].type= key_type; - keyinfo[0].seg[i].flag=0; /* Things like HA_REVERSE_SORT */ - keyinfo[0].seg[i].start= (key_length*i)+1; - keyinfo[0].seg[i].length=key_length; - keyinfo[0].seg[i].null_bit= null_fields ? 2 : 0; - keyinfo[0].seg[i].null_pos=0; - keyinfo[0].seg[i].language=default_charset_info->number; - } - - if (!silent) - printf("- Creating isam-file\n"); - - bzero((char*) &create_info,sizeof(create_info)); - create_info.max_rows=10000000; - - if (mi_create(filename, - 1, /* keys */ - keyinfo, - 1+2*ndims+opt_unique, /* columns */ - recinfo,uniques,&uniquedef,&create_info,create_flag)) - goto err; - - if (!silent) - printf("- Open isam-file\n"); - - if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) - goto err; - - if (!silent) - printf("- Writing key:s\n"); - - for (i=0; i<nrecords; i++ ) - { - create_record(record,i); - error=mi_write(file,record); - print_record(record,mi_position(file),"\n"); - if (!error) - { - row_count++; - } - else - { - printf("mi_write: %d\n", error); - goto err; - } - } - - if ((error=read_with_pos(file,silent))) - goto err; - - if (!silent) - printf("- Reading rows with key\n"); - - for (i=0 ; i < nrecords ; i++) - { - my_errno=0; - create_record(record,i); - - bzero((char*) read_record,MAX_REC_LENGTH); - error=mi_rkey(file,read_record,0,record+1,0,HA_READ_MBR_EQUAL); - - if (error && error!=HA_ERR_KEY_NOT_FOUND) - { - printf(" mi_rkey: %3d errno: %3d\n",error,my_errno); - goto err; - } - if (error == HA_ERR_KEY_NOT_FOUND) - { - print_record(record,mi_position(file)," NOT FOUND\n"); - continue; - } - print_record(read_record,mi_position(file),"\n"); - } - - if (!silent) - printf("- Deleting rows\n"); - for (i=0; i < nrecords/4; i++) - { - my_errno=0; - bzero((char*) read_record,MAX_REC_LENGTH); - error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR); - if (error) - { - printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno); - goto err; - } - print_record(read_record,mi_position(file),"\n"); - - error=mi_delete(file,read_record); - if (error) - { - printf("pos: %2d mi_delete: %3d errno: %3d\n",i,error,my_errno); - goto err; - } - } - - if (!silent) - printf("- Updating rows with position\n"); - for (i=0; i < (nrecords - nrecords/4) ; i++) - { - my_errno=0; - bzero((char*) read_record,MAX_REC_LENGTH); - error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR); - if (error) - { - if (error==HA_ERR_RECORD_DELETED) - continue; - printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno); - goto err; - } - print_record(read_record,mi_position(file),""); - create_record(record,i+nrecords*upd); - printf("\t-> "); - print_record(record,mi_position(file),"\n"); - error=mi_update(file,read_record,record); - if (error) - { - printf("pos: %2d mi_update: %3d errno: %3d\n",i,error,my_errno); - goto err; - } - } - - if ((error=read_with_pos(file,silent))) - goto err; - - if (!silent) - printf("- Test mi_rkey then a sequence of mi_rnext_same\n"); - - create_record(record, nrecords*4/5); - print_record(record,0," search for\n"); - - if ((error=mi_rkey(file,read_record,0,record+1,0,HA_READ_MBR_INTERSECT))) - { - printf("mi_rkey: %3d errno: %3d\n",error,my_errno); - goto err; - } - print_record(read_record,mi_position(file)," mi_rkey\n"); - row_count=1; - - for (;;) - { - if ((error=mi_rnext_same(file,read_record))) - { - if (error==HA_ERR_END_OF_FILE) - break; - printf("mi_next: %3d errno: %3d\n",error,my_errno); - goto err; - } - print_record(read_record,mi_position(file)," mi_rnext_same\n"); - row_count++; - } - printf(" %d rows\n",row_count); - - if (!silent) - printf("- Test mi_rfirst then a sequence of mi_rnext\n"); - - error=mi_rfirst(file,read_record,0); - if (error) - { - printf("mi_rfirst: %3d errno: %3d\n",error,my_errno); - goto err; - } - row_count=1; - print_record(read_record,mi_position(file)," mi_frirst\n"); - - for (i=0;i<nrecords;i++) - { - if ((error=mi_rnext(file,read_record,0))) - { - if (error==HA_ERR_END_OF_FILE) - break; - printf("mi_next: %3d errno: %3d\n",error,my_errno); - goto err; - } - print_record(read_record,mi_position(file)," mi_rnext\n"); - row_count++; - } - printf(" %d rows\n",row_count); - - if (!silent) - printf("- Test mi_records_in_range()\n"); - - create_record1(record, nrecords*4/5); - print_record(record,0,"\n"); - - range.key= record+1; - range.length= 1000; /* Big enough */ - range.flag= HA_READ_MBR_INTERSECT; - hrows= mi_records_in_range(file,0, &range, (key_range*) 0); - printf(" %ld rows\n", (long) hrows); - - if (mi_close(file)) goto err; - my_end(MY_CHECK_ERROR); - - return 0; - -err: - printf("got error: %3d when using myisam-database\n",my_errno); - return 1; /* skip warning */ -} - - - -static int read_with_pos (MI_INFO * file,int silent) -{ - int error; - int i; - char read_record[MAX_REC_LENGTH]; - - if (!silent) - printf("- Reading rows with position\n"); - for (i=0;;i++) - { - my_errno=0; - bzero((char*) read_record,MAX_REC_LENGTH); - error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR); - if (error) - { - if (error==HA_ERR_END_OF_FILE) - break; - if (error==HA_ERR_RECORD_DELETED) - continue; - printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno); - return error; - } - print_record(read_record,mi_position(file),"\n"); - } - return 0; -} - - -#ifdef NOT_USED -static void bprint_record(char * record, - my_off_t offs __attribute__((unused)), - const char * tail) -{ - int i; - char * pos; - i=(unsigned char)record[0]; - printf("%02X ",i); - - for( pos=record+1, i=0; i<32; i++,pos++){ - int b=(unsigned char)*pos; - printf("%02X",b); - } - printf("%s",tail); -} -#endif - - -static void print_record(char * record, - my_off_t offs __attribute__((unused)), - const char * tail) -{ - int i; - char * pos; - double c; - - printf(" rec=(%d)",(unsigned char)record[0]); - for ( pos=record+1, i=0; i<2*ndims; i++) - { - memcpy(&c,pos,sizeof(c)); - float8get(c,pos); - printf(" %.14g ",c); - pos+=sizeof(c); - } - printf("pos=%ld",(long int)offs); - printf("%s",tail); -} - - - -static void create_record1(char *record,uint rownr) -{ - int i; - char * pos; - double c=rownr+10; - - bzero((char*) record,MAX_REC_LENGTH); - record[0]=0x01; /* DEL marker */ - - for ( pos=record+1, i=0; i<2*ndims; i++) - { - memcpy(pos,&c,sizeof(c)); - float8store(pos,c); - pos+=sizeof(c); - } -} - -#ifdef NOT_USED - -static void create_record0(char *record,uint rownr) -{ - int i; - char * pos; - double c=rownr+10; - double c0=0; - - bzero((char*) record,MAX_REC_LENGTH); - record[0]=0x01; /* DEL marker */ - - for ( pos=record+1, i=0; i<ndims; i++) - { - memcpy(pos,&c0,sizeof(c0)); - float8store(pos,c0); - pos+=sizeof(c0); - memcpy(pos,&c,sizeof(c)); - float8store(pos,c); - pos+=sizeof(c); - } -} - -#endif - -static void create_record(char *record,uint rownr) -{ - int i; - char *pos; - double *data= rt_data+rownr*4; - record[0]=0x01; /* DEL marker */ - for ( pos=record+1, i=0; i<ndims*2; i++) - { - float8store(pos,data[i]); - pos+=8; - } -} - -#else -int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) -{ - exit(0); -} -#endif /*HAVE_RTREE_KEYS*/ diff --git a/myisam/sort.c b/myisam/sort.c deleted file mode 100644 index 9d2af2e8c70..00000000000 --- a/myisam/sort.c +++ /dev/null @@ -1,1017 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Creates a index for a database by reading keys, sorting them and outputing - them in sorted order through SORT_INFO functions. -*/ - -#include "fulltext.h" -#if defined(MSDOS) || defined(__WIN__) -#include <fcntl.h> -#else -#include <stddef.h> -#endif -#include <queues.h> - -/* static variables */ - -#undef MIN_SORT_MEMORY -#undef MYF_RW -#undef DISK_BUFFER_SIZE - -#define MERGEBUFF 15 -#define MERGEBUFF2 31 -#define MIN_SORT_MEMORY (4096-MALLOC_OVERHEAD) -#define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL) -#define DISK_BUFFER_SIZE (IO_SIZE*16) - - -/* - Pointers of functions for store and read keys from temp file -*/ - -extern void print_error _VARARGS((const char *fmt,...)); - -/* Functions defined in this file */ - -static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info,uint keys, - uchar **sort_keys, - DYNAMIC_ARRAY *buffpek,int *maxbuffer, - IO_CACHE *tempfile, - IO_CACHE *tempfile_for_exceptions); -static int NEAR_F write_keys(MI_SORT_PARAM *info,uchar **sort_keys, - uint count, BUFFPEK *buffpek,IO_CACHE *tempfile); -static int NEAR_F write_key(MI_SORT_PARAM *info, uchar *key, - IO_CACHE *tempfile); -static int NEAR_F write_index(MI_SORT_PARAM *info,uchar * *sort_keys, - uint count); -static int NEAR_F merge_many_buff(MI_SORT_PARAM *info,uint keys, - uchar * *sort_keys, - BUFFPEK *buffpek,int *maxbuffer, - IO_CACHE *t_file); -static uint NEAR_F read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek, - uint sort_length); -static int NEAR_F merge_buffers(MI_SORT_PARAM *info,uint keys, - IO_CACHE *from_file, IO_CACHE *to_file, - uchar * *sort_keys, BUFFPEK *lastbuff, - BUFFPEK *Fb, BUFFPEK *Tb); -static int NEAR_F merge_index(MI_SORT_PARAM *,uint,uchar **,BUFFPEK *, int, - IO_CACHE *); -static int flush_ft_buf(MI_SORT_PARAM *info); - -static int NEAR_F write_keys_varlen(MI_SORT_PARAM *info,uchar **sort_keys, - uint count, BUFFPEK *buffpek, - IO_CACHE *tempfile); -static uint NEAR_F read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek, - uint sort_length); -static int NEAR_F write_merge_key(MI_SORT_PARAM *info, IO_CACHE *to_file, - char *key, uint sort_length, uint count); -static int NEAR_F write_merge_key_varlen(MI_SORT_PARAM *info, - IO_CACHE *to_file, - char* key, uint sort_length, - uint count); -static inline int -my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, byte *bufs); - -/* - Creates a index of sorted keys - - SYNOPSIS - _create_index_by_sort() - info Sort parameters - no_messages Set to 1 if no output - sortbuff_size Size if sortbuffer to allocate - - RESULT - 0 ok - <> 0 Error -*/ - -int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, - ulong sortbuff_size) -{ - int error,maxbuffer,skr; - uint memavl,old_memavl,keys,sort_length; - DYNAMIC_ARRAY buffpek; - ha_rows records; - uchar **sort_keys; - IO_CACHE tempfile, tempfile_for_exceptions; - DBUG_ENTER("_create_index_by_sort"); - DBUG_PRINT("enter",("sort_length: %d", info->key_length)); - - if (info->keyinfo->flag & HA_VAR_LENGTH_KEY) - { - info->write_keys=write_keys_varlen; - info->read_to_buffer=read_to_buffer_varlen; - info->write_key=write_merge_key_varlen; - } - else - { - info->write_keys=write_keys; - info->read_to_buffer=read_to_buffer; - info->write_key=write_merge_key; - } - - my_b_clear(&tempfile); - my_b_clear(&tempfile_for_exceptions); - bzero((char*) &buffpek,sizeof(buffpek)); - sort_keys= (uchar **) NULL; error= 1; - maxbuffer=1; - - memavl=max(sortbuff_size,MIN_SORT_MEMORY); - records= info->sort_info->max_records; - sort_length= info->key_length; - LINT_INIT(keys); - - while (memavl >= MIN_SORT_MEMORY) - { - if ((my_off_t) (records+1)*(sort_length+sizeof(char*)) <= - (my_off_t) memavl) - keys= records+1; - else - do - { - skr=maxbuffer; - if (memavl < sizeof(BUFFPEK)*(uint) maxbuffer || - (keys=(memavl-sizeof(BUFFPEK)*(uint) maxbuffer)/ - (sort_length+sizeof(char*))) <= 1) - { - mi_check_print_error(info->sort_info->param, - "sort_buffer_size is to small"); - goto err; - } - } - while ((maxbuffer= (int) (records/(keys-1)+1)) != skr); - - if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+ - HA_FT_MAXBYTELEN, MYF(0)))) - { - if (my_init_dynamic_array(&buffpek, sizeof(BUFFPEK), maxbuffer, - maxbuffer/2)) - { - my_free((gptr) sort_keys,MYF(0)); - sort_keys= 0; - } - else - break; - } - old_memavl=memavl; - if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY) - memavl=MIN_SORT_MEMORY; - } - if (memavl < MIN_SORT_MEMORY) - { - mi_check_print_error(info->sort_info->param,"Sort buffer to small"); /* purecov: tested */ - goto err; /* purecov: tested */ - } - (*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */ - - if (!no_messages) - printf(" - Searching for keys, allocating buffer for %d keys\n",keys); - - if ((records=find_all_keys(info,keys,sort_keys,&buffpek,&maxbuffer, - &tempfile,&tempfile_for_exceptions)) - == HA_POS_ERROR) - goto err; /* purecov: tested */ - if (maxbuffer == 0) - { - if (!no_messages) - printf(" - Dumping %lu keys\n", (ulong) records); - if (write_index(info,sort_keys, (uint) records)) - goto err; /* purecov: inspected */ - } - else - { - keys=(keys*(sort_length+sizeof(char*)))/sort_length; - if (maxbuffer >= MERGEBUFF2) - { - if (!no_messages) - printf(" - Merging %lu keys\n", (ulong) records); /* purecov: tested */ - if (merge_many_buff(info,keys,sort_keys, - dynamic_element(&buffpek,0,BUFFPEK *),&maxbuffer,&tempfile)) - goto err; /* purecov: inspected */ - } - if (flush_io_cache(&tempfile) || - reinit_io_cache(&tempfile,READ_CACHE,0L,0,0)) - goto err; /* purecov: inspected */ - if (!no_messages) - printf(" - Last merge and dumping keys\n"); /* purecov: tested */ - if (merge_index(info,keys,sort_keys,dynamic_element(&buffpek,0,BUFFPEK *), - maxbuffer,&tempfile)) - goto err; /* purecov: inspected */ - } - - if (flush_ft_buf(info) || flush_pending_blocks(info)) - goto err; - - if (my_b_inited(&tempfile_for_exceptions)) - { - MI_INFO *index=info->sort_info->info; - uint keyno=info->key; - uint key_length, ref_length=index->s->rec_reflength; - - if (!no_messages) - printf(" - Adding exceptions\n"); /* purecov: tested */ - if (flush_io_cache(&tempfile_for_exceptions) || - reinit_io_cache(&tempfile_for_exceptions,READ_CACHE,0L,0,0)) - goto err; - - while (!my_b_read(&tempfile_for_exceptions,(byte*)&key_length, - sizeof(key_length)) - && !my_b_read(&tempfile_for_exceptions,(byte*)sort_keys, - (uint) key_length)) - { - if (_mi_ck_write(index,keyno,(uchar*) sort_keys,key_length-ref_length)) - goto err; - } - } - - error =0; - -err: - if (sort_keys) - my_free((gptr) sort_keys,MYF(0)); - delete_dynamic(&buffpek); - close_cached_file(&tempfile); - close_cached_file(&tempfile_for_exceptions); - - DBUG_RETURN(error ? -1 : 0); -} /* _create_index_by_sort */ - - -/* Search after all keys and place them in a temp. file */ - -static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys, - uchar **sort_keys, DYNAMIC_ARRAY *buffpek, - int *maxbuffer, IO_CACHE *tempfile, - IO_CACHE *tempfile_for_exceptions) -{ - int error; - uint idx; - DBUG_ENTER("find_all_keys"); - - idx=error=0; - sort_keys[0]=(uchar*) (sort_keys+keys); - - while (!(error=(*info->key_read)(info,sort_keys[idx]))) - { - if (info->real_key_length > info->key_length) - { - if (write_key(info,sort_keys[idx],tempfile_for_exceptions)) - DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */ - continue; - } - - if (++idx == keys) - { - if (info->write_keys(info,sort_keys,idx-1,(BUFFPEK *)alloc_dynamic(buffpek), - tempfile)) - DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */ - - sort_keys[0]=(uchar*) (sort_keys+keys); - memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length); - idx=1; - } - sort_keys[idx]=sort_keys[idx-1]+info->key_length; - } - if (error > 0) - DBUG_RETURN(HA_POS_ERROR); /* Aborted by get_key */ /* purecov: inspected */ - if (buffpek->elements) - { - if (info->write_keys(info,sort_keys,idx,(BUFFPEK *)alloc_dynamic(buffpek), - tempfile)) - DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */ - *maxbuffer=buffpek->elements-1; - } - else - *maxbuffer=0; - - DBUG_RETURN((*maxbuffer)*(keys-1)+idx); -} /* find_all_keys */ - - -#ifdef THREAD -/* Search after all keys and place them in a temp. file */ - -pthread_handler_decl(thr_find_all_keys,arg) -{ - MI_SORT_PARAM *info= (MI_SORT_PARAM*) arg; - int error; - uint memavl,old_memavl,keys,sort_length; - uint idx, maxbuffer; - uchar **sort_keys=0; - - LINT_INIT(keys); - - error=1; - - if (my_thread_init()) - goto err; - if (info->sort_info->got_error) - goto err; - - if (info->keyinfo->flag && HA_VAR_LENGTH_KEY) - { - info->write_keys=write_keys_varlen; - info->read_to_buffer=read_to_buffer_varlen; - info->write_key=write_merge_key_varlen; - } - else - { - info->write_keys=write_keys; - info->read_to_buffer=read_to_buffer; - info->write_key=write_merge_key; - } - - my_b_clear(&info->tempfile); - my_b_clear(&info->tempfile_for_exceptions); - bzero((char*) &info->buffpek,sizeof(info->buffpek)); - bzero((char*) &info->unique, sizeof(info->unique)); - sort_keys= (uchar **) NULL; - - memavl=max(info->sortbuff_size, MIN_SORT_MEMORY); - idx= info->sort_info->max_records; - sort_length= info->key_length; - maxbuffer= 1; - - while (memavl >= MIN_SORT_MEMORY) - { - if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= - (my_off_t) memavl) - keys= idx+1; - else - { - uint skr; - do - { - skr=maxbuffer; - if (memavl < sizeof(BUFFPEK)*maxbuffer || - (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ - (sort_length+sizeof(char*))) <= 1) - { - mi_check_print_error(info->sort_info->param, - "sort_buffer_size is to small"); - goto err; - } - } - while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr); - } - if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+ - ((info->keyinfo->flag & HA_FULLTEXT) ? - HA_FT_MAXBYTELEN : 0), MYF(0)))) - { - if (my_init_dynamic_array(&info->buffpek, sizeof(BUFFPEK), - maxbuffer, maxbuffer/2)) - my_free((gptr) sort_keys,MYF(0)); - else - break; - } - old_memavl=memavl; - if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY) - memavl=MIN_SORT_MEMORY; - } - if (memavl < MIN_SORT_MEMORY) - { - mi_check_print_error(info->sort_info->param,"Sort buffer to small"); /* purecov: tested */ - goto err; /* purecov: tested */ - } - - if (info->sort_info->param->testflag & T_VERBOSE) - printf("Key %d - Allocating buffer for %d keys\n",info->key+1,keys); - info->sort_keys=sort_keys; - - idx=error=0; - sort_keys[0]=(uchar*) (sort_keys+keys); - - while (!(error=info->sort_info->got_error) && - !(error=(*info->key_read)(info,sort_keys[idx]))) - { - if (info->real_key_length > info->key_length) - { - if (write_key(info,sort_keys[idx], &info->tempfile_for_exceptions)) - goto err; - continue; - } - - if (++idx == keys) - { - if (info->write_keys(info,sort_keys,idx-1, - (BUFFPEK *)alloc_dynamic(&info->buffpek), - &info->tempfile)) - goto err; - sort_keys[0]=(uchar*) (sort_keys+keys); - memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length); - idx=1; - } - sort_keys[idx]=sort_keys[idx-1]+info->key_length; - } - if (error > 0) - goto err; - if (info->buffpek.elements) - { - if (info->write_keys(info,sort_keys, idx, - (BUFFPEK *) alloc_dynamic(&info->buffpek), &info->tempfile)) - goto err; - info->keys=(info->buffpek.elements-1)*(keys-1)+idx; - } - else - info->keys=idx; - - info->sort_keys_length=keys; - goto ok; - -err: - info->sort_info->got_error=1; /* no need to protect this with a mutex */ - if (sort_keys) - my_free((gptr) sort_keys,MYF(0)); - info->sort_keys=0; - delete_dynamic(& info->buffpek); - close_cached_file(&info->tempfile); - close_cached_file(&info->tempfile_for_exceptions); - -ok: - remove_io_thread(&info->read_cache); - pthread_mutex_lock(&info->sort_info->mutex); - info->sort_info->threads_running--; - pthread_cond_signal(&info->sort_info->cond); - pthread_mutex_unlock(&info->sort_info->mutex); - my_thread_end(); - return NULL; -} - - -int thr_write_keys(MI_SORT_PARAM *sort_param) -{ - SORT_INFO *sort_info=sort_param->sort_info; - MI_CHECK *param=sort_info->param; - ulong length, keys; - ulong *rec_per_key_part=param->rec_per_key_part; - int got_error=sort_info->got_error; - uint i; - MI_INFO *info=sort_info->info; - MYISAM_SHARE *share=info->s; - MI_SORT_PARAM *sinfo; - byte *mergebuf=0; - LINT_INIT(length); - - for (i= 0, sinfo= sort_param ; - i < sort_info->total_keys ; - i++, rec_per_key_part+=sinfo->keyinfo->keysegs, sinfo++) - { - if (!sinfo->sort_keys) - { - got_error=1; - continue; - } - if (!got_error) - { - share->state.key_map|=(ulonglong) 1 << sinfo->key; - if (param->testflag & T_STATISTICS) - update_key_parts(sinfo->keyinfo, rec_per_key_part, - sinfo->unique, (ulonglong) info->state->records); - if (!sinfo->buffpek.elements) - { - if (param->testflag & T_VERBOSE) - { - printf("Key %d - Dumping %u keys\n",sinfo->key+1, sinfo->keys); - fflush(stdout); - } - if (write_index(sinfo, sinfo->sort_keys, sinfo->keys) || - flush_ft_buf(sinfo) || flush_pending_blocks(sinfo)) - got_error=1; - } - } - my_free((gptr) sinfo->sort_keys,MYF(0)); - my_free(mi_get_rec_buff_ptr(info, sinfo->rec_buff), - MYF(MY_ALLOW_ZERO_PTR)); - sinfo->sort_keys=0; - } - - for (i= 0, sinfo= sort_param ; - i < sort_info->total_keys ; - i++, - delete_dynamic(&sinfo->buffpek), - close_cached_file(&sinfo->tempfile), - close_cached_file(&sinfo->tempfile_for_exceptions), - sinfo++) - { - if (got_error) - continue; - if (sinfo->keyinfo->flag && HA_VAR_LENGTH_KEY) - { - sinfo->write_keys=write_keys_varlen; - sinfo->read_to_buffer=read_to_buffer_varlen; - sinfo->write_key=write_merge_key_varlen; - } - else - { - sinfo->write_keys=write_keys; - sinfo->read_to_buffer=read_to_buffer; - sinfo->write_key=write_merge_key; - } - if (sinfo->buffpek.elements) - { - uint maxbuffer=sinfo->buffpek.elements-1; - if (!mergebuf) - { - length=param->sort_buffer_length; - while (length >= MIN_SORT_MEMORY && !mergebuf) - { - mergebuf=my_malloc(length, MYF(0)); - length=length*3/4; - } - if (!mergebuf) - { - got_error=1; - continue; - } - } - keys=length/sinfo->key_length; - if (maxbuffer >= MERGEBUFF2) - { - if (param->testflag & T_VERBOSE) - printf("Key %d - Merging %u keys\n",sinfo->key+1, sinfo->keys); - if (merge_many_buff(sinfo, keys, (uchar **)mergebuf, - dynamic_element(&sinfo->buffpek, 0, BUFFPEK *), - (int*) &maxbuffer, &sinfo->tempfile)) - { - got_error=1; - continue; - } - } - if (flush_io_cache(&sinfo->tempfile) || - reinit_io_cache(&sinfo->tempfile,READ_CACHE,0L,0,0)) - { - got_error=1; - continue; - } - if (param->testflag & T_VERBOSE) - printf("Key %d - Last merge and dumping keys\n", sinfo->key+1); - if (merge_index(sinfo, keys, (uchar **)mergebuf, - dynamic_element(&sinfo->buffpek,0,BUFFPEK *), - maxbuffer,&sinfo->tempfile) || - flush_ft_buf(sinfo) || - flush_pending_blocks(sinfo)) - { - got_error=1; - continue; - } - } - if (my_b_inited(&sinfo->tempfile_for_exceptions)) - { - uint key_length; - - if (param->testflag & T_VERBOSE) - printf("Key %d - Dumping 'long' keys\n", sinfo->key+1); - - if (flush_io_cache(&sinfo->tempfile_for_exceptions) || - reinit_io_cache(&sinfo->tempfile_for_exceptions,READ_CACHE,0L,0,0)) - { - got_error=1; - continue; - } - - while (!got_error && - !my_b_read(&sinfo->tempfile_for_exceptions,(byte*)&key_length, - sizeof(key_length)) && - !my_b_read(&sinfo->tempfile_for_exceptions,(byte*)mergebuf, - (uint) key_length)) - { - if (_mi_ck_write(info,sinfo->key,(uchar*) mergebuf, - key_length - info->s->rec_reflength)) - got_error=1; - } - } - } - my_free((gptr) mergebuf,MYF(MY_ALLOW_ZERO_PTR)); - return got_error; -} -#endif /* THREAD */ - - /* Write all keys in memory to file for later merge */ - -static int NEAR_F write_keys(MI_SORT_PARAM *info, register uchar **sort_keys, - uint count, BUFFPEK *buffpek, IO_CACHE *tempfile) -{ - uchar **end; - uint sort_length=info->key_length; - DBUG_ENTER("write_keys"); - - qsort2((byte*) sort_keys,count,sizeof(byte*),(qsort2_cmp) info->key_cmp, - info); - if (!my_b_inited(tempfile) && - open_cached_file(tempfile, my_tmpdir(info->tmpdir), "ST", - DISK_BUFFER_SIZE, info->sort_info->param->myf_rw)) - DBUG_RETURN(1); /* purecov: inspected */ - - buffpek->file_pos=my_b_tell(tempfile); - buffpek->count=count; - - for (end=sort_keys+count ; sort_keys != end ; sort_keys++) - { - if (my_b_write(tempfile,(byte*) *sort_keys,(uint) sort_length)) - DBUG_RETURN(1); /* purecov: inspected */ - } - DBUG_RETURN(0); -} /* write_keys */ - - -static inline int -my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, byte *bufs) -{ - int err; - uint16 len = _mi_keylength(info->keyinfo, (uchar*) bufs); - - /* The following is safe as this is a local file */ - if ((err= my_b_write(to_file, (byte*)&len, sizeof(len)))) - return (err); - if ((err= my_b_write(to_file,bufs, (uint) len))) - return (err); - return (0); -} - - -static int NEAR_F write_keys_varlen(MI_SORT_PARAM *info, - register uchar **sort_keys, - uint count, BUFFPEK *buffpek, - IO_CACHE *tempfile) -{ - uchar **end; - int err; - DBUG_ENTER("write_keys_varlen"); - - qsort2((byte*) sort_keys,count,sizeof(byte*),(qsort2_cmp) info->key_cmp, - info); - if (!my_b_inited(tempfile) && - open_cached_file(tempfile, my_tmpdir(info->tmpdir), "ST", - DISK_BUFFER_SIZE, info->sort_info->param->myf_rw)) - DBUG_RETURN(1); /* purecov: inspected */ - - buffpek->file_pos=my_b_tell(tempfile); - buffpek->count=count; - for (end=sort_keys+count ; sort_keys != end ; sort_keys++) - { - if ((err= my_var_write(info,tempfile, (byte*) *sort_keys))) - DBUG_RETURN(err); - } - DBUG_RETURN(0); -} /* write_keys_varlen */ - - -static int NEAR_F write_key(MI_SORT_PARAM *info, uchar *key, - IO_CACHE *tempfile) -{ - uint key_length=info->real_key_length; - DBUG_ENTER("write_key"); - - if (!my_b_inited(tempfile) && - open_cached_file(tempfile, my_tmpdir(info->tmpdir), "ST", - DISK_BUFFER_SIZE, info->sort_info->param->myf_rw)) - DBUG_RETURN(1); - - if (my_b_write(tempfile,(byte*)&key_length,sizeof(key_length)) || - my_b_write(tempfile,(byte*)key,(uint) key_length)) - DBUG_RETURN(1); - DBUG_RETURN(0); -} /* write_key */ - - -/* Write index */ - -static int NEAR_F write_index(MI_SORT_PARAM *info, register uchar **sort_keys, - register uint count) -{ - DBUG_ENTER("write_index"); - - qsort2((gptr) sort_keys,(size_t) count,sizeof(byte*), - (qsort2_cmp) info->key_cmp,info); - while (count--) - { - if ((*info->key_write)(info,*sort_keys++)) - DBUG_RETURN(-1); /* purecov: inspected */ - } - DBUG_RETURN(0); -} /* write_index */ - - - /* Merge buffers to make < MERGEBUFF2 buffers */ - -static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys, - uchar **sort_keys, BUFFPEK *buffpek, - int *maxbuffer, IO_CACHE *t_file) -{ - register int i; - IO_CACHE t_file2, *from_file, *to_file, *temp; - BUFFPEK *lastbuff; - DBUG_ENTER("merge_many_buff"); - - if (*maxbuffer < MERGEBUFF2) - DBUG_RETURN(0); /* purecov: inspected */ - if (flush_io_cache(t_file) || - open_cached_file(&t_file2,my_tmpdir(info->tmpdir),"ST", - DISK_BUFFER_SIZE, info->sort_info->param->myf_rw)) - DBUG_RETURN(1); /* purecov: inspected */ - - from_file= t_file ; to_file= &t_file2; - while (*maxbuffer >= MERGEBUFF2) - { - reinit_io_cache(from_file,READ_CACHE,0L,0,0); - reinit_io_cache(to_file,WRITE_CACHE,0L,0,0); - lastbuff=buffpek; - for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF) - { - if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++, - buffpek+i,buffpek+i+MERGEBUFF-1)) - break; /* purecov: inspected */ - } - if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++, - buffpek+i,buffpek+ *maxbuffer)) - break; /* purecov: inspected */ - if (flush_io_cache(to_file)) - break; /* purecov: inspected */ - temp=from_file; from_file=to_file; to_file=temp; - *maxbuffer= (int) (lastbuff-buffpek)-1; - } - close_cached_file(to_file); /* This holds old result */ - if (to_file == t_file) - *t_file=t_file2; /* Copy result file */ - - DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */ -} /* merge_many_buff */ - - -/* - Read data to buffer - - SYNOPSIS - read_to_buffer() - fromfile File to read from - buffpek Where to read from - sort_length max length to read - RESULT - > 0 Ammount of bytes read - -1 Error -*/ - -static uint NEAR_F read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek, - uint sort_length) -{ - register uint count; - uint length; - - if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count))) - { - if (my_pread(fromfile->file,(byte*) buffpek->base, - (length= sort_length*count),buffpek->file_pos,MYF_RW)) - return((uint) -1); /* purecov: inspected */ - buffpek->key=buffpek->base; - buffpek->file_pos+= length; /* New filepos */ - buffpek->count-= count; - buffpek->mem_count= count; - } - return (count*sort_length); -} /* read_to_buffer */ - -static uint NEAR_F read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek, - uint sort_length) -{ - register uint count; - uint16 length_of_key = 0; - uint idx; - uchar *buffp; - - if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count))) - { - buffp = buffpek->base; - - for (idx=1;idx<=count;idx++) - { - if (my_pread(fromfile->file,(byte*)&length_of_key,sizeof(length_of_key), - buffpek->file_pos,MYF_RW)) - return((uint) -1); - buffpek->file_pos+=sizeof(length_of_key); - if (my_pread(fromfile->file,(byte*) buffp,length_of_key, - buffpek->file_pos,MYF_RW)) - return((uint) -1); - buffpek->file_pos+=length_of_key; - buffp = buffp + sort_length; - } - buffpek->key=buffpek->base; - buffpek->count-= count; - buffpek->mem_count= count; - } - return (count*sort_length); -} /* read_to_buffer_varlen */ - - -static int NEAR_F write_merge_key_varlen(MI_SORT_PARAM *info, - IO_CACHE *to_file,char* key, - uint sort_length, uint count) -{ - uint idx; - - char *bufs = key; - for (idx=1;idx<=count;idx++) - { - int err; - if ((err= my_var_write(info,to_file, (byte*) bufs))) - return (err); - bufs=bufs+sort_length; - } - return(0); -} - - -static int NEAR_F write_merge_key(MI_SORT_PARAM *info __attribute__((unused)), - IO_CACHE *to_file, char* key, - uint sort_length, uint count) -{ - return my_b_write(to_file,(byte*) key,(uint) sort_length*count); -} - -/* - Merge buffers to one buffer - If to_file == 0 then use info->key_write -*/ - -static int NEAR_F -merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file, - IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff, - BUFFPEK *Fb, BUFFPEK *Tb) -{ - int error; - uint sort_length,maxcount; - ha_rows count; - my_off_t to_start_filepos; - uchar *strpos; - BUFFPEK *buffpek,**refpek; - QUEUE queue; - volatile int *killed= killed_ptr(info->sort_info->param); - - DBUG_ENTER("merge_buffers"); - - count=error=0; - maxcount=keys/((uint) (Tb-Fb) +1); - LINT_INIT(to_start_filepos); - if (to_file) - to_start_filepos=my_b_tell(to_file); - strpos=(uchar*) sort_keys; - sort_length=info->key_length; - - if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0, - (int (*)(void*, byte *,byte*)) info->key_cmp, - (void*) info)) - DBUG_RETURN(1); /* purecov: inspected */ - - for (buffpek= Fb ; buffpek <= Tb ; buffpek++) - { - count+= buffpek->count; - buffpek->base= strpos; - buffpek->max_keys=maxcount; - strpos+= (uint) (error=(int) info->read_to_buffer(from_file,buffpek, - sort_length)); - if (error == -1) - goto err; /* purecov: inspected */ - queue_insert(&queue,(char*) buffpek); - } - - while (queue.elements > 1) - { - for (;;) - { - if (*killed) - { - error=1; goto err; - } - buffpek=(BUFFPEK*) queue_top(&queue); - if (to_file) - { - if (info->write_key(info,to_file,(byte*) buffpek->key, - (uint) sort_length,1)) - { - error=1; goto err; /* purecov: inspected */ - } - } - else - { - if ((*info->key_write)(info,(void*) buffpek->key)) - { - error=1; goto err; /* purecov: inspected */ - } - } - buffpek->key+=sort_length; - if (! --buffpek->mem_count) - { - if (!(error=(int) info->read_to_buffer(from_file,buffpek,sort_length))) - { - uchar *base=buffpek->base; - uint max_keys=buffpek->max_keys; - - VOID(queue_remove(&queue,0)); - - /* Put room used by buffer to use in other buffer */ - for (refpek= (BUFFPEK**) &queue_top(&queue); - refpek <= (BUFFPEK**) &queue_end(&queue); - refpek++) - { - buffpek= *refpek; - if (buffpek->base+buffpek->max_keys*sort_length == base) - { - buffpek->max_keys+=max_keys; - break; - } - else if (base+max_keys*sort_length == buffpek->base) - { - buffpek->base=base; - buffpek->max_keys+=max_keys; - break; - } - } - break; /* One buffer have been removed */ - } - } - else if (error == -1) - goto err; /* purecov: inspected */ - queue_replaced(&queue); /* Top element has been replaced */ - } - } - buffpek=(BUFFPEK*) queue_top(&queue); - buffpek->base=(uchar *) sort_keys; - buffpek->max_keys=keys; - do - { - if (to_file) - { - if (info->write_key(info,to_file,(byte*) buffpek->key, - sort_length,buffpek->mem_count)) - { - error=1; goto err; /* purecov: inspected */ - } - } - else - { - register uchar *end; - strpos= buffpek->key; - for (end=strpos+buffpek->mem_count*sort_length; - strpos != end ; - strpos+=sort_length) - { - if ((*info->key_write)(info,(void*) strpos)) - { - error=1; goto err; /* purecov: inspected */ - } - } - } - } - while ((error=(int) info->read_to_buffer(from_file,buffpek,sort_length)) != -1 && - error != 0); - - lastbuff->count=count; - if (to_file) - lastbuff->file_pos=to_start_filepos; -err: - delete_queue(&queue); - DBUG_RETURN(error); -} /* merge_buffers */ - - - /* Do a merge to output-file (save only positions) */ - -static int NEAR_F -merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys, - BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile) -{ - DBUG_ENTER("merge_index"); - if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek, - buffpek+maxbuffer)) - DBUG_RETURN(1); /* purecov: inspected */ - DBUG_RETURN(0); -} /* merge_index */ - -static int -flush_ft_buf(MI_SORT_PARAM *info) -{ - int err=0; - if (info->sort_info->ft_buf) - { - err=sort_ft_buf_flush(info); - my_free((gptr)info->sort_info->ft_buf, MYF(0)); - info->sort_info->ft_buf=0; - } - return err; -} - diff --git a/myisam/sp_defs.h b/myisam/sp_defs.h deleted file mode 100644 index 4cc2267a1bd..00000000000 --- a/myisam/sp_defs.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin & MySQL Finland AB - & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#ifndef _SP_DEFS_H -#define _SP_DEFS_H - -#define SPDIMS 2 -#define SPTYPE HA_KEYTYPE_DOUBLE -#define SPLEN 8 - -#ifdef HAVE_SPATIAL - -enum wkbType -{ - wkbPoint = 1, - wkbLineString = 2, - wkbPolygon = 3, - wkbMultiPoint = 4, - wkbMultiLineString = 5, - wkbMultiPolygon = 6, - wkbGeometryCollection = 7 -}; - -enum wkbByteOrder -{ - wkbXDR = 0, /* Big Endian */ - wkbNDR = 1 /* Little Endian */ -}; - -uint sp_make_key(register MI_INFO *info, uint keynr, uchar *key, - const byte *record, my_off_t filepos); - -#endif /*HAVE_SPATIAL*/ -#endif /* _SP_DEFS_H */ diff --git a/myisam/sp_key.c b/myisam/sp_key.c deleted file mode 100644 index b61e8094cde..00000000000 --- a/myisam/sp_key.c +++ /dev/null @@ -1,296 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "myisamdef.h" - -#ifdef HAVE_SPATIAL - -#include "sp_defs.h" - -static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims, - uchar byte_order, double *mbr); -static int sp_get_point_mbr(uchar *(*wkb), uchar *end, uint n_dims, - uchar byte_order, double *mbr); -static int sp_get_linestring_mbr(uchar *(*wkb), uchar *end, uint n_dims, - uchar byte_order, double *mbr); -static int sp_get_polygon_mbr(uchar *(*wkb), uchar *end, uint n_dims, - uchar byte_order, double *mbr); -static int sp_get_geometry_mbr(uchar *(*wkb), uchar *end, uint n_dims, - double *mbr, int top); -static int sp_mbr_from_wkb(uchar (*wkb), uint size, uint n_dims, double *mbr); - - -uint sp_make_key(register MI_INFO *info, uint keynr, uchar *key, - const byte *record, my_off_t filepos) -{ - HA_KEYSEG *keyseg; - MI_KEYDEF *keyinfo = &info->s->keyinfo[keynr]; - uint len = 0; - byte *pos; - uint dlen; - uchar *dptr; - double mbr[SPDIMS * 2]; - uint i; - - keyseg = &keyinfo->seg[-1]; - pos = (byte*)record + keyseg->start; - - dlen = _mi_calc_blob_length(keyseg->bit_start, pos); - memcpy_fixed(&dptr, pos + keyseg->bit_start, sizeof(char*)); - if (!dptr) - { - my_errno= HA_ERR_NULL_IN_SPATIAL; - return 0; - } - sp_mbr_from_wkb(dptr + 4, dlen - 4, SPDIMS, mbr); /* SRID */ - - for (i = 0, keyseg = keyinfo->seg; keyseg->type; keyseg++, i++) - { - uint length = keyseg->length; - - pos = ((byte*)mbr) + keyseg->start; - if (keyseg->flag & HA_SWAP_KEY) - { -#ifdef HAVE_ISNAN - if (keyseg->type == HA_KEYTYPE_FLOAT) - { - float nr; - float4get(nr, pos); - if (isnan(nr)) - { - /* Replace NAN with zero */ - bzero(key, length); - key+= length; - continue; - } - } - else if (keyseg->type == HA_KEYTYPE_DOUBLE) - { - double nr; - float8get(nr, pos); - if (isnan(nr)) - { - bzero(key, length); - key+= length; - continue; - } - } -#endif - pos += length; - while (length--) - { - *key++ = *--pos; - } - } - else - { - memcpy((byte*)key, pos, length); - key += keyseg->length; - } - len += keyseg->length; - } - _mi_dpointer(info, key, filepos); - return len; -} - -/* -Calculate minimal bounding rectangle (mbr) of the spatial object -stored in "well-known binary representation" (wkb) format. -*/ -static int sp_mbr_from_wkb(uchar *wkb, uint size, uint n_dims, double *mbr) -{ - uint i; - - for (i=0; i < n_dims; ++i) - { - mbr[i * 2] = DBL_MAX; - mbr[i * 2 + 1] = -DBL_MAX; - } - - return sp_get_geometry_mbr(&wkb, wkb + size, n_dims, mbr, 1); -} - -/* - Add one point stored in wkb to mbr -*/ - -static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims, - uchar byte_order __attribute__((unused)), - double *mbr) -{ - double ord; - double *mbr_end= mbr + n_dims * 2; - - while (mbr < mbr_end) - { - if ((*wkb) > end - 8) - return -1; - float8get(ord, (*wkb)); - (*wkb)+= 8; - if (ord < *mbr) - float8store((char*) mbr, ord); - mbr++; - if (ord > *mbr) - float8store((char*) mbr, ord); - mbr++; - } - return 0; -} - - -static int sp_get_point_mbr(uchar *(*wkb), uchar *end, uint n_dims, - uchar byte_order, double *mbr) -{ - return sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr); -} - - -static int sp_get_linestring_mbr(uchar *(*wkb), uchar *end, uint n_dims, - uchar byte_order, double *mbr) -{ - uint n_points; - - n_points = uint4korr(*wkb); - (*wkb) += 4; - for (; n_points > 0; --n_points) - { - /* Add next point to mbr */ - if (sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr)) - return -1; - } - return 0; -} - - -static int sp_get_polygon_mbr(uchar *(*wkb), uchar *end, uint n_dims, - uchar byte_order, double *mbr) -{ - uint n_linear_rings; - uint n_points; - - n_linear_rings = uint4korr((*wkb)); - (*wkb) += 4; - - for (; n_linear_rings > 0; --n_linear_rings) - { - n_points = uint4korr((*wkb)); - (*wkb) += 4; - for (; n_points > 0; --n_points) - { - /* Add next point to mbr */ - if (sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr)) - return -1; - } - } - return 0; -} - -static int sp_get_geometry_mbr(uchar *(*wkb), uchar *end, uint n_dims, - double *mbr, int top) -{ - int res; - uchar byte_order; - uint wkb_type; - - byte_order = *(*wkb); - ++(*wkb); - - wkb_type = uint4korr((*wkb)); - (*wkb) += 4; - - switch ((enum wkbType) wkb_type) - { - case wkbPoint: - res = sp_get_point_mbr(wkb, end, n_dims, byte_order, mbr); - break; - case wkbLineString: - res = sp_get_linestring_mbr(wkb, end, n_dims, byte_order, mbr); - break; - case wkbPolygon: - res = sp_get_polygon_mbr(wkb, end, n_dims, byte_order, mbr); - break; - case wkbMultiPoint: - { - uint n_items; - n_items = uint4korr((*wkb)); - (*wkb) += 4; - for (; n_items > 0; --n_items) - { - byte_order = *(*wkb); - ++(*wkb); - (*wkb) += 4; - if (sp_get_point_mbr(wkb, end, n_dims, byte_order, mbr)) - return -1; - } - res = 0; - break; - } - case wkbMultiLineString: - { - uint n_items; - n_items = uint4korr((*wkb)); - (*wkb) += 4; - for (; n_items > 0; --n_items) - { - byte_order = *(*wkb); - ++(*wkb); - (*wkb) += 4; - if (sp_get_linestring_mbr(wkb, end, n_dims, byte_order, mbr)) - return -1; - } - res = 0; - break; - } - case wkbMultiPolygon: - { - uint n_items; - n_items = uint4korr((*wkb)); - (*wkb) += 4; - for (; n_items > 0; --n_items) - { - byte_order = *(*wkb); - ++(*wkb); - (*wkb) += 4; - if (sp_get_polygon_mbr(wkb, end, n_dims, byte_order, mbr)) - return -1; - } - res = 0; - break; - } - case wkbGeometryCollection: - { - uint n_items; - - if (!top) - return -1; - - n_items = uint4korr((*wkb)); - (*wkb) += 4; - for (; n_items > 0; --n_items) - { - if (sp_get_geometry_mbr(wkb, end, n_dims, mbr, 0)) - return -1; - } - res = 0; - break; - } - default: - res = -1; - } - return res; -} - -#endif /*HAVE_SPATIAL*/ diff --git a/myisam/sp_test.c b/myisam/sp_test.c deleted file mode 100644 index f0b48dbd5d8..00000000000 --- a/myisam/sp_test.c +++ /dev/null @@ -1,565 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Testing of the basic functions of a MyISAM spatial table */ -/* Written by Alex Barkov, who has a shared copyright to this code */ - -#include "myisam.h" - -#ifdef HAVE_SPATIAL -#include "sp_defs.h" - -#define MAX_REC_LENGTH 1024 -#define KEYALG HA_KEY_ALG_RTREE - -static void create_linestring(char *record,uint rownr); -static void print_record(char * record,my_off_t offs,const char * tail); - -static void create_key(char *key,uint rownr); -static void print_key(const char *key,const char * tail); - -static int run_test(const char *filename); -static int read_with_pos(MI_INFO * file, int silent); - -static int rtree_CreateLineStringWKB(double *ords, uint n_dims, uint n_points, - uchar *wkb); -static void rtree_PrintWKB(uchar *wkb, uint n_dims); - -static char blob_key[MAX_REC_LENGTH]; - - -int main(int argc __attribute__((unused)),char *argv[]) -{ - MY_INIT(argv[0]); - exit(run_test("sp_test")); -} - - -int run_test(const char *filename) -{ - MI_INFO *file; - MI_UNIQUEDEF uniquedef; - MI_CREATE_INFO create_info; - MI_COLUMNDEF recinfo[20]; - MI_KEYDEF keyinfo[20]; - HA_KEYSEG keyseg[20]; - key_range min_range, max_range; - int silent=0; - int create_flag=0; - int null_fields=0; - int nrecords=30; - int uniques=0; - int i; - int error; - int row_count=0; - char record[MAX_REC_LENGTH]; - char key[MAX_REC_LENGTH]; - char read_record[MAX_REC_LENGTH]; - int upd=10; - ha_rows hrows; - - /* Define a column for NULLs and DEL markers*/ - - recinfo[0].type=FIELD_NORMAL; - recinfo[0].length=1; /* For NULL bits */ - - - /* Define spatial column */ - - recinfo[1].type=FIELD_BLOB; - recinfo[1].length=4 + mi_portable_sizeof_char_ptr; - - - - /* Define a key with 1 spatial segment */ - - keyinfo[0].seg=keyseg; - keyinfo[0].keysegs=1; - keyinfo[0].flag=HA_SPATIAL; - keyinfo[0].key_alg=KEYALG; - - keyinfo[0].seg[0].type= HA_KEYTYPE_BINARY; - keyinfo[0].seg[0].flag=0; - keyinfo[0].seg[0].start= 1; - keyinfo[0].seg[0].length=1; /* Spatial ignores it anyway */ - keyinfo[0].seg[0].null_bit= null_fields ? 2 : 0; - keyinfo[0].seg[0].null_pos=0; - keyinfo[0].seg[0].language=default_charset_info->number; - keyinfo[0].seg[0].bit_start=4; /* Long BLOB */ - - - if (!silent) - printf("- Creating isam-file\n"); - - bzero((char*) &create_info,sizeof(create_info)); - create_info.max_rows=10000000; - - if (mi_create(filename, - 1, /* keys */ - keyinfo, - 2, /* columns */ - recinfo,uniques,&uniquedef,&create_info,create_flag)) - goto err; - - if (!silent) - printf("- Open isam-file\n"); - - if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) - goto err; - - if (!silent) - printf("- Writing key:s\n"); - - for (i=0; i<nrecords; i++ ) - { - create_linestring(record,i); - error=mi_write(file,record); - print_record(record,mi_position(file),"\n"); - if (!error) - { - row_count++; - } - else - { - printf("mi_write: %d\n", error); - goto err; - } - } - - if ((error=read_with_pos(file,silent))) - goto err; - - if (!silent) - printf("- Deleting rows with position\n"); - for (i=0; i < nrecords/4; i++) - { - my_errno=0; - bzero((char*) read_record,MAX_REC_LENGTH); - error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR); - if (error) - { - printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno); - goto err; - } - print_record(read_record,mi_position(file),"\n"); - error=mi_delete(file,read_record); - if (error) - { - printf("pos: %2d mi_delete: %3d errno: %3d\n",i,error,my_errno); - goto err; - } - } - - if (!silent) - printf("- Updating rows with position\n"); - for (i=0; i < nrecords/2 ; i++) - { - my_errno=0; - bzero((char*) read_record,MAX_REC_LENGTH); - error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR); - if (error) - { - if (error==HA_ERR_RECORD_DELETED) - continue; - printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno); - goto err; - } - print_record(read_record,mi_position(file),""); - create_linestring(record,i+nrecords*upd); - printf("\t-> "); - print_record(record,mi_position(file),"\n"); - error=mi_update(file,read_record,record); - if (error) - { - printf("pos: %2d mi_update: %3d errno: %3d\n",i,error,my_errno); - goto err; - } - } - - if ((error=read_with_pos(file,silent))) - goto err; - - if (!silent) - printf("- Test mi_rkey then a sequence of mi_rnext_same\n"); - - create_key(key, nrecords*4/5); - print_key(key," search for INTERSECT\n"); - - if ((error=mi_rkey(file,read_record,0,key,0,HA_READ_MBR_INTERSECT))) - { - printf("mi_rkey: %3d errno: %3d\n",error,my_errno); - goto err; - } - print_record(read_record,mi_position(file)," mi_rkey\n"); - row_count=1; - - for (;;) - { - if ((error=mi_rnext_same(file,read_record))) - { - if (error==HA_ERR_END_OF_FILE) - break; - printf("mi_next: %3d errno: %3d\n",error,my_errno); - goto err; - } - print_record(read_record,mi_position(file)," mi_rnext_same\n"); - row_count++; - } - printf(" %d rows\n",row_count); - - if (!silent) - printf("- Test mi_rfirst then a sequence of mi_rnext\n"); - - error=mi_rfirst(file,read_record,0); - if (error) - { - printf("mi_rfirst: %3d errno: %3d\n",error,my_errno); - goto err; - } - row_count=1; - print_record(read_record,mi_position(file)," mi_frirst\n"); - - for(i=0;i<nrecords;i++) { - if ((error=mi_rnext(file,read_record,0))) - { - if (error==HA_ERR_END_OF_FILE) - break; - printf("mi_next: %3d errno: %3d\n",error,my_errno); - goto err; - } - print_record(read_record,mi_position(file)," mi_rnext\n"); - row_count++; - } - printf(" %d rows\n",row_count); - - if (!silent) - printf("- Test mi_records_in_range()\n"); - - create_key(key, nrecords*upd); - print_key(key," INTERSECT\n"); - min_range.key= key; - min_range.length= 1000; /* Big enough */ - min_range.flag= HA_READ_MBR_INTERSECT; - max_range.key= record+1; - max_range.length= 1000; /* Big enough */ - max_range.flag= HA_READ_KEY_EXACT; - hrows= mi_records_in_range(file,0, &min_range, &max_range); - printf(" %ld rows\n", (long) hrows); - - if (mi_close(file)) goto err; - my_end(MY_CHECK_ERROR); - return 0; - -err: - printf("got error: %3d when using myisam-database\n",my_errno); - return 1; /* skip warning */ -} - - -static int read_with_pos (MI_INFO * file,int silent) -{ - int error; - int i; - char read_record[MAX_REC_LENGTH]; - int rows=0; - - if (!silent) - printf("- Reading rows with position\n"); - for (i=0;;i++) - { - my_errno=0; - bzero((char*) read_record,MAX_REC_LENGTH); - error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR); - if (error) - { - if (error==HA_ERR_END_OF_FILE) - break; - if (error==HA_ERR_RECORD_DELETED) - continue; - printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno); - return error; - } - rows++; - print_record(read_record,mi_position(file),"\n"); - } - printf(" %d rows\n",rows); - return 0; -} - - -#ifdef NOT_USED -static void bprint_record(char * record, - my_off_t offs __attribute__((unused)), - const char * tail) -{ - int i; - char * pos; - i=(unsigned char)record[0]; - printf("%02X ",i); - - for( pos=record+1, i=0; i<32; i++,pos++) - { - int b=(unsigned char)*pos; - printf("%02X",b); - } - printf("%s",tail); -} -#endif - - -static void print_record(char * record, my_off_t offs,const char * tail) -{ - char *pos; - char *ptr; - uint len; - - printf(" rec=(%d)",(unsigned char)record[0]); - pos=record+1; - len=sint4korr(pos); - pos+=4; - printf(" len=%d ",len); - memcpy_fixed(&ptr,pos,sizeof(char*)); - if (ptr) - rtree_PrintWKB((uchar*) ptr,SPDIMS); - else - printf("<NULL> "); - printf(" offs=%ld ",(long int)offs); - printf("%s",tail); -} - - -#ifdef NOT_USED -static void create_point(char *record,uint rownr) -{ - uint tmp; - char *ptr; - char *pos=record; - double x[200]; - int i; - - for(i=0;i<SPDIMS;i++) - x[i]=rownr; - - bzero((char*) record,MAX_REC_LENGTH); - *pos=0x01; /* DEL marker */ - pos++; - - memset(blob_key,0,sizeof(blob_key)); - tmp=rtree_CreatePointWKB(x,SPDIMS,blob_key); - - int4store(pos,tmp); - pos+=4; - - ptr=blob_key; - memcpy_fixed(pos,&ptr,sizeof(char*)); -} -#endif - - -static void create_linestring(char *record,uint rownr) -{ - uint tmp; - char *ptr; - char *pos=record; - double x[200]; - int i,j; - int npoints=2; - - for(j=0;j<npoints;j++) - for(i=0;i<SPDIMS;i++) - x[i+j*SPDIMS]=rownr*j; - - bzero((char*) record,MAX_REC_LENGTH); - *pos=0x01; /* DEL marker */ - pos++; - - memset(blob_key,0,sizeof(blob_key)); - tmp=rtree_CreateLineStringWKB(x,SPDIMS,npoints, (uchar*) blob_key); - - int4store(pos,tmp); - pos+=4; - - ptr=blob_key; - memcpy_fixed(pos,&ptr,sizeof(char*)); -} - - -static void create_key(char *key,uint rownr) -{ - double c=rownr; - char *pos; - uint i; - - bzero(key,MAX_REC_LENGTH); - for ( pos=key, i=0; i<2*SPDIMS; i++) - { - float8store(pos,c); - pos+=sizeof(c); - } -} - -static void print_key(const char *key,const char * tail) -{ - double c; - uint i; - - printf(" key="); - for (i=0; i<2*SPDIMS; i++) - { - float8get(c,key); - key+=sizeof(c); - printf("%.14g ",c); - } - printf("%s",tail); -} - - -#ifdef NOT_USED - -static int rtree_CreatePointWKB(double *ords, uint n_dims, uchar *wkb) -{ - uint i; - - *wkb = wkbXDR; - ++wkb; - int4store(wkb, wkbPoint); - wkb += 4; - - for (i=0; i < n_dims; ++i) - { - float8store(wkb, ords[i]); - wkb += 8; - } - return 5 + n_dims * 8; -} -#endif - - -static int rtree_CreateLineStringWKB(double *ords, uint n_dims, uint n_points, - uchar *wkb) -{ - uint i; - uint n_ords = n_dims * n_points; - - *wkb = wkbXDR; - ++wkb; - int4store(wkb, wkbLineString); - wkb += 4; - int4store(wkb, n_points); - wkb += 4; - for (i=0; i < n_ords; ++i) - { - float8store(wkb, ords[i]); - wkb += 8; - } - return 9 + n_points * n_dims * 8; -} - - -static void rtree_PrintWKB(uchar *wkb, uint n_dims) -{ - uint wkb_type; - - ++wkb; - wkb_type = uint4korr(wkb); - wkb += 4; - - switch ((enum wkbType)wkb_type) - { - case wkbPoint: - { - uint i; - double ord; - - printf("POINT("); - for (i=0; i < n_dims; ++i) - { - float8get(ord, wkb); - wkb += 8; - printf("%.14g", ord); - if (i < n_dims - 1) - printf(" "); - else - printf(")"); - } - break; - } - case wkbLineString: - { - uint p, i; - uint n_points; - double ord; - - printf("LineString("); - n_points = uint4korr(wkb); - wkb += 4; - for (p=0; p < n_points; ++p) - { - for (i=0; i < n_dims; ++i) - { - float8get(ord, wkb); - wkb += 8; - printf("%.14g", ord); - if (i < n_dims - 1) - printf(" "); - } - if (p < n_points - 1) - printf(", "); - else - printf(")"); - } - break; - } - case wkbPolygon: - { - printf("POLYGON(...)"); - break; - } - case wkbMultiPoint: - { - printf("MULTIPOINT(...)"); - break; - } - case wkbMultiLineString: - { - printf("MULTILINESTRING(...)"); - break; - } - case wkbMultiPolygon: - { - printf("MULTIPOLYGON(...)"); - break; - } - case wkbGeometryCollection: - { - printf("GEOMETRYCOLLECTION(...)"); - break; - } - default: - { - printf("UNKNOWN GEOMETRY TYPE"); - break; - } - } -} - -#else -int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) -{ - exit(0); -} -#endif /*HAVE_SPATIAL*/ - diff --git a/myisam/test_pack b/myisam/test_pack deleted file mode 100755 index 0cbeb57ba70..00000000000 --- a/myisam/test_pack +++ /dev/null @@ -1,9 +0,0 @@ -silent="-s" -suffix=$MACH -mi_test1$MACH -s ; myisampack$MACH --force -s test1 ; myisamchk$MACH -es test1 ; myisamchk$MACH -rqs test1 ; myisamchk$MACH -es test1 ; myisamchk$MACH -us test1 ; myisamchk$MACH -es test1 -mi_test1$MACH -s -S ; myisampack$MACH --force -s test1 ; myisamchk$MACH -es test1 ; myisamchk$MACH -rqs test1 ; myisamchk$MACH -es test1 ;myisamchk$MACH -us test1 ; myisamchk$MACH -es test1 -mi_test1$MACH -s -b ; myisampack$MACH --force -s test1 ; myisamchk$MACH -es test1 ; myisamchk$MACH -rqs test1 ; myisamchk$MACH -es test1 -mi_test1$MACH -s -w ; myisampack$MACH --force -s test1 ; myisamchk$MACH -es test1 ; myisamchk$MACH -ros test1 ; myisamchk$MACH -es test1 - -mi_test2$MACH -s -t4 ; myisampack$MACH --force -s test2 ; myisamchk$MACH -es test2 ; myisamchk$MACH -ros test2 ; myisamchk$MACH -es test2 ; myisamchk$MACH -s -u test2 ; myisamchk$MACH -sm test2 -mi_test2$MACH -s -t4 -b -N ; myisampack$MACH --force -s test2 ; myisamchk$MACH -es test2 ; myisamchk$MACH -ros test2 ; myisamchk$MACH -es test2 ; myisamchk$MACH -s -u test2 ; myisamchk$MACH -sm test2 |