sequence.go 17 KB

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