initial implementation of IP allocator, only using memory storage
diff --git a/ip-allocator/storage.go b/ip-allocator/storage.go
new file mode 100644
index 0000000..26be353
--- /dev/null
+++ b/ip-allocator/storage.go
@@ -0,0 +1,87 @@
+package main
+
+type Storage interface {
+ Init(start string, count uint) error
+ Get(mac string) (string, error)
+ GetAll() map[string]string
+ Put(mac, ip string) error
+ Remove(mac string) (string, error)
+ Dequeue() (string, error)
+ Enqueue(ip string) error
+}
+
+type MemoryStorage struct {
+ allocated map[string]IPv4
+ available []IPv4
+ readIdx, writeIdx, size uint
+}
+
+func (s *MemoryStorage) Init(start string, count uint) error {
+ ip, err := ParseIP(start)
+ if err != nil {
+ return err
+ }
+ s.readIdx = 0
+ s.writeIdx = 0
+ s.size = count
+ s.allocated = make(map[string]IPv4)
+ s.available = make([]IPv4, count)
+ for i := uint(0); i < count; i += 1 {
+ s.available[i] = ip
+ ip, err = ip.Next()
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (s *MemoryStorage) Get(mac string) (string, error) {
+ ip, ok := s.allocated[mac]
+ if !ok {
+ return "", nil
+ }
+ return ip.String(), nil
+}
+
+func (s *MemoryStorage) GetAll() map[string]string {
+ all := make(map[string]string)
+ for k, v := range s.allocated {
+ all[k] = v.String()
+ }
+ return all
+}
+
+func (s *MemoryStorage) Put(mac, ip string) error {
+ data, err := ParseIP(ip)
+ if err != nil {
+ return err
+ }
+ s.allocated[mac] = data
+ return nil
+}
+
+func (s *MemoryStorage) Remove(mac string) (string, error) {
+ ip, ok := s.allocated[mac]
+ if !ok {
+ return "", nil
+ }
+ delete(s.allocated, mac)
+ return ip.String(), nil
+}
+
+func (s *MemoryStorage) Dequeue() (string, error) {
+ ip := s.available[s.readIdx]
+ s.readIdx = (s.readIdx + 1) % s.size
+ return ip.String(), nil
+}
+
+func (s *MemoryStorage) Enqueue(ip string) error {
+ data, err := ParseIP(ip)
+ if err != nil {
+ return err
+ }
+ s.available[s.writeIdx] = data
+ s.writeIdx = (s.writeIdx + 1) % s.size
+ return nil
+}