Received: from out4-smtp.messagingengine.com (out4-smtp.messagingengine.com [66.111.4.28]) by mail.sr.ht (Postfix) with ESMTPS id C6F81400B6 for <~sircmpwn/aerc@lists.sr.ht>; Thu, 11 Jul 2019 13:49:39 +0000 (UTC) Authentication-Results: mail.sr.ht; dkim=pass (2048-bit key) header.d=benburwell.com header.i=@benburwell.com header.b=ryiAMwsM; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=Ejzpq1Fi Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 7C80E21F2E; Thu, 11 Jul 2019 09:49:39 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Thu, 11 Jul 2019 09:49:39 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=benburwell.com; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm3; bh=7Cky1CaHh/7no 83XiDUnp+0gXCR4OX8xOOt8pmhPnc0=; b=ryiAMwsM8kimT6K5rsxOXnpPVNZZc m0CN930PVbyt1CA+DhWyAVTpVxqLXxvl6HKcwOSc4zDGqSxW0C6Xjy9nliGLbaa8 BzfnrRWuIchaPBxPaEuGBafoqblM8E6slulRw798QWzmhuLExn+6G1Ba5Oyh3We8 lypqyJKY1NmEq57PibYFKbHvO7gWB1yAUQ6cxgPIcQdBPAsTd3xDPvWOk2iGt0Ul kY3OPJ+ylzFRJ9ZgkfVXW5eGsmtSntBrIzAXKuLqnnenCbdjgz6yEDg8IQH+6hZC HUThtsa2Ws9uwyFlyxRx+Nw3qo01ujjGkLMgoObzG4U8sLU6rsBnyOLqA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=7Cky1CaHh/7no83XiDUnp+0gXCR4OX8xOOt8pmhPnc0=; b=Ejzpq1Fi AoX5Ms0C0qijiAN6128U8ZMrrx5qtu5hrjpWImSkM/kBcPBdePaeD5KjwgGGFsKL QSgDyBL1u0oWmQFh0/pT+9rMbdvSCiRSMeRxAydfKME0yFxpFb/05Wspndui5WI1 TNY3xopBKsFMN4B/ms54xEHm9jQgit7Abi3JOAPwTLj9xQpLhecSYJKwrfSNd4Rg 0EMILfIUZGlKAlzZlR8xO/dGfcEDD5afrPeB6wupR7fq+/pVldlFK1/kXxbSlpvS TOkdXEUqm5QECVrpeIrmU/oTzlniOaEJfHm2+2MCz0FLR0I8lf2TkEc/mIJF+raR OLXoaixnIJb+Cg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduvddrgeekgdejtdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpeeuvghnuceuuhhrfigvlhhluceosggvnhessggvnhgsuhhrfigv lhhlrdgtohhmqeenucfkphepudegiedrudduhedrgedvrddutdenucfrrghrrghmpehmrg hilhhfrhhomhepsggvnhessggvnhgsuhhrfigvlhhlrdgtohhmnecuvehluhhsthgvrhfu ihiivgeptd X-ME-Proxy: Received: from localhost (146-115-42-10.s4872.c3-0.abr-cbr1.sbo-abr.ma.cable.rcncustomer.com [146.115.42.10]) by mail.messagingengine.com (Postfix) with ESMTPA id 23FD88005A; Thu, 11 Jul 2019 09:49:39 -0400 (EDT) From: Ben Burwell To: ~sircmpwn/aerc@lists.sr.ht Cc: Ben Burwell Subject: [PATCH v2 1/5] Create UIDStore package Date: Thu, 11 Jul 2019 09:44:50 -0400 Message-Id: <20190711134454.80318-2-ben@benburwell.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190711134454.80318-1-ben@benburwell.com> References: <20190711134454.80318-1-ben@benburwell.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable This package can be used to provide a source for mapping mock UIDs back to relevant keys for alternate backends. For example, for the Maildir backend, we need to map between UID and message file names. --- lib/uidstore/uidstore.go | 62 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 lib/uidstore/uidstore.go diff --git a/lib/uidstore/uidstore.go b/lib/uidstore/uidstore.go new file mode 100644 index 0000000..11c5e47 --- /dev/null +++ b/lib/uidstore/uidstore.go @@ -0,0 +1,62 @@ +// Package uidstore provides a concurrency-safe two-way mapping between = UIDs +// used by the UI and arbitrary string keys as used by different mail ba= ckends. +// +// Multiple Store instances can safely be created and the UIDs that they +// generate will be globally unique. +package uidstore + +import ( + "sync" + "sync/atomic" +) + +var nextUID uint32 =3D 1 + +// Store holds a mapping between application keys and globally-unique UI= Ds. +type Store struct { + keyByUID map[uint32]string + uidByKey map[string]uint32 + m sync.Mutex +} + +// NewStore creates a new, empty Store. +func NewStore() *Store { + return &Store{ + keyByUID: make(map[uint32]string), + uidByKey: make(map[string]uint32), + } +} + +// GetOrInsert returns the UID for the provided key. If the key was alre= ady +// present in the store, the same UID value is returned. Otherwise, the = key is +// inserted and the newly generated UID is returned. +func (s *Store) GetOrInsert(key string) uint32 { + s.m.Lock() + defer s.m.Unlock() + if uid, ok :=3D s.uidByKey[key]; ok { + return uid + } + uid :=3D atomic.AddUint32(&nextUID, 1) + s.keyByUID[uid] =3D key + s.uidByKey[key] =3D uid + return uid +} + +// GetKey returns the key for the provided UID, if available. +func (s *Store) GetKey(uid uint32) (string, bool) { + s.m.Lock() + defer s.m.Unlock() + key, ok :=3D s.keyByUID[uid] + return key, ok +} + +// RemoveUID removes the specified UID from the store. +func (s *Store) RemoveUID(uid uint32) { + s.m.Lock() + defer s.m.Unlock() + key, ok :=3D s.keyByUID[uid] + if ok { + delete(s.uidByKey, key) + } + delete(s.keyByUID, uid) +} --=20 2.22.0