Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / docker / libnetwork / idm / idm.go
1 // Package idm manages reservation/release of numerical ids from a configured set of contiguous ids
2 package idm
3
4 import (
5         "errors"
6         "fmt"
7
8         "github.com/docker/libnetwork/bitseq"
9         "github.com/docker/libnetwork/datastore"
10 )
11
12 // Idm manages the reservation/release of numerical ids from a contiguous set
13 type Idm struct {
14         start  uint64
15         end    uint64
16         handle *bitseq.Handle
17 }
18
19 // New returns an instance of id manager for a [start,end] set of numerical ids
20 func New(ds datastore.DataStore, id string, start, end uint64) (*Idm, error) {
21         if id == "" {
22                 return nil, errors.New("Invalid id")
23         }
24         if end <= start {
25                 return nil, fmt.Errorf("Invalid set range: [%d, %d]", start, end)
26         }
27
28         h, err := bitseq.NewHandle("idm", ds, id, 1+end-start)
29         if err != nil {
30                 return nil, fmt.Errorf("failed to initialize bit sequence handler: %s", err.Error())
31         }
32
33         return &Idm{start: start, end: end, handle: h}, nil
34 }
35
36 // GetID returns the first available id in the set
37 func (i *Idm) GetID() (uint64, error) {
38         if i.handle == nil {
39                 return 0, errors.New("ID set is not initialized")
40         }
41         ordinal, err := i.handle.SetAny()
42         return i.start + ordinal, err
43 }
44
45 // GetSpecificID tries to reserve the specified id
46 func (i *Idm) GetSpecificID(id uint64) error {
47         if i.handle == nil {
48                 return errors.New("ID set is not initialized")
49         }
50
51         if id < i.start || id > i.end {
52                 return errors.New("Requested id does not belong to the set")
53         }
54
55         return i.handle.Set(id - i.start)
56 }
57
58 // GetIDInRange returns the first available id in the set within a [start,end] range
59 func (i *Idm) GetIDInRange(start, end uint64) (uint64, error) {
60         if i.handle == nil {
61                 return 0, errors.New("ID set is not initialized")
62         }
63
64         if start < i.start || end > i.end {
65                 return 0, errors.New("Requested range does not belong to the set")
66         }
67
68         ordinal, err := i.handle.SetAnyInRange(start-i.start, end-i.start)
69
70         return i.start + ordinal, err
71 }
72
73 // Release releases the specified id
74 func (i *Idm) Release(id uint64) {
75         i.handle.Unset(id - i.start)
76 }