summaryrefslogtreecommitdiff
path: root/myisam
diff options
context:
space:
mode:
authorunknown <brian@zim.(none)>2005-04-26 18:19:54 -0700
committerunknown <brian@zim.(none)>2005-04-26 18:19:54 -0700
commitb7e422be1b7a8ca3f4e761e67db5e8febc701dfd (patch)
treedf9016f3d70b4657f89dcddca2ec4e188fc7fbdf /myisam
parentc0333ecee42a4de499b3377cfa21d7b5af1ddd2b (diff)
downloadmariadb-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')
-rw-r--r--myisam/.cvsignore14
-rw-r--r--myisam/ChangeLog150
-rw-r--r--myisam/Makefile.am108
-rw-r--r--myisam/NEWS66
-rw-r--r--myisam/TODO7
-rw-r--r--myisam/ft_boolean_search.c735
-rw-r--r--myisam/ft_eval.c253
-rw-r--r--myisam/ft_eval.h42
-rw-r--r--myisam/ft_nlq_search.c360
-rw-r--r--myisam/ft_parser.c249
-rw-r--r--myisam/ft_static.c628
-rw-r--r--myisam/ft_stem.c19
-rw-r--r--myisam/ft_stopwords.c129
-rw-r--r--myisam/ft_test1.c316
-rw-r--r--myisam/ft_test1.h421
-rw-r--r--myisam/ft_update.c350
-rwxr-xr-xmyisam/ftbench/Ecompare.pl96
-rwxr-xr-xmyisam/ftbench/Ecreate.pl44
-rwxr-xr-xmyisam/ftbench/Ereport.pl49
-rw-r--r--myisam/ftbench/README43
-rwxr-xr-xmyisam/ftbench/ft-test-run.sh98
-rw-r--r--myisam/ftdefs.h152
-rw-r--r--myisam/fulltext.h38
-rwxr-xr-xmyisam/make-ccc5
-rw-r--r--myisam/mi_cache.c108
-rw-r--r--myisam/mi_changed.c34
-rw-r--r--myisam/mi_check.c4082
-rw-r--r--myisam/mi_checksum.c65
-rw-r--r--myisam/mi_close.c118
-rw-r--r--myisam/mi_create.c792
-rw-r--r--myisam/mi_dbug.c193
-rw-r--r--myisam/mi_delete.c887
-rw-r--r--myisam/mi_delete_all.c72
-rw-r--r--myisam/mi_delete_table.c58
-rw-r--r--myisam/mi_dynrec.c1641
-rw-r--r--myisam/mi_extra.c405
-rw-r--r--myisam/mi_info.c140
-rw-r--r--myisam/mi_key.c574
-rw-r--r--myisam/mi_keycache.c162
-rw-r--r--myisam/mi_locking.c510
-rw-r--r--myisam/mi_log.c164
-rw-r--r--myisam/mi_open.c1270
-rw-r--r--myisam/mi_packrec.c1358
-rw-r--r--myisam/mi_page.c160
-rw-r--r--myisam/mi_panic.c114
-rw-r--r--myisam/mi_preload.c118
-rw-r--r--myisam/mi_range.c244
-rw-r--r--myisam/mi_rename.c61
-rw-r--r--myisam/mi_rfirst.c27
-rw-r--r--myisam/mi_rkey.c141
-rw-r--r--myisam/mi_rlast.c27
-rw-r--r--myisam/mi_rnext.c122
-rw-r--r--myisam/mi_rnext_same.c105
-rw-r--r--myisam/mi_rprev.c88
-rw-r--r--myisam/mi_rrnd.c60
-rw-r--r--myisam/mi_rsame.c66
-rw-r--r--myisam/mi_rsamepos.c56
-rw-r--r--myisam/mi_scan.c46
-rw-r--r--myisam/mi_search.c1829
-rw-r--r--myisam/mi_static.c63
-rw-r--r--myisam/mi_statrec.c301
-rw-r--r--myisam/mi_test1.c674
-rw-r--r--myisam/mi_test2.c1048
-rw-r--r--myisam/mi_test3.c502
-rw-r--r--myisam/mi_test_all.res53
-rwxr-xr-xmyisam/mi_test_all.sh147
-rw-r--r--myisam/mi_unique.c217
-rw-r--r--myisam/mi_update.c228
-rw-r--r--myisam/mi_write.c1003
-rw-r--r--myisam/myisam_ftdump.c277
-rw-r--r--myisam/myisamchk.c1771
-rw-r--r--myisam/myisamdef.h736
-rw-r--r--myisam/myisamlog.c845
-rw-r--r--myisam/myisampack.c2180
-rw-r--r--myisam/rt_index.c1082
-rw-r--r--myisam/rt_index.h47
-rw-r--r--myisam/rt_key.c100
-rw-r--r--myisam/rt_key.h33
-rw-r--r--myisam/rt_mbr.c801
-rw-r--r--myisam/rt_mbr.h38
-rw-r--r--myisam/rt_split.c352
-rw-r--r--myisam/rt_test.c471
-rw-r--r--myisam/sort.c1017
-rw-r--r--myisam/sp_defs.h48
-rw-r--r--myisam/sp_key.c296
-rw-r--r--myisam/sp_test.c565
-rwxr-xr-xmyisam/test_pack9
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,&param)))
- {
- 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 &#38; 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 &#38; 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*) &param->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, &not_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(&param->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(&param->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(&param->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(&param->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(&param->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(&param->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(&param->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(&param->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(&param->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(&param->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(&param->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(&param->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(&param->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(&param->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(&param->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,&not_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, &not_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,
- &not_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,&not_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,&not_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,
- &not_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,&not_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,
- &not_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(&param->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(&param->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(&param->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(&param->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 &not_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