sequence.go 16 KB

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