sequence.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. // Package bitseq provides a structure and utilities for representing long bitmask
  2. // as sequence of run-length encoded blocks. It operates directly on the encoded
  3. // representation, it does not decode/encode.
  4. package bitseq
  5. import (
  6. "encoding/binary"
  7. "encoding/json"
  8. "fmt"
  9. "sync"
  10. "github.com/Sirupsen/logrus"
  11. "github.com/docker/libnetwork/datastore"
  12. "github.com/docker/libnetwork/types"
  13. )
  14. // block sequence constants
  15. // If needed we can think of making these configurable
  16. const (
  17. blockLen = uint32(32)
  18. blockBytes = uint64(blockLen / 8)
  19. blockMAX = uint32(1<<blockLen - 1)
  20. blockFirstBit = uint32(1) << (blockLen - 1)
  21. invalidPos = uint64(0xFFFFFFFFFFFFFFFF)
  22. )
  23. var (
  24. // ErrNoBitAvailable is returned when no more bits are available to set
  25. ErrNoBitAvailable = fmt.Errorf("no bit available")
  26. // ErrBitAllocated is returned when the specific bit requested is already set
  27. ErrBitAllocated = fmt.Errorf("requested bit is already allocated")
  28. )
  29. // Handle contains the sequece representing the bitmask and its identifier
  30. type Handle struct {
  31. bits uint64
  32. unselected uint64
  33. head *sequence
  34. app string
  35. id string
  36. dbIndex uint64
  37. dbExists bool
  38. store datastore.DataStore
  39. sync.Mutex
  40. }
  41. // NewHandle returns a thread-safe instance of the bitmask handler
  42. func NewHandle(app string, ds datastore.DataStore, id string, numElements uint64) (*Handle, error) {
  43. h := &Handle{
  44. app: app,
  45. id: id,
  46. store: ds,
  47. bits: numElements,
  48. unselected: numElements,
  49. head: &sequence{
  50. block: 0x0,
  51. count: getNumBlocks(numElements),
  52. },
  53. }
  54. if h.store == nil {
  55. return h, nil
  56. }
  57. // Get the initial status from the ds if present.
  58. if err := h.store.GetObject(datastore.Key(h.Key()...), h); err != nil && err != datastore.ErrKeyNotFound {
  59. return nil, err
  60. }
  61. // If the handle is not in store, write it.
  62. if !h.Exists() {
  63. if err := h.writeToStore(); err != nil {
  64. return nil, fmt.Errorf("failed to write bitsequence to store: %v", err)
  65. }
  66. }
  67. return h, nil
  68. }
  69. // sequence represents a recurring sequence of 32 bits long bitmasks
  70. type sequence struct {
  71. block uint32 // block is a symbol representing 4 byte long allocation bitmask
  72. count uint64 // number of consecutive blocks (symbols)
  73. next *sequence // next sequence
  74. }
  75. // String returns a string representation of the block sequence starting from this block
  76. func (s *sequence) toString() string {
  77. var nextBlock string
  78. if s.next == nil {
  79. nextBlock = "end"
  80. } else {
  81. nextBlock = s.next.toString()
  82. }
  83. return fmt.Sprintf("(0x%x, %d)->%s", s.block, s.count, nextBlock)
  84. }
  85. // GetAvailableBit returns the position of the first unset bit in the bitmask represented by this sequence
  86. func (s *sequence) getAvailableBit(from uint64) (uint64, uint64, error) {
  87. if s.block == blockMAX || s.count == 0 {
  88. return invalidPos, invalidPos, ErrNoBitAvailable
  89. }
  90. bits := from
  91. bitSel := blockFirstBit >> from
  92. for bitSel > 0 && s.block&bitSel != 0 {
  93. bitSel >>= 1
  94. bits++
  95. }
  96. return bits / 8, bits % 8, nil
  97. }
  98. // GetCopy returns a copy of the linked list rooted at this node
  99. func (s *sequence) getCopy() *sequence {
  100. n := &sequence{block: s.block, count: s.count}
  101. pn := n
  102. ps := s.next
  103. for ps != nil {
  104. pn.next = &sequence{block: ps.block, count: ps.count}
  105. pn = pn.next
  106. ps = ps.next
  107. }
  108. return n
  109. }
  110. // Equal checks if this sequence is equal to the passed one
  111. func (s *sequence) equal(o *sequence) bool {
  112. this := s
  113. other := o
  114. for this != nil {
  115. if other == nil {
  116. return false
  117. }
  118. if this.block != other.block || this.count != other.count {
  119. return false
  120. }
  121. this = this.next
  122. other = other.next
  123. }
  124. // Check if other is longer than this
  125. if other != nil {
  126. return false
  127. }
  128. return true
  129. }
  130. // ToByteArray converts the sequence into a byte array
  131. func (s *sequence) toByteArray() ([]byte, error) {
  132. var bb []byte
  133. p := s
  134. for p != nil {
  135. b := make([]byte, 12)
  136. binary.BigEndian.PutUint32(b[0:], p.block)
  137. binary.BigEndian.PutUint64(b[4:], p.count)
  138. bb = append(bb, b...)
  139. p = p.next
  140. }
  141. return bb, nil
  142. }
  143. // fromByteArray construct the sequence from the byte array
  144. func (s *sequence) fromByteArray(data []byte) error {
  145. l := len(data)
  146. if l%12 != 0 {
  147. return fmt.Errorf("cannot deserialize byte sequence of length %d (%v)", l, data)
  148. }
  149. p := s
  150. i := 0
  151. for {
  152. p.block = binary.BigEndian.Uint32(data[i : i+4])
  153. p.count = binary.BigEndian.Uint64(data[i+4 : i+12])
  154. i += 12
  155. if i == l {
  156. break
  157. }
  158. p.next = &sequence{}
  159. p = p.next
  160. }
  161. return nil
  162. }
  163. func (h *Handle) getCopy() *Handle {
  164. return &Handle{
  165. bits: h.bits,
  166. unselected: h.unselected,
  167. head: h.head.getCopy(),
  168. app: h.app,
  169. id: h.id,
  170. dbIndex: h.dbIndex,
  171. dbExists: h.dbExists,
  172. store: h.store,
  173. }
  174. }
  175. // SetAnyInRange atomically sets the first unset bit in the specified range in the sequence and returns the corresponding ordinal
  176. func (h *Handle) SetAnyInRange(start, end uint64) (uint64, error) {
  177. if end < start || end >= h.bits {
  178. return invalidPos, fmt.Errorf("invalid bit range [%d, %d]", start, end)
  179. }
  180. if h.Unselected() == 0 {
  181. return invalidPos, ErrNoBitAvailable
  182. }
  183. return h.set(0, start, end, true, false)
  184. }
  185. // SetAny atomically sets the first unset bit in the sequence and returns the corresponding ordinal
  186. func (h *Handle) SetAny() (uint64, error) {
  187. if h.Unselected() == 0 {
  188. return invalidPos, ErrNoBitAvailable
  189. }
  190. return h.set(0, 0, h.bits-1, true, false)
  191. }
  192. // Set atomically sets the corresponding bit in the sequence
  193. func (h *Handle) Set(ordinal uint64) error {
  194. if err := h.validateOrdinal(ordinal); err != nil {
  195. return err
  196. }
  197. _, err := h.set(ordinal, 0, 0, false, false)
  198. return err
  199. }
  200. // Unset atomically unsets the corresponding bit in the sequence
  201. func (h *Handle) Unset(ordinal uint64) error {
  202. if err := h.validateOrdinal(ordinal); err != nil {
  203. return err
  204. }
  205. _, err := h.set(ordinal, 0, 0, false, true)
  206. return err
  207. }
  208. // IsSet atomically checks if the ordinal bit is set. In case ordinal
  209. // is outside of the bit sequence limits, false is returned.
  210. func (h *Handle) IsSet(ordinal uint64) bool {
  211. if err := h.validateOrdinal(ordinal); err != nil {
  212. return false
  213. }
  214. h.Lock()
  215. _, _, err := checkIfAvailable(h.head, ordinal)
  216. h.Unlock()
  217. return err != nil
  218. }
  219. func (h *Handle) runConsistencyCheck() bool {
  220. corrupted := false
  221. for p, c := h.head, h.head.next; c != nil; c = c.next {
  222. if c.count == 0 {
  223. corrupted = true
  224. p.next = c.next
  225. continue // keep same p
  226. }
  227. p = c
  228. }
  229. return corrupted
  230. }
  231. // CheckConsistency checks if the bit sequence is in an inconsistent state and attempts to fix it.
  232. // It looks for a corruption signature that may happen in docker 1.9.0 and 1.9.1.
  233. func (h *Handle) CheckConsistency() error {
  234. for {
  235. h.Lock()
  236. store := h.store
  237. h.Unlock()
  238. if store != nil {
  239. if err := store.GetObject(datastore.Key(h.Key()...), h); err != nil && err != datastore.ErrKeyNotFound {
  240. return err
  241. }
  242. }
  243. h.Lock()
  244. nh := h.getCopy()
  245. h.Unlock()
  246. if !nh.runConsistencyCheck() {
  247. return nil
  248. }
  249. if err := nh.writeToStore(); err != nil {
  250. if _, ok := err.(types.RetryError); !ok {
  251. return fmt.Errorf("internal failure while fixing inconsistent bitsequence: %v", err)
  252. }
  253. continue
  254. }
  255. logrus.Infof("Fixed inconsistent bit sequence in datastore:\n%s\n%s", h, nh)
  256. h.Lock()
  257. h.head = nh.head
  258. h.Unlock()
  259. return nil
  260. }
  261. }
  262. // set/reset the bit
  263. func (h *Handle) set(ordinal, start, end uint64, any bool, release bool) (uint64, error) {
  264. var (
  265. bitPos uint64
  266. bytePos uint64
  267. ret uint64
  268. err error
  269. )
  270. for {
  271. var store datastore.DataStore
  272. h.Lock()
  273. store = h.store
  274. h.Unlock()
  275. if store != nil {
  276. if err := store.GetObject(datastore.Key(h.Key()...), h); err != nil && err != datastore.ErrKeyNotFound {
  277. return ret, err
  278. }
  279. }
  280. h.Lock()
  281. // Get position if available
  282. if release {
  283. bytePos, bitPos = ordinalToPos(ordinal)
  284. } else {
  285. if any {
  286. bytePos, bitPos, err = getFirstAvailable(h.head, start)
  287. ret = posToOrdinal(bytePos, bitPos)
  288. if end < ret {
  289. err = ErrNoBitAvailable
  290. }
  291. } else {
  292. bytePos, bitPos, err = checkIfAvailable(h.head, ordinal)
  293. ret = ordinal
  294. }
  295. }
  296. if err != nil {
  297. h.Unlock()
  298. return ret, err
  299. }
  300. // Create a private copy of h and work on it
  301. nh := h.getCopy()
  302. h.Unlock()
  303. nh.head = pushReservation(bytePos, bitPos, nh.head, release)
  304. if release {
  305. nh.unselected++
  306. } else {
  307. nh.unselected--
  308. }
  309. // Attempt to write private copy to store
  310. if err := nh.writeToStore(); err != nil {
  311. if _, ok := err.(types.RetryError); !ok {
  312. return ret, fmt.Errorf("internal failure while setting the bit: %v", err)
  313. }
  314. // Retry
  315. continue
  316. }
  317. // Previous atomic push was succesfull. Save private copy to local copy
  318. h.Lock()
  319. defer h.Unlock()
  320. h.unselected = nh.unselected
  321. h.head = nh.head
  322. h.dbExists = nh.dbExists
  323. h.dbIndex = nh.dbIndex
  324. return ret, nil
  325. }
  326. }
  327. // checks is needed because to cover the case where the number of bits is not a multiple of blockLen
  328. func (h *Handle) validateOrdinal(ordinal uint64) error {
  329. h.Lock()
  330. defer h.Unlock()
  331. if ordinal >= h.bits {
  332. return fmt.Errorf("bit does not belong to the sequence")
  333. }
  334. return nil
  335. }
  336. // Destroy removes from the datastore the data belonging to this handle
  337. func (h *Handle) Destroy() error {
  338. for {
  339. if err := h.deleteFromStore(); err != nil {
  340. if _, ok := err.(types.RetryError); !ok {
  341. return fmt.Errorf("internal failure while destroying the sequence: %v", err)
  342. }
  343. // Fetch latest
  344. if err := h.store.GetObject(datastore.Key(h.Key()...), h); err != nil {
  345. if err == datastore.ErrKeyNotFound { // already removed
  346. return nil
  347. }
  348. return fmt.Errorf("failed to fetch from store when destroying the sequence: %v", err)
  349. }
  350. continue
  351. }
  352. return nil
  353. }
  354. }
  355. // ToByteArray converts this handle's data into a byte array
  356. func (h *Handle) ToByteArray() ([]byte, error) {
  357. h.Lock()
  358. defer h.Unlock()
  359. ba := make([]byte, 16)
  360. binary.BigEndian.PutUint64(ba[0:], h.bits)
  361. binary.BigEndian.PutUint64(ba[8:], h.unselected)
  362. bm, err := h.head.toByteArray()
  363. if err != nil {
  364. return nil, fmt.Errorf("failed to serialize head: %s", err.Error())
  365. }
  366. ba = append(ba, bm...)
  367. return ba, nil
  368. }
  369. // FromByteArray reads his handle's data from a byte array
  370. func (h *Handle) FromByteArray(ba []byte) error {
  371. if ba == nil {
  372. return fmt.Errorf("nil byte array")
  373. }
  374. nh := &sequence{}
  375. err := nh.fromByteArray(ba[16:])
  376. if err != nil {
  377. return fmt.Errorf("failed to deserialize head: %s", err.Error())
  378. }
  379. h.Lock()
  380. h.head = nh
  381. h.bits = binary.BigEndian.Uint64(ba[0:8])
  382. h.unselected = binary.BigEndian.Uint64(ba[8:16])
  383. h.Unlock()
  384. return nil
  385. }
  386. // Bits returns the length of the bit sequence
  387. func (h *Handle) Bits() uint64 {
  388. return h.bits
  389. }
  390. // Unselected returns the number of bits which are not selected
  391. func (h *Handle) Unselected() uint64 {
  392. h.Lock()
  393. defer h.Unlock()
  394. return h.unselected
  395. }
  396. func (h *Handle) String() string {
  397. h.Lock()
  398. defer h.Unlock()
  399. return fmt.Sprintf("App: %s, ID: %s, DBIndex: 0x%x, bits: %d, unselected: %d, sequence: %s",
  400. h.app, h.id, h.dbIndex, h.bits, h.unselected, h.head.toString())
  401. }
  402. // MarshalJSON encodes Handle into json message
  403. func (h *Handle) MarshalJSON() ([]byte, error) {
  404. m := map[string]interface{}{
  405. "id": h.id,
  406. }
  407. b, err := h.ToByteArray()
  408. if err != nil {
  409. return nil, err
  410. }
  411. m["sequence"] = b
  412. return json.Marshal(m)
  413. }
  414. // UnmarshalJSON decodes json message into Handle
  415. func (h *Handle) UnmarshalJSON(data []byte) error {
  416. var (
  417. m map[string]interface{}
  418. b []byte
  419. err error
  420. )
  421. if err = json.Unmarshal(data, &m); err != nil {
  422. return err
  423. }
  424. h.id = m["id"].(string)
  425. bi, _ := json.Marshal(m["sequence"])
  426. if err := json.Unmarshal(bi, &b); err != nil {
  427. return err
  428. }
  429. return h.FromByteArray(b)
  430. }
  431. // getFirstAvailable looks for the first unset bit in passed mask starting from start
  432. func getFirstAvailable(head *sequence, start uint64) (uint64, uint64, error) {
  433. // Find sequence which contains the start bit
  434. byteStart, bitStart := ordinalToPos(start)
  435. current, _, _, inBlockBytePos := findSequence(head, byteStart)
  436. // Derive the this sequence offsets
  437. byteOffset := byteStart - inBlockBytePos
  438. bitOffset := inBlockBytePos*8 + bitStart
  439. for current != nil {
  440. if current.block != blockMAX {
  441. bytePos, bitPos, err := current.getAvailableBit(bitOffset)
  442. return byteOffset + bytePos, bitPos, err
  443. }
  444. // Moving to next block: Reset bit offset.
  445. bitOffset = 0
  446. byteOffset += current.count * blockBytes
  447. current = current.next
  448. }
  449. return invalidPos, invalidPos, ErrNoBitAvailable
  450. }
  451. // checkIfAvailable checks if the bit correspondent to the specified ordinal is unset
  452. // If the ordinal is beyond the sequence limits, a negative response is returned
  453. func checkIfAvailable(head *sequence, ordinal uint64) (uint64, uint64, error) {
  454. bytePos, bitPos := ordinalToPos(ordinal)
  455. // Find the sequence containing this byte
  456. current, _, _, inBlockBytePos := findSequence(head, bytePos)
  457. if current != nil {
  458. // Check whether the bit corresponding to the ordinal address is unset
  459. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  460. if current.block&bitSel == 0 {
  461. return bytePos, bitPos, nil
  462. }
  463. }
  464. return invalidPos, invalidPos, ErrBitAllocated
  465. }
  466. // Given the byte position and the sequences list head, return the pointer to the
  467. // sequence containing the byte (current), the pointer to the previous sequence,
  468. // the number of blocks preceding the block containing the byte inside the current sequence.
  469. // If bytePos is outside of the list, function will return (nil, nil, 0, invalidPos)
  470. func findSequence(head *sequence, bytePos uint64) (*sequence, *sequence, uint64, uint64) {
  471. // Find the sequence containing this byte
  472. previous := head
  473. current := head
  474. n := bytePos
  475. for current.next != nil && n >= (current.count*blockBytes) { // Nil check for less than 32 addresses masks
  476. n -= (current.count * blockBytes)
  477. previous = current
  478. current = current.next
  479. }
  480. // If byte is outside of the list, let caller know
  481. if n >= (current.count * blockBytes) {
  482. return nil, nil, 0, invalidPos
  483. }
  484. // Find the byte position inside the block and the number of blocks
  485. // preceding the block containing the byte inside this sequence
  486. precBlocks := n / blockBytes
  487. inBlockBytePos := bytePos % blockBytes
  488. return current, previous, precBlocks, inBlockBytePos
  489. }
  490. // PushReservation pushes the bit reservation inside the bitmask.
  491. // Given byte and bit positions, identify the sequence (current) which holds the block containing the affected bit.
  492. // Create a new block with the modified bit according to the operation (allocate/release).
  493. // Create a new sequence containing the new block and insert it in the proper position.
  494. // Remove current sequence if empty.
  495. // Check if new sequence can be merged with neighbour (previous/next) sequences.
  496. //
  497. //
  498. // Identify "current" sequence containing block:
  499. // [prev seq] [current seq] [next seq]
  500. //
  501. // Based on block position, resulting list of sequences can be any of three forms:
  502. //
  503. // block position Resulting list of sequences
  504. // A) block is first in current: [prev seq] [new] [modified current seq] [next seq]
  505. // B) block is last in current: [prev seq] [modified current seq] [new] [next seq]
  506. // C) block is in the middle of current: [prev seq] [curr pre] [new] [curr post] [next seq]
  507. func pushReservation(bytePos, bitPos uint64, head *sequence, release bool) *sequence {
  508. // Store list's head
  509. newHead := head
  510. // Find the sequence containing this byte
  511. current, previous, precBlocks, inBlockBytePos := findSequence(head, bytePos)
  512. if current == nil {
  513. return newHead
  514. }
  515. // Construct updated block
  516. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  517. newBlock := current.block
  518. if release {
  519. newBlock &^= bitSel
  520. } else {
  521. newBlock |= bitSel
  522. }
  523. // Quit if it was a redundant request
  524. if current.block == newBlock {
  525. return newHead
  526. }
  527. // Current sequence inevitably looses one block, upadate count
  528. current.count--
  529. // Create new sequence
  530. newSequence := &sequence{block: newBlock, count: 1}
  531. // Insert the new sequence in the list based on block position
  532. if precBlocks == 0 { // First in sequence (A)
  533. newSequence.next = current
  534. if current == head {
  535. newHead = newSequence
  536. previous = newHead
  537. } else {
  538. previous.next = newSequence
  539. }
  540. removeCurrentIfEmpty(&newHead, newSequence, current)
  541. mergeSequences(previous)
  542. } else if precBlocks == current.count { // Last in sequence (B)
  543. newSequence.next = current.next
  544. current.next = newSequence
  545. mergeSequences(current)
  546. } else { // In between the sequence (C)
  547. currPre := &sequence{block: current.block, count: precBlocks, next: newSequence}
  548. currPost := current
  549. currPost.count -= precBlocks
  550. newSequence.next = currPost
  551. if currPost == head {
  552. newHead = currPre
  553. } else {
  554. previous.next = currPre
  555. }
  556. // No merging or empty current possible here
  557. }
  558. return newHead
  559. }
  560. // Removes the current sequence from the list if empty, adjusting the head pointer if needed
  561. func removeCurrentIfEmpty(head **sequence, previous, current *sequence) {
  562. if current.count == 0 {
  563. if current == *head {
  564. *head = current.next
  565. } else {
  566. previous.next = current.next
  567. current = current.next
  568. }
  569. }
  570. }
  571. // Given a pointer to a sequence, it checks if it can be merged with any following sequences
  572. // It stops when no more merging is possible.
  573. // TODO: Optimization: only attempt merge from start to end sequence, no need to scan till the end of the list
  574. func mergeSequences(seq *sequence) {
  575. if seq != nil {
  576. // Merge all what possible from seq
  577. for seq.next != nil && seq.block == seq.next.block {
  578. seq.count += seq.next.count
  579. seq.next = seq.next.next
  580. }
  581. // Move to next
  582. mergeSequences(seq.next)
  583. }
  584. }
  585. func getNumBlocks(numBits uint64) uint64 {
  586. numBlocks := numBits / uint64(blockLen)
  587. if numBits%uint64(blockLen) != 0 {
  588. numBlocks++
  589. }
  590. return numBlocks
  591. }
  592. func ordinalToPos(ordinal uint64) (uint64, uint64) {
  593. return ordinal / 8, ordinal % 8
  594. }
  595. func posToOrdinal(bytePos, bitPos uint64) uint64 {
  596. return bytePos*8 + bitPos
  597. }