location.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. /*
  11. Package util contains utility functions for slot headers.
  12. Packing and unpacking of slot sizes
  13. The package contains functions to pack/unpack sizes for physical slots and
  14. logical buckets. The size info is a 4 byte value which allocates 2 bytes
  15. for current size and 2 bytes for available size.
  16. CCCC CCCC CCCC CCCC AAAA AAAA AAAA AAAA
  17. The allocated size value is a packed integer using a 2 bit multiplier
  18. in the beginning - using these packed values a slot can grow up to
  19. 138681822 bytes (138 MB). The space allocation becomes more and more
  20. wasteful with increasing slot size. The current size is stored as a
  21. difference to the allocated size. The maximum difference between
  22. alloacted and current space is 65534 bytes.
  23. Packing and unpacking locations
  24. The package contains utility functions to pack and unpack location information
  25. in an uint64. A location is a pointer which identifies a specific record and
  26. within the record a specific offset.
  27. The 8 byte uint64 value is split into a 6 byte (48 bits) record address and
  28. 2 byte offset.
  29. RRRR RRRR RRRR RRRR RRRR RRRR RRRR RRRR RRRR RRRR RRRR RRRR OOOO OOOO OOOO OOOO
  30. We can address at maximum (having a record size of 32767 bytes):
  31. (2^48 / 2 - 1) * 32767 = 4.61154528 * 10^18 which is around 4 exabyte
  32. Considering a default page size of 4096 bytes we can address:
  33. (2^48 / 2 - 1) * 4096 = 5.76460752 * 10^17 which is around 512 petabyte
  34. */
  35. package util
  36. import "devt.de/krotik/eliasdb/storage/file"
  37. /*
  38. LocationSize is the size of a location in bytes
  39. */
  40. const LocationSize = file.SizeLong
  41. /*
  42. MaxRecordValue is the maximum record value (2^48 / 2 - 1)
  43. 6 byte = 48 bits
  44. */
  45. const MaxRecordValue = 0xFFFFFF
  46. /*
  47. MaxOffsetValue is the maximum offset value for a location (32767).
  48. */
  49. const MaxOffsetValue = 0xFFFF
  50. /*
  51. LocationRecord retirms the record id from a location.
  52. */
  53. func LocationRecord(location uint64) uint64 {
  54. return uint64(location >> 16)
  55. }
  56. /*
  57. LocationOffset returns the offset from a location.
  58. */
  59. func LocationOffset(location uint64) uint16 {
  60. return uint16(location & 0xffff)
  61. }
  62. /*
  63. PackLocation packs location information into an uint64.
  64. */
  65. func PackLocation(recordID uint64, offset uint16) uint64 {
  66. if offset == 0xFFFF && recordID == 0xFFFFFF {
  67. return 0xFFFFFFFF
  68. }
  69. if recordID > MaxRecordValue {
  70. panic("Cannot create location with record id greater than 0xFFFFFF")
  71. }
  72. return (recordID << 16) + uint64(offset)
  73. }