os_fid.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1996, 1997, 1998, 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: os_fid.c,v 11.7 2000/10/26 14:17:05 bostic Exp $";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #if TIME_WITH_SYS_TIME
  15. #include <sys/time.h>
  16. #include <time.h>
  17. #else
  18. #if HAVE_SYS_TIME_H
  19. #include <sys/time.h>
  20. #else
  21. #include <time.h>
  22. #endif
  23. #endif
  24. #include <string.h>
  25. #include <unistd.h>
  26. #endif
  27. #include "db_int.h"
  28. #define SERIAL_INIT 0
  29. static u_int32_t fid_serial = SERIAL_INIT;
  30. /*
  31.  * __os_fileid --
  32.  * Return a unique identifier for a file.
  33.  *
  34.  * PUBLIC: int __os_fileid __P((DB_ENV *, const char *, int, u_int8_t *));
  35.  */
  36. int
  37. __os_fileid(dbenv, fname, unique_okay, fidp)
  38. DB_ENV *dbenv;
  39. const char *fname;
  40. int unique_okay;
  41. u_int8_t *fidp;
  42. {
  43. struct stat sb;
  44. size_t i;
  45. int ret;
  46. u_int32_t tmp;
  47. u_int8_t *p;
  48. /* Clear the buffer. */
  49. memset(fidp, 0, DB_FILE_ID_LEN);
  50. /* On POSIX/UNIX, use a dev/inode pair. */
  51. #ifdef HAVE_VXWORKS
  52. if (stat((char *)fname, &sb)) {
  53. #else
  54. if (stat(fname, &sb)) {
  55. #endif
  56. ret = __os_get_errno();
  57. __db_err(dbenv, "%s: %s", fname, strerror(ret));
  58. return (ret);
  59. }
  60. /*
  61.  * Initialize/increment the serial number we use to help avoid
  62.  * fileid collisions.  Note that we don't bother with locking;
  63.  * it's unpleasant to do from down in here, and if we race on
  64.  * this no real harm will be done, since the finished fileid
  65.  * has so many other components.
  66.  *
  67.  * We increment by 100000 on each call as a simple way of
  68.  * randomizing;  simply incrementing seems potentially less useful
  69.  * if pids are also simply incremented, since this is process-local
  70.  * and we may be one of a set of processes starting up.  100000
  71.  * pushes us out of pid space on most platforms, and has few
  72.  * interesting properties in base 2.
  73.  */
  74. if (fid_serial == SERIAL_INIT)
  75. fid_serial = (u_int32_t)getpid();
  76. else
  77. fid_serial += 100000;
  78. /*
  79.  * !!!
  80.  * Nothing is ever big enough -- on Sparc V9, st_ino, st_dev and the
  81.  * time_t types are all 8 bytes.  As DB_FILE_ID_LEN is only 20 bytes,
  82.  * we convert to a (potentially) smaller fixed-size type and use it.
  83.  *
  84.  * We don't worry about byte sexing or the actual variable sizes.
  85.  *
  86.  * When this routine is called from the DB access methods, it's only
  87.  * called once -- whatever ID is generated when a database is created
  88.  * is stored in the database file's metadata, and that is what is
  89.  * saved in the mpool region's information to uniquely identify the
  90.  * file.
  91.  *
  92.  * When called from the mpool layer this routine will be called each
  93.  * time a new thread of control wants to share the file, which makes
  94.  * things tougher.  As far as byte sexing goes, since the mpool region
  95.  * lives on a single host, there's no issue of that -- the entire
  96.  * region is byte sex dependent.  As far as variable sizes go, we make
  97.  * the simplifying assumption that 32-bit and 64-bit processes will
  98.  * get the same 32-bit values if we truncate any returned 64-bit value
  99.  * to a 32-bit value.  When we're called from the mpool layer, though,
  100.  * we need to be careful not to include anything that isn't
  101.  * reproducible for a given file, such as the timestamp or serial
  102.  * number.
  103.  */
  104. tmp = (u_int32_t)sb.st_ino;
  105. for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
  106. *fidp++ = *p++;
  107. tmp = (u_int32_t)sb.st_dev;
  108. for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
  109. *fidp++ = *p++;
  110. if (unique_okay) {
  111. /*
  112.  * We want the number of seconds, not the high-order 0 bits,
  113.  * so convert the returned time_t to a (potentially) smaller
  114.  * fixed-size type.
  115.  */
  116. tmp = (u_int32_t)time(NULL);
  117. for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
  118. *fidp++ = *p++;
  119. for (p = (u_int8_t *)&fid_serial, i = sizeof(u_int32_t);
  120.     i > 0; --i)
  121. *fidp++ = *p++;
  122. }
  123. return (0);
  124. }