Proposal : ObjectIdTime(t time.Time)

33 views
Skip to first unread message

Ahmed Waheed

unread,
Apr 19, 2014, 4:02:27 AM4/19/14
to mgo-...@googlegroups.com
While I was testing, I wanted to set a specific time on the ObjectId, and, ended up using :

func makeTimedObjectId(t time.Time) bson.ObjectId {
    oid := bson.NewObjectId().Hex()
    nid := fmt.Sprintf("%x%s", t.Unix(), oid[8:])
    return bson.ObjectIdHex(nid)
}

However It would be much easier to add a new function to the library, for example :


func ObjectIdTime(t time.Time) ObjectId {
var b [12]byte
// Timestamp, 4 bytes, big endian
binary.BigEndian.PutUint32(b[:], uint32(t.Unix()))
// Machine, first 3 bytes of md5(hostname)
b[4] = machineId[0]
b[5] = machineId[1]
b[6] = machineId[2]
// Pid, 2 bytes, specs don't specify endianness, but we use big endian.
pid := os.Getpid()
b[7] = byte(pid >> 8)
b[8] = byte(pid)
// Increment, 3 bytes, big endian
i := atomic.AddUint32(&objectIdCounter, 1)
b[9] = byte(i >> 16)
b[10] = byte(i >> 8)
b[11] = byte(i)
return ObjectId(b[:])
}
//change NewObjectid
func NewObjectId() ObjectId {
return ObjectIdTime(time.Now())
}

It's a very simple change, it won't break any current projects either.

The reasoning for this is I'm using the objectid to query the collection for time, and for mocking I need to set specific times on the objectid.

Using NewObjectIdWIthTime is fine for querying, but not for insertion.

Regards,
Ahmed W.

Gustavo Niemeyer

unread,
May 12, 2014, 5:40:58 PM5/12/14
to mgo-...@googlegroups.com, Ahmed Waheed
Hi Ahmed,

On Sat, Apr 19, 2014 at 5:02 AM, Ahmed Waheed <oneo...@gmail.com> wrote:
> However It would be much easier to add a new function to the library, for
> example :
>
>
>> func ObjectIdTime(t time.Time) ObjectId {
(...)
> It's a very simple change, it won't break any current projects either.
>
> The reasoning for this is I'm using the objectid to query the collection for
> time, and for mocking I need to set specific times on the objectid.

Isn't that the same as:

b := bson.NewObjectId()
binary.BigEndian.PutUint32([]byte(b), uint32(t.Unix()))

?

Also, I don't fully understand why you'd want something like that.
When is a random id with a cooked timestamp useful? For querying
purposes, it might be zeroed out, except for the time, right?


gustavo @ http://niemeyer.net

Ahmed Waheed

unread,
May 12, 2014, 6:03:55 PM5/12/14
to mgo-...@googlegroups.com, Ahmed Waheed
For a project I was working on I was using the IDs as timestamps, and since I was moving from MySQL I wanted to use specific times for it.

While it's easy to workaround it with your code or mine, I think it belongs in mgo.

Gustavo Niemeyer

unread,
May 12, 2014, 6:08:02 PM5/12/14
to mgo-...@googlegroups.com, Ahmed Waheed
On Mon, May 12, 2014 at 7:03 PM, Ahmed Waheed <oneo...@gmail.com> wrote:
> For a project I was working on I was using the IDs as timestamps, and since
> I was moving from MySQL I wanted to use specific times for it.
>
> While it's easy to workaround it with your code or mine, I think it belongs
> in mgo.

Implementing the feature requires a single line of code, it was only
ever brought up once, and for a project that is temporary. Doesn't
feel worth of inclusion.


gustavo @ http://niemeyer.net
Reply all
Reply to author
Forward
0 new messages