sequence.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. // Package bitseq provides a structure and utilities for representing long bitmask
  2. // as sequence of run-lenght encoded blocks. It operates direclty on the encoded
  3. // representation, it does not decode/encode.
  4. package bitseq
  5. import (
  6. "fmt"
  7. "sync"
  8. "github.com/docker/libnetwork/datastore"
  9. "github.com/docker/libnetwork/netutils"
  10. )
  11. // Block Sequence constants
  12. // If needed we can think of making these configurable
  13. const (
  14. blockLen = 32
  15. blockBytes = blockLen / 8
  16. blockMAX = 1<<blockLen - 1
  17. blockFirstBit = 1 << (blockLen - 1)
  18. )
  19. // Handle contains the sequece representing the bitmask and its identifier
  20. type Handle struct {
  21. bits uint32
  22. unselected uint32
  23. head *Sequence
  24. app string
  25. id string
  26. dbIndex uint64
  27. dbExists bool
  28. store datastore.DataStore
  29. sync.Mutex
  30. }
  31. // NewHandle returns a thread-safe instance of the bitmask handler
  32. func NewHandle(app string, ds datastore.DataStore, id string, numElements uint32) (*Handle, error) {
  33. h := &Handle{
  34. app: app,
  35. id: id,
  36. store: ds,
  37. bits: numElements,
  38. unselected: numElements,
  39. head: &Sequence{
  40. Block: 0x0,
  41. Count: getNumBlocks(numElements),
  42. },
  43. }
  44. if h.store == nil {
  45. return h, nil
  46. }
  47. // Register for status changes
  48. h.watchForChanges()
  49. // Get the initial status from the ds if present.
  50. err := h.store.GetObject(datastore.Key(h.Key()...), h)
  51. if err != datastore.ErrKeyNotFound {
  52. return nil, err
  53. }
  54. return h, err
  55. }
  56. // Sequence reresents a recurring sequence of 32 bits long bitmasks
  57. type Sequence struct {
  58. Block uint32 // block representing 4 byte long allocation bitmask
  59. Count uint32 // number of consecutive blocks
  60. Next *Sequence // next sequence
  61. }
  62. // NewSequence returns a sequence initialized to represent a bitmaks of numElements bits
  63. func NewSequence(numElements uint32) *Sequence {
  64. return &Sequence{Block: 0x0, Count: getNumBlocks(numElements), Next: nil}
  65. }
  66. // String returns a string representation of the block sequence starting from this block
  67. func (s *Sequence) String() string {
  68. var nextBlock string
  69. if s.Next == nil {
  70. nextBlock = "end"
  71. } else {
  72. nextBlock = s.Next.String()
  73. }
  74. return fmt.Sprintf("(0x%x, %d)->%s", s.Block, s.Count, nextBlock)
  75. }
  76. // GetAvailableBit returns the position of the first unset bit in the bitmask represented by this sequence
  77. func (s *Sequence) GetAvailableBit() (bytePos, bitPos int) {
  78. if s.Block == blockMAX || s.Count == 0 {
  79. return -1, -1
  80. }
  81. bits := 0
  82. bitSel := uint32(blockFirstBit)
  83. for bitSel > 0 && s.Block&bitSel != 0 {
  84. bitSel >>= 1
  85. bits++
  86. }
  87. return bits / 8, bits % 8
  88. }
  89. // GetCopy returns a copy of the linked list rooted at this node
  90. func (s *Sequence) GetCopy() *Sequence {
  91. n := &Sequence{Block: s.Block, Count: s.Count}
  92. pn := n
  93. ps := s.Next
  94. for ps != nil {
  95. pn.Next = &Sequence{Block: ps.Block, Count: ps.Count}
  96. pn = pn.Next
  97. ps = ps.Next
  98. }
  99. return n
  100. }
  101. // Equal checks if this sequence is equal to the passed one
  102. func (s *Sequence) Equal(o *Sequence) bool {
  103. this := s
  104. other := o
  105. for this != nil {
  106. if other == nil {
  107. return false
  108. }
  109. if this.Block != other.Block || this.Count != other.Count {
  110. return false
  111. }
  112. this = this.Next
  113. other = other.Next
  114. }
  115. // Check if other is longer than this
  116. if other != nil {
  117. return false
  118. }
  119. return true
  120. }
  121. // ToByteArray converts the sequence into a byte array
  122. // TODO (aboch): manage network/host order stuff
  123. func (s *Sequence) ToByteArray() ([]byte, error) {
  124. var bb []byte
  125. p := s
  126. for p != nil {
  127. bb = append(bb, netutils.U32ToA(p.Block)...)
  128. bb = append(bb, netutils.U32ToA(p.Count)...)
  129. p = p.Next
  130. }
  131. return bb, nil
  132. }
  133. // FromByteArray construct the sequence from the byte array
  134. // TODO (aboch): manage network/host order stuff
  135. func (s *Sequence) FromByteArray(data []byte) error {
  136. l := len(data)
  137. if l%8 != 0 {
  138. return fmt.Errorf("cannot deserialize byte sequence of lenght %d (%v)", l, data)
  139. }
  140. p := s
  141. i := 0
  142. for {
  143. p.Block = netutils.ATo32(data[i : i+4])
  144. p.Count = netutils.ATo32(data[i+4 : i+8])
  145. i += 8
  146. if i == l {
  147. break
  148. }
  149. p.Next = &Sequence{}
  150. p = p.Next
  151. }
  152. return nil
  153. }
  154. // GetFirstAvailable returns the byte and bit position of the first unset bit
  155. func (h *Handle) GetFirstAvailable() (int, int, error) {
  156. h.Lock()
  157. defer h.Unlock()
  158. return GetFirstAvailable(h.head)
  159. }
  160. // CheckIfAvailable checks if the bit correspondent to the specified ordinal is unset
  161. // If the ordinal is beyond the Sequence limits, a negative response is returned
  162. func (h *Handle) CheckIfAvailable(ordinal int) (int, int, error) {
  163. h.Lock()
  164. defer h.Unlock()
  165. return CheckIfAvailable(h.head, ordinal)
  166. }
  167. // PushReservation pushes the bit reservation inside the bitmask.
  168. func (h *Handle) PushReservation(bytePos, bitPos int, release bool) error {
  169. // Create a copy of the current handler
  170. h.Lock()
  171. nh := &Handle{
  172. app: h.app,
  173. id: h.id,
  174. store: h.store,
  175. dbIndex: h.dbIndex,
  176. head: h.head.GetCopy(),
  177. dbExists: h.dbExists,
  178. }
  179. h.Unlock()
  180. nh.head = PushReservation(bytePos, bitPos, nh.head, release)
  181. err := nh.writeToStore()
  182. if err == nil {
  183. // Commit went through, save locally
  184. h.Lock()
  185. h.head = nh.head
  186. if release {
  187. h.unselected++
  188. } else {
  189. h.unselected--
  190. }
  191. // Can't use SetIndex() since we're locked.
  192. h.dbIndex = nh.Index()
  193. h.dbExists = true
  194. h.Unlock()
  195. }
  196. return err
  197. }
  198. // Destroy removes from the datastore the data belonging to this handle
  199. func (h *Handle) Destroy() {
  200. h.deleteFromStore()
  201. }
  202. // ToByteArray converts this handle's data into a byte array
  203. func (h *Handle) ToByteArray() ([]byte, error) {
  204. ba := make([]byte, 8)
  205. h.Lock()
  206. defer h.Unlock()
  207. copy(ba[0:4], netutils.U32ToA(h.bits))
  208. copy(ba[4:8], netutils.U32ToA(h.unselected))
  209. bm, err := h.head.ToByteArray()
  210. if err != nil {
  211. return nil, fmt.Errorf("failed to serialize head: %s", err.Error())
  212. }
  213. ba = append(ba, bm...)
  214. return ba, nil
  215. }
  216. // FromByteArray reads his handle's data from a byte array
  217. func (h *Handle) FromByteArray(ba []byte) error {
  218. if ba == nil {
  219. return fmt.Errorf("nil byte array")
  220. }
  221. nh := &Sequence{}
  222. err := nh.FromByteArray(ba[8:])
  223. if err != nil {
  224. return fmt.Errorf("failed to deserialize head: %s", err.Error())
  225. }
  226. h.Lock()
  227. h.head = nh
  228. h.bits = netutils.ATo32(ba[0:4])
  229. h.unselected = netutils.ATo32(ba[4:8])
  230. h.Unlock()
  231. return nil
  232. }
  233. // Bits returns the length of the bit sequence
  234. func (h *Handle) Bits() uint32 {
  235. return h.bits
  236. }
  237. // Unselected returns the number of bits which are not selected
  238. func (h *Handle) Unselected() uint32 {
  239. h.Lock()
  240. defer h.Unlock()
  241. return h.unselected
  242. }
  243. // GetFirstAvailable looks for the first unset bit in passed mask
  244. func GetFirstAvailable(head *Sequence) (int, int, error) {
  245. byteIndex := 0
  246. current := head
  247. for current != nil {
  248. if current.Block != blockMAX {
  249. bytePos, bitPos := current.GetAvailableBit()
  250. return byteIndex + bytePos, bitPos, nil
  251. }
  252. byteIndex += int(current.Count * blockBytes)
  253. current = current.Next
  254. }
  255. return -1, -1, fmt.Errorf("no bit available")
  256. }
  257. // CheckIfAvailable checks if the bit correspondent to the specified ordinal is unset
  258. // If the ordinal is beyond the Sequence limits, a negative response is returned
  259. func CheckIfAvailable(head *Sequence, ordinal int) (int, int, error) {
  260. bytePos := ordinal / 8
  261. bitPos := ordinal % 8
  262. // Find the Sequence containing this byte
  263. current, _, _, inBlockBytePos := findSequence(head, bytePos)
  264. if current != nil {
  265. // Check whether the bit corresponding to the ordinal address is unset
  266. bitSel := uint32(blockFirstBit >> uint(inBlockBytePos*8+bitPos))
  267. if current.Block&bitSel == 0 {
  268. return bytePos, bitPos, nil
  269. }
  270. }
  271. return -1, -1, fmt.Errorf("requested bit is not available")
  272. }
  273. // Given the byte position and the sequences list head, return the pointer to the
  274. // sequence containing the byte (current), the pointer to the previous sequence,
  275. // the number of blocks preceding the block containing the byte inside the current sequence.
  276. // If bytePos is outside of the list, function will return (nil, nil, 0, -1)
  277. func findSequence(head *Sequence, bytePos int) (*Sequence, *Sequence, uint32, int) {
  278. // Find the Sequence containing this byte
  279. previous := head
  280. current := head
  281. n := bytePos
  282. for current.Next != nil && n >= int(current.Count*blockBytes) { // Nil check for less than 32 addresses masks
  283. n -= int(current.Count * blockBytes)
  284. previous = current
  285. current = current.Next
  286. }
  287. // If byte is outside of the list, let caller know
  288. if n >= int(current.Count*blockBytes) {
  289. return nil, nil, 0, -1
  290. }
  291. // Find the byte position inside the block and the number of blocks
  292. // preceding the block containing the byte inside this sequence
  293. precBlocks := uint32(n / blockBytes)
  294. inBlockBytePos := bytePos % blockBytes
  295. return current, previous, precBlocks, inBlockBytePos
  296. }
  297. // PushReservation pushes the bit reservation inside the bitmask.
  298. // Given byte and bit positions, identify the sequence (current) which holds the block containing the affected bit.
  299. // Create a new block with the modified bit according to the operation (allocate/release).
  300. // Create a new Sequence containing the new Block and insert it in the proper position.
  301. // Remove current sequence if empty.
  302. // Check if new Sequence can be merged with neighbour (previous/Next) sequences.
  303. //
  304. //
  305. // Identify "current" Sequence containing block:
  306. // [prev seq] [current seq] [Next seq]
  307. //
  308. // Based on block position, resulting list of sequences can be any of three forms:
  309. //
  310. // Block position Resulting list of sequences
  311. // A) Block is first in current: [prev seq] [new] [modified current seq] [Next seq]
  312. // B) Block is last in current: [prev seq] [modified current seq] [new] [Next seq]
  313. // C) Block is in the middle of current: [prev seq] [curr pre] [new] [curr post] [Next seq]
  314. func PushReservation(bytePos, bitPos int, head *Sequence, release bool) *Sequence {
  315. // Store list's head
  316. newHead := head
  317. // Find the Sequence containing this byte
  318. current, previous, precBlocks, inBlockBytePos := findSequence(head, bytePos)
  319. if current == nil {
  320. return newHead
  321. }
  322. // Construct updated block
  323. bitSel := uint32(blockFirstBit >> uint(inBlockBytePos*8+bitPos))
  324. newBlock := current.Block
  325. if release {
  326. newBlock &^= bitSel
  327. } else {
  328. newBlock |= bitSel
  329. }
  330. // Quit if it was a redundant request
  331. if current.Block == newBlock {
  332. return newHead
  333. }
  334. // Current Sequence inevitably looses one block, upadate Count
  335. current.Count--
  336. // Create new sequence
  337. newSequence := &Sequence{Block: newBlock, Count: 1}
  338. // Insert the new sequence in the list based on block position
  339. if precBlocks == 0 { // First in sequence (A)
  340. newSequence.Next = current
  341. if current == head {
  342. newHead = newSequence
  343. previous = newHead
  344. } else {
  345. previous.Next = newSequence
  346. }
  347. removeCurrentIfEmpty(&newHead, newSequence, current)
  348. mergeSequences(previous)
  349. } else if precBlocks == current.Count-2 { // Last in sequence (B)
  350. newSequence.Next = current.Next
  351. current.Next = newSequence
  352. mergeSequences(current)
  353. } else { // In between the sequence (C)
  354. currPre := &Sequence{Block: current.Block, Count: precBlocks, Next: newSequence}
  355. currPost := current
  356. currPost.Count -= precBlocks
  357. newSequence.Next = currPost
  358. if currPost == head {
  359. newHead = currPre
  360. } else {
  361. previous.Next = currPre
  362. }
  363. // No merging or empty current possible here
  364. }
  365. return newHead
  366. }
  367. // Removes the current sequence from the list if empty, adjusting the head pointer if needed
  368. func removeCurrentIfEmpty(head **Sequence, previous, current *Sequence) {
  369. if current.Count == 0 {
  370. if current == *head {
  371. *head = current.Next
  372. } else {
  373. previous.Next = current.Next
  374. current = current.Next
  375. }
  376. }
  377. }
  378. // Given a pointer to a Sequence, it checks if it can be merged with any following sequences
  379. // It stops when no more merging is possible.
  380. // TODO: Optimization: only attempt merge from start to end sequence, no need to scan till the end of the list
  381. func mergeSequences(seq *Sequence) {
  382. if seq != nil {
  383. // Merge all what possible from seq
  384. for seq.Next != nil && seq.Block == seq.Next.Block {
  385. seq.Count += seq.Next.Count
  386. seq.Next = seq.Next.Next
  387. }
  388. // Move to Next
  389. mergeSequences(seq.Next)
  390. }
  391. }
  392. func getNumBlocks(numBits uint32) uint32 {
  393. numBlocks := numBits / blockLen
  394. if numBits%blockLen != 0 {
  395. numBlocks++
  396. }
  397. return numBlocks
  398. }