sequence.go 12 KB

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