sequence.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  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. App string
  22. ID string
  23. Head *Sequence
  24. store datastore.DataStore
  25. dbIndex uint64
  26. sync.Mutex
  27. }
  28. // NewHandle returns a thread-safe instance of the bitmask handler
  29. func NewHandle(app string, ds datastore.DataStore, id string, numElements uint32) *Handle {
  30. h := &Handle{
  31. App: app,
  32. ID: id,
  33. store: ds,
  34. Head: &Sequence{
  35. Block: 0x0,
  36. Count: getNumBlocks(numElements),
  37. Next: nil,
  38. },
  39. }
  40. h.watchForChanges()
  41. return h
  42. }
  43. // Sequence reresents a recurring sequence of 32 bits long bitmasks
  44. type Sequence struct {
  45. Block uint32 // block representing 4 byte long allocation bitmask
  46. Count uint32 // number of consecutive blocks
  47. Next *Sequence // next sequence
  48. }
  49. // NewSequence returns a sequence initialized to represent a bitmaks of numElements bits
  50. func NewSequence(numElements uint32) *Sequence {
  51. return &Sequence{Block: 0x0, Count: getNumBlocks(numElements), Next: nil}
  52. }
  53. // String returns a string representation of the block sequence starting from this block
  54. func (s *Sequence) String() string {
  55. var nextBlock string
  56. if s.Next == nil {
  57. nextBlock = "end"
  58. } else {
  59. nextBlock = s.Next.String()
  60. }
  61. return fmt.Sprintf("(0x%x, %d)->%s", s.Block, s.Count, nextBlock)
  62. }
  63. // GetAvailableBit returns the position of the first unset bit in the bitmask represented by this sequence
  64. func (s *Sequence) GetAvailableBit() (bytePos, bitPos int) {
  65. if s.Block == blockMAX || s.Count == 0 {
  66. return -1, -1
  67. }
  68. bits := 0
  69. bitSel := uint32(blockFirstBit)
  70. for bitSel > 0 && s.Block&bitSel != 0 {
  71. bitSel >>= 1
  72. bits++
  73. }
  74. return bits / 8, bits % 8
  75. }
  76. // Equal checks if this sequence is equal to the passed one
  77. func (s *Sequence) Equal(o *Sequence) bool {
  78. this := s
  79. other := o
  80. for this != nil {
  81. if other == nil {
  82. return false
  83. }
  84. if this.Block != other.Block || this.Count != other.Count {
  85. return false
  86. }
  87. this = this.Next
  88. other = other.Next
  89. }
  90. // Check if other is longer than this
  91. if other != nil {
  92. return false
  93. }
  94. return true
  95. }
  96. // ToByteArray converts the sequence into a byte array
  97. // TODO (aboch): manage network/host order stuff
  98. func (s *Sequence) ToByteArray() ([]byte, error) {
  99. var bb []byte
  100. p := s
  101. for p != nil {
  102. bb = append(bb, netutils.U32ToA(p.Block)...)
  103. bb = append(bb, netutils.U32ToA(p.Count)...)
  104. p = p.Next
  105. }
  106. return bb, nil
  107. }
  108. // FromByteArray construct the sequence from the byte array
  109. // TODO (aboch): manage network/host order stuff
  110. func (s *Sequence) FromByteArray(data []byte) error {
  111. l := len(data)
  112. if l%8 != 0 {
  113. return fmt.Errorf("cannot deserialize byte sequence of lenght %d", l)
  114. }
  115. p := s
  116. i := 0
  117. for {
  118. p.Block = netutils.ATo32(data[i : i+4])
  119. p.Count = netutils.ATo32(data[i+4 : i+8])
  120. i += 8
  121. if i == l {
  122. break
  123. }
  124. p.Next = &Sequence{}
  125. p = p.Next
  126. }
  127. return nil
  128. }
  129. // GetFirstAvailable returns the byte and bit position of the first unset bit
  130. func (h *Handle) GetFirstAvailable() (int, int, error) {
  131. h.Lock()
  132. defer h.Unlock()
  133. return GetFirstAvailable(h.Head)
  134. }
  135. // CheckIfAvailable checks if the bit correspondent to the specified ordinal is unset
  136. // If the ordinal is beyond the Sequence limits, a negative response is returned
  137. func (h *Handle) CheckIfAvailable(ordinal int) (int, int, error) {
  138. h.Lock()
  139. defer h.Unlock()
  140. return CheckIfAvailable(h.Head, ordinal)
  141. }
  142. // PushReservation pushes the bit reservation inside the bitmask.
  143. func (h *Handle) PushReservation(bytePos, bitPos int, release bool) error {
  144. h.Lock()
  145. h.Head = PushReservation(bytePos, bitPos, h.Head, release)
  146. h.Unlock()
  147. return h.writeToStore()
  148. }
  149. // GetFirstAvailable looks for the first unset bit in passed mask
  150. func GetFirstAvailable(head *Sequence) (int, int, error) {
  151. byteIndex := 0
  152. current := head
  153. for current != nil {
  154. if current.Block != blockMAX {
  155. bytePos, bitPos := current.GetAvailableBit()
  156. return byteIndex + bytePos, bitPos, nil
  157. }
  158. byteIndex += int(current.Count * blockBytes)
  159. current = current.Next
  160. }
  161. return -1, -1, fmt.Errorf("no bit available")
  162. }
  163. // CheckIfAvailable checks if the bit correspondent to the specified ordinal is unset
  164. // If the ordinal is beyond the Sequence limits, a negative response is returned
  165. func CheckIfAvailable(head *Sequence, ordinal int) (int, int, error) {
  166. bytePos := ordinal / 8
  167. bitPos := ordinal % 8
  168. // Find the Sequence containing this byte
  169. current, _, _, inBlockBytePos := findSequence(head, bytePos)
  170. if current != nil {
  171. // Check whether the bit corresponding to the ordinal address is unset
  172. bitSel := uint32(blockFirstBit >> uint(inBlockBytePos*8+bitPos))
  173. if current.Block&bitSel == 0 {
  174. return bytePos, bitPos, nil
  175. }
  176. }
  177. return -1, -1, fmt.Errorf("requested bit is not available")
  178. }
  179. // Given the byte position and the sequences list head, return the pointer to the
  180. // sequence containing the byte (current), the pointer to the previous sequence,
  181. // the number of blocks preceding the block containing the byte inside the current sequence.
  182. // If bytePos is outside of the list, function will return (nil, nil, 0, -1)
  183. func findSequence(head *Sequence, bytePos int) (*Sequence, *Sequence, uint32, int) {
  184. // Find the Sequence containing this byte
  185. previous := head
  186. current := head
  187. n := bytePos
  188. for current.Next != nil && n >= int(current.Count*blockBytes) { // Nil check for less than 32 addresses masks
  189. n -= int(current.Count * blockBytes)
  190. previous = current
  191. current = current.Next
  192. }
  193. // If byte is outside of the list, let caller know
  194. if n >= int(current.Count*blockBytes) {
  195. return nil, nil, 0, -1
  196. }
  197. // Find the byte position inside the block and the number of blocks
  198. // preceding the block containing the byte inside this sequence
  199. precBlocks := uint32(n / blockBytes)
  200. inBlockBytePos := bytePos % blockBytes
  201. return current, previous, precBlocks, inBlockBytePos
  202. }
  203. // PushReservation pushes the bit reservation inside the bitmask.
  204. // Given byte and bit positions, identify the sequence (current) which holds the block containing the affected bit.
  205. // Create a new block with the modified bit according to the operation (allocate/release).
  206. // Create a new Sequence containing the new Block and insert it in the proper position.
  207. // Remove current sequence if empty.
  208. // Check if new Sequence can be merged with neighbour (previous/Next) sequences.
  209. //
  210. //
  211. // Identify "current" Sequence containing block:
  212. // [prev seq] [current seq] [Next seq]
  213. //
  214. // Based on block position, resulting list of sequences can be any of three forms:
  215. //
  216. // Block position Resulting list of sequences
  217. // A) Block is first in current: [prev seq] [new] [modified current seq] [Next seq]
  218. // B) Block is last in current: [prev seq] [modified current seq] [new] [Next seq]
  219. // C) Block is in the middle of current: [prev seq] [curr pre] [new] [curr post] [Next seq]
  220. func PushReservation(bytePos, bitPos int, head *Sequence, release bool) *Sequence {
  221. // Store list's head
  222. newHead := head
  223. // Find the Sequence containing this byte
  224. current, previous, precBlocks, inBlockBytePos := findSequence(head, bytePos)
  225. if current == nil {
  226. return newHead
  227. }
  228. // Construct updated block
  229. bitSel := uint32(blockFirstBit >> uint(inBlockBytePos*8+bitPos))
  230. newBlock := current.Block
  231. if release {
  232. newBlock &^= bitSel
  233. } else {
  234. newBlock |= bitSel
  235. }
  236. // Quit if it was a redundant request
  237. if current.Block == newBlock {
  238. return newHead
  239. }
  240. // Current Sequence inevitably looses one block, upadate Count
  241. current.Count--
  242. // Create new sequence
  243. newSequence := &Sequence{Block: newBlock, Count: 1}
  244. // Insert the new sequence in the list based on block position
  245. if precBlocks == 0 { // First in sequence (A)
  246. newSequence.Next = current
  247. if current == head {
  248. newHead = newSequence
  249. previous = newHead
  250. } else {
  251. previous.Next = newSequence
  252. }
  253. removeCurrentIfEmpty(&newHead, newSequence, current)
  254. mergeSequences(previous)
  255. } else if precBlocks == current.Count-2 { // Last in sequence (B)
  256. newSequence.Next = current.Next
  257. current.Next = newSequence
  258. mergeSequences(current)
  259. } else { // In between the sequence (C)
  260. currPre := &Sequence{Block: current.Block, Count: precBlocks, Next: newSequence}
  261. currPost := current
  262. currPost.Count -= precBlocks
  263. newSequence.Next = currPost
  264. if currPost == head {
  265. newHead = currPre
  266. } else {
  267. previous.Next = currPre
  268. }
  269. // No merging or empty current possible here
  270. }
  271. return newHead
  272. }
  273. // Removes the current sequence from the list if empty, adjusting the head pointer if needed
  274. func removeCurrentIfEmpty(head **Sequence, previous, current *Sequence) {
  275. if current.Count == 0 {
  276. if current == *head {
  277. *head = current.Next
  278. } else {
  279. previous.Next = current.Next
  280. current = current.Next
  281. }
  282. }
  283. }
  284. // Given a pointer to a Sequence, it checks if it can be merged with any following sequences
  285. // It stops when no more merging is possible.
  286. // TODO: Optimization: only attempt merge from start to end sequence, no need to scan till the end of the list
  287. func mergeSequences(seq *Sequence) {
  288. if seq != nil {
  289. // Merge all what possible from seq
  290. for seq.Next != nil && seq.Block == seq.Next.Block {
  291. seq.Count += seq.Next.Count
  292. seq.Next = seq.Next.Next
  293. }
  294. // Move to Next
  295. mergeSequences(seq.Next)
  296. }
  297. }
  298. // Serialize converts the sequence into a byte array
  299. func Serialize(head *Sequence) ([]byte, error) {
  300. return nil, nil
  301. }
  302. // Deserialize decodes the byte array into a sequence
  303. func Deserialize(data []byte) (*Sequence, error) {
  304. return nil, nil
  305. }
  306. func getNumBlocks(numBits uint32) uint32 {
  307. numBlocks := numBits / blockLen
  308. if numBits%blockLen != 0 {
  309. numBlocks++
  310. }
  311. return numBlocks
  312. }